test_arrayprint.py 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967
  1. import sys
  2. import gc
  3. from hypothesis import given
  4. from hypothesis.extra import numpy as hynp
  5. import pytest
  6. import numpy as np
  7. from numpy.testing import (
  8. assert_, assert_equal, assert_raises, assert_warns, HAS_REFCOUNT,
  9. assert_raises_regex,
  10. )
  11. import textwrap
  12. class TestArrayRepr:
  13. def test_nan_inf(self):
  14. x = np.array([np.nan, np.inf])
  15. assert_equal(repr(x), 'array([nan, inf])')
  16. def test_subclass(self):
  17. class sub(np.ndarray): pass
  18. # one dimensional
  19. x1d = np.array([1, 2]).view(sub)
  20. assert_equal(repr(x1d), 'sub([1, 2])')
  21. # two dimensional
  22. x2d = np.array([[1, 2], [3, 4]]).view(sub)
  23. assert_equal(repr(x2d),
  24. 'sub([[1, 2],\n'
  25. ' [3, 4]])')
  26. # two dimensional with flexible dtype
  27. xstruct = np.ones((2,2), dtype=[('a', '<i4')]).view(sub)
  28. assert_equal(repr(xstruct),
  29. "sub([[(1,), (1,)],\n"
  30. " [(1,), (1,)]], dtype=[('a', '<i4')])"
  31. )
  32. @pytest.mark.xfail(reason="See gh-10544")
  33. def test_object_subclass(self):
  34. class sub(np.ndarray):
  35. def __new__(cls, inp):
  36. obj = np.asarray(inp).view(cls)
  37. return obj
  38. def __getitem__(self, ind):
  39. ret = super().__getitem__(ind)
  40. return sub(ret)
  41. # test that object + subclass is OK:
  42. x = sub([None, None])
  43. assert_equal(repr(x), 'sub([None, None], dtype=object)')
  44. assert_equal(str(x), '[None None]')
  45. x = sub([None, sub([None, None])])
  46. assert_equal(repr(x),
  47. 'sub([None, sub([None, None], dtype=object)], dtype=object)')
  48. assert_equal(str(x), '[None sub([None, None], dtype=object)]')
  49. def test_0d_object_subclass(self):
  50. # make sure that subclasses which return 0ds instead
  51. # of scalars don't cause infinite recursion in str
  52. class sub(np.ndarray):
  53. def __new__(cls, inp):
  54. obj = np.asarray(inp).view(cls)
  55. return obj
  56. def __getitem__(self, ind):
  57. ret = super().__getitem__(ind)
  58. return sub(ret)
  59. x = sub(1)
  60. assert_equal(repr(x), 'sub(1)')
  61. assert_equal(str(x), '1')
  62. x = sub([1, 1])
  63. assert_equal(repr(x), 'sub([1, 1])')
  64. assert_equal(str(x), '[1 1]')
  65. # check it works properly with object arrays too
  66. x = sub(None)
  67. assert_equal(repr(x), 'sub(None, dtype=object)')
  68. assert_equal(str(x), 'None')
  69. # plus recursive object arrays (even depth > 1)
  70. y = sub(None)
  71. x[()] = y
  72. y[()] = x
  73. assert_equal(repr(x),
  74. 'sub(sub(sub(..., dtype=object), dtype=object), dtype=object)')
  75. assert_equal(str(x), '...')
  76. x[()] = 0 # resolve circular references for garbage collector
  77. # nested 0d-subclass-object
  78. x = sub(None)
  79. x[()] = sub(None)
  80. assert_equal(repr(x), 'sub(sub(None, dtype=object), dtype=object)')
  81. assert_equal(str(x), 'None')
  82. # gh-10663
  83. class DuckCounter(np.ndarray):
  84. def __getitem__(self, item):
  85. result = super().__getitem__(item)
  86. if not isinstance(result, DuckCounter):
  87. result = result[...].view(DuckCounter)
  88. return result
  89. def to_string(self):
  90. return {0: 'zero', 1: 'one', 2: 'two'}.get(self.item(), 'many')
  91. def __str__(self):
  92. if self.shape == ():
  93. return self.to_string()
  94. else:
  95. fmt = {'all': lambda x: x.to_string()}
  96. return np.array2string(self, formatter=fmt)
  97. dc = np.arange(5).view(DuckCounter)
  98. assert_equal(str(dc), "[zero one two many many]")
  99. assert_equal(str(dc[0]), "zero")
  100. def test_self_containing(self):
  101. arr0d = np.array(None)
  102. arr0d[()] = arr0d
  103. assert_equal(repr(arr0d),
  104. 'array(array(..., dtype=object), dtype=object)')
  105. arr0d[()] = 0 # resolve recursion for garbage collector
  106. arr1d = np.array([None, None])
  107. arr1d[1] = arr1d
  108. assert_equal(repr(arr1d),
  109. 'array([None, array(..., dtype=object)], dtype=object)')
  110. arr1d[1] = 0 # resolve recursion for garbage collector
  111. first = np.array(None)
  112. second = np.array(None)
  113. first[()] = second
  114. second[()] = first
  115. assert_equal(repr(first),
  116. 'array(array(array(..., dtype=object), dtype=object), dtype=object)')
  117. first[()] = 0 # resolve circular references for garbage collector
  118. def test_containing_list(self):
  119. # printing square brackets directly would be ambiguuous
  120. arr1d = np.array([None, None])
  121. arr1d[0] = [1, 2]
  122. arr1d[1] = [3]
  123. assert_equal(repr(arr1d),
  124. 'array([list([1, 2]), list([3])], dtype=object)')
  125. def test_void_scalar_recursion(self):
  126. # gh-9345
  127. repr(np.void(b'test')) # RecursionError ?
  128. def test_fieldless_structured(self):
  129. # gh-10366
  130. no_fields = np.dtype([])
  131. arr_no_fields = np.empty(4, dtype=no_fields)
  132. assert_equal(repr(arr_no_fields), 'array([(), (), (), ()], dtype=[])')
  133. class TestComplexArray:
  134. def test_str(self):
  135. rvals = [0, 1, -1, np.inf, -np.inf, np.nan]
  136. cvals = [complex(rp, ip) for rp in rvals for ip in rvals]
  137. dtypes = [np.complex64, np.cdouble, np.clongdouble]
  138. actual = [str(np.array([c], dt)) for c in cvals for dt in dtypes]
  139. wanted = [
  140. '[0.+0.j]', '[0.+0.j]', '[0.+0.j]',
  141. '[0.+1.j]', '[0.+1.j]', '[0.+1.j]',
  142. '[0.-1.j]', '[0.-1.j]', '[0.-1.j]',
  143. '[0.+infj]', '[0.+infj]', '[0.+infj]',
  144. '[0.-infj]', '[0.-infj]', '[0.-infj]',
  145. '[0.+nanj]', '[0.+nanj]', '[0.+nanj]',
  146. '[1.+0.j]', '[1.+0.j]', '[1.+0.j]',
  147. '[1.+1.j]', '[1.+1.j]', '[1.+1.j]',
  148. '[1.-1.j]', '[1.-1.j]', '[1.-1.j]',
  149. '[1.+infj]', '[1.+infj]', '[1.+infj]',
  150. '[1.-infj]', '[1.-infj]', '[1.-infj]',
  151. '[1.+nanj]', '[1.+nanj]', '[1.+nanj]',
  152. '[-1.+0.j]', '[-1.+0.j]', '[-1.+0.j]',
  153. '[-1.+1.j]', '[-1.+1.j]', '[-1.+1.j]',
  154. '[-1.-1.j]', '[-1.-1.j]', '[-1.-1.j]',
  155. '[-1.+infj]', '[-1.+infj]', '[-1.+infj]',
  156. '[-1.-infj]', '[-1.-infj]', '[-1.-infj]',
  157. '[-1.+nanj]', '[-1.+nanj]', '[-1.+nanj]',
  158. '[inf+0.j]', '[inf+0.j]', '[inf+0.j]',
  159. '[inf+1.j]', '[inf+1.j]', '[inf+1.j]',
  160. '[inf-1.j]', '[inf-1.j]', '[inf-1.j]',
  161. '[inf+infj]', '[inf+infj]', '[inf+infj]',
  162. '[inf-infj]', '[inf-infj]', '[inf-infj]',
  163. '[inf+nanj]', '[inf+nanj]', '[inf+nanj]',
  164. '[-inf+0.j]', '[-inf+0.j]', '[-inf+0.j]',
  165. '[-inf+1.j]', '[-inf+1.j]', '[-inf+1.j]',
  166. '[-inf-1.j]', '[-inf-1.j]', '[-inf-1.j]',
  167. '[-inf+infj]', '[-inf+infj]', '[-inf+infj]',
  168. '[-inf-infj]', '[-inf-infj]', '[-inf-infj]',
  169. '[-inf+nanj]', '[-inf+nanj]', '[-inf+nanj]',
  170. '[nan+0.j]', '[nan+0.j]', '[nan+0.j]',
  171. '[nan+1.j]', '[nan+1.j]', '[nan+1.j]',
  172. '[nan-1.j]', '[nan-1.j]', '[nan-1.j]',
  173. '[nan+infj]', '[nan+infj]', '[nan+infj]',
  174. '[nan-infj]', '[nan-infj]', '[nan-infj]',
  175. '[nan+nanj]', '[nan+nanj]', '[nan+nanj]']
  176. for res, val in zip(actual, wanted):
  177. assert_equal(res, val)
  178. class TestArray2String:
  179. def test_basic(self):
  180. """Basic test of array2string."""
  181. a = np.arange(3)
  182. assert_(np.array2string(a) == '[0 1 2]')
  183. assert_(np.array2string(a, max_line_width=4, legacy='1.13') == '[0 1\n 2]')
  184. assert_(np.array2string(a, max_line_width=4) == '[0\n 1\n 2]')
  185. def test_unexpected_kwarg(self):
  186. # ensure than an appropriate TypeError
  187. # is raised when array2string receives
  188. # an unexpected kwarg
  189. with assert_raises_regex(TypeError, 'nonsense'):
  190. np.array2string(np.array([1, 2, 3]),
  191. nonsense=None)
  192. def test_format_function(self):
  193. """Test custom format function for each element in array."""
  194. def _format_function(x):
  195. if np.abs(x) < 1:
  196. return '.'
  197. elif np.abs(x) < 2:
  198. return 'o'
  199. else:
  200. return 'O'
  201. x = np.arange(3)
  202. x_hex = "[0x0 0x1 0x2]"
  203. x_oct = "[0o0 0o1 0o2]"
  204. assert_(np.array2string(x, formatter={'all':_format_function}) ==
  205. "[. o O]")
  206. assert_(np.array2string(x, formatter={'int_kind':_format_function}) ==
  207. "[. o O]")
  208. assert_(np.array2string(x, formatter={'all':lambda x: "%.4f" % x}) ==
  209. "[0.0000 1.0000 2.0000]")
  210. assert_equal(np.array2string(x, formatter={'int':lambda x: hex(x)}),
  211. x_hex)
  212. assert_equal(np.array2string(x, formatter={'int':lambda x: oct(x)}),
  213. x_oct)
  214. x = np.arange(3.)
  215. assert_(np.array2string(x, formatter={'float_kind':lambda x: "%.2f" % x}) ==
  216. "[0.00 1.00 2.00]")
  217. assert_(np.array2string(x, formatter={'float':lambda x: "%.2f" % x}) ==
  218. "[0.00 1.00 2.00]")
  219. s = np.array(['abc', 'def'])
  220. assert_(np.array2string(s, formatter={'numpystr':lambda s: s*2}) ==
  221. '[abcabc defdef]')
  222. def test_structure_format(self):
  223. dt = np.dtype([('name', np.str_, 16), ('grades', np.float64, (2,))])
  224. x = np.array([('Sarah', (8.0, 7.0)), ('John', (6.0, 7.0))], dtype=dt)
  225. assert_equal(np.array2string(x),
  226. "[('Sarah', [8., 7.]) ('John', [6., 7.])]")
  227. np.set_printoptions(legacy='1.13')
  228. try:
  229. # for issue #5692
  230. A = np.zeros(shape=10, dtype=[("A", "M8[s]")])
  231. A[5:].fill(np.datetime64('NaT'))
  232. assert_equal(
  233. np.array2string(A),
  234. textwrap.dedent("""\
  235. [('1970-01-01T00:00:00',) ('1970-01-01T00:00:00',) ('1970-01-01T00:00:00',)
  236. ('1970-01-01T00:00:00',) ('1970-01-01T00:00:00',) ('NaT',) ('NaT',)
  237. ('NaT',) ('NaT',) ('NaT',)]""")
  238. )
  239. finally:
  240. np.set_printoptions(legacy=False)
  241. # same again, but with non-legacy behavior
  242. assert_equal(
  243. np.array2string(A),
  244. textwrap.dedent("""\
  245. [('1970-01-01T00:00:00',) ('1970-01-01T00:00:00',)
  246. ('1970-01-01T00:00:00',) ('1970-01-01T00:00:00',)
  247. ('1970-01-01T00:00:00',) ( 'NaT',)
  248. ( 'NaT',) ( 'NaT',)
  249. ( 'NaT',) ( 'NaT',)]""")
  250. )
  251. # and again, with timedeltas
  252. A = np.full(10, 123456, dtype=[("A", "m8[s]")])
  253. A[5:].fill(np.datetime64('NaT'))
  254. assert_equal(
  255. np.array2string(A),
  256. textwrap.dedent("""\
  257. [(123456,) (123456,) (123456,) (123456,) (123456,) ( 'NaT',) ( 'NaT',)
  258. ( 'NaT',) ( 'NaT',) ( 'NaT',)]""")
  259. )
  260. # See #8160
  261. struct_int = np.array([([1, -1],), ([123, 1],)], dtype=[('B', 'i4', 2)])
  262. assert_equal(np.array2string(struct_int),
  263. "[([ 1, -1],) ([123, 1],)]")
  264. struct_2dint = np.array([([[0, 1], [2, 3]],), ([[12, 0], [0, 0]],)],
  265. dtype=[('B', 'i4', (2, 2))])
  266. assert_equal(np.array2string(struct_2dint),
  267. "[([[ 0, 1], [ 2, 3]],) ([[12, 0], [ 0, 0]],)]")
  268. # See #8172
  269. array_scalar = np.array(
  270. (1., 2.1234567890123456789, 3.), dtype=('f8,f8,f8'))
  271. assert_equal(np.array2string(array_scalar), "(1., 2.12345679, 3.)")
  272. def test_unstructured_void_repr(self):
  273. a = np.array([27, 91, 50, 75, 7, 65, 10, 8,
  274. 27, 91, 51, 49,109, 82,101,100], dtype='u1').view('V8')
  275. assert_equal(repr(a[0]), r"void(b'\x1B\x5B\x32\x4B\x07\x41\x0A\x08')")
  276. assert_equal(str(a[0]), r"b'\x1B\x5B\x32\x4B\x07\x41\x0A\x08'")
  277. assert_equal(repr(a),
  278. r"array([b'\x1B\x5B\x32\x4B\x07\x41\x0A\x08'," "\n"
  279. r" b'\x1B\x5B\x33\x31\x6D\x52\x65\x64'], dtype='|V8')")
  280. assert_equal(eval(repr(a), vars(np)), a)
  281. assert_equal(eval(repr(a[0]), vars(np)), a[0])
  282. def test_edgeitems_kwarg(self):
  283. # previously the global print options would be taken over the kwarg
  284. arr = np.zeros(3, int)
  285. assert_equal(
  286. np.array2string(arr, edgeitems=1, threshold=0),
  287. "[0 ... 0]"
  288. )
  289. def test_summarize_1d(self):
  290. A = np.arange(1001)
  291. strA = '[ 0 1 2 ... 998 999 1000]'
  292. assert_equal(str(A), strA)
  293. reprA = 'array([ 0, 1, 2, ..., 998, 999, 1000])'
  294. assert_equal(repr(A), reprA)
  295. def test_summarize_2d(self):
  296. A = np.arange(1002).reshape(2, 501)
  297. strA = '[[ 0 1 2 ... 498 499 500]\n' \
  298. ' [ 501 502 503 ... 999 1000 1001]]'
  299. assert_equal(str(A), strA)
  300. reprA = 'array([[ 0, 1, 2, ..., 498, 499, 500],\n' \
  301. ' [ 501, 502, 503, ..., 999, 1000, 1001]])'
  302. assert_equal(repr(A), reprA)
  303. def test_linewidth(self):
  304. a = np.full(6, 1)
  305. def make_str(a, width, **kw):
  306. return np.array2string(a, separator="", max_line_width=width, **kw)
  307. assert_equal(make_str(a, 8, legacy='1.13'), '[111111]')
  308. assert_equal(make_str(a, 7, legacy='1.13'), '[111111]')
  309. assert_equal(make_str(a, 5, legacy='1.13'), '[1111\n'
  310. ' 11]')
  311. assert_equal(make_str(a, 8), '[111111]')
  312. assert_equal(make_str(a, 7), '[11111\n'
  313. ' 1]')
  314. assert_equal(make_str(a, 5), '[111\n'
  315. ' 111]')
  316. b = a[None,None,:]
  317. assert_equal(make_str(b, 12, legacy='1.13'), '[[[111111]]]')
  318. assert_equal(make_str(b, 9, legacy='1.13'), '[[[111111]]]')
  319. assert_equal(make_str(b, 8, legacy='1.13'), '[[[11111\n'
  320. ' 1]]]')
  321. assert_equal(make_str(b, 12), '[[[111111]]]')
  322. assert_equal(make_str(b, 9), '[[[111\n'
  323. ' 111]]]')
  324. assert_equal(make_str(b, 8), '[[[11\n'
  325. ' 11\n'
  326. ' 11]]]')
  327. def test_wide_element(self):
  328. a = np.array(['xxxxx'])
  329. assert_equal(
  330. np.array2string(a, max_line_width=5),
  331. "['xxxxx']"
  332. )
  333. assert_equal(
  334. np.array2string(a, max_line_width=5, legacy='1.13'),
  335. "[ 'xxxxx']"
  336. )
  337. def test_multiline_repr(self):
  338. class MultiLine:
  339. def __repr__(self):
  340. return "Line 1\nLine 2"
  341. a = np.array([[None, MultiLine()], [MultiLine(), None]])
  342. assert_equal(
  343. np.array2string(a),
  344. '[[None Line 1\n'
  345. ' Line 2]\n'
  346. ' [Line 1\n'
  347. ' Line 2 None]]'
  348. )
  349. assert_equal(
  350. np.array2string(a, max_line_width=5),
  351. '[[None\n'
  352. ' Line 1\n'
  353. ' Line 2]\n'
  354. ' [Line 1\n'
  355. ' Line 2\n'
  356. ' None]]'
  357. )
  358. assert_equal(
  359. repr(a),
  360. 'array([[None, Line 1\n'
  361. ' Line 2],\n'
  362. ' [Line 1\n'
  363. ' Line 2, None]], dtype=object)'
  364. )
  365. class MultiLineLong:
  366. def __repr__(self):
  367. return "Line 1\nLooooooooooongestLine2\nLongerLine 3"
  368. a = np.array([[None, MultiLineLong()], [MultiLineLong(), None]])
  369. assert_equal(
  370. repr(a),
  371. 'array([[None, Line 1\n'
  372. ' LooooooooooongestLine2\n'
  373. ' LongerLine 3 ],\n'
  374. ' [Line 1\n'
  375. ' LooooooooooongestLine2\n'
  376. ' LongerLine 3 , None]], dtype=object)'
  377. )
  378. assert_equal(
  379. np.array_repr(a, 20),
  380. 'array([[None,\n'
  381. ' Line 1\n'
  382. ' LooooooooooongestLine2\n'
  383. ' LongerLine 3 ],\n'
  384. ' [Line 1\n'
  385. ' LooooooooooongestLine2\n'
  386. ' LongerLine 3 ,\n'
  387. ' None]],\n'
  388. ' dtype=object)'
  389. )
  390. def test_nested_array_repr(self):
  391. a = np.empty((2, 2), dtype=object)
  392. a[0, 0] = np.eye(2)
  393. a[0, 1] = np.eye(3)
  394. a[1, 0] = None
  395. a[1, 1] = np.ones((3, 1))
  396. assert_equal(
  397. repr(a),
  398. 'array([[array([[1., 0.],\n'
  399. ' [0., 1.]]), array([[1., 0., 0.],\n'
  400. ' [0., 1., 0.],\n'
  401. ' [0., 0., 1.]])],\n'
  402. ' [None, array([[1.],\n'
  403. ' [1.],\n'
  404. ' [1.]])]], dtype=object)'
  405. )
  406. @given(hynp.from_dtype(np.dtype("U")))
  407. def test_any_text(self, text):
  408. # This test checks that, given any value that can be represented in an
  409. # array of dtype("U") (i.e. unicode string), ...
  410. a = np.array([text, text, text])
  411. # casting a list of them to an array does not e.g. truncate the value
  412. assert_equal(a[0], text)
  413. # and that np.array2string puts a newline in the expected location
  414. expected_repr = "[{0!r} {0!r}\n {0!r}]".format(text)
  415. result = np.array2string(a, max_line_width=len(repr(text)) * 2 + 3)
  416. assert_equal(result, expected_repr)
  417. @pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts")
  418. def test_refcount(self):
  419. # make sure we do not hold references to the array due to a recursive
  420. # closure (gh-10620)
  421. gc.disable()
  422. a = np.arange(2)
  423. r1 = sys.getrefcount(a)
  424. np.array2string(a)
  425. np.array2string(a)
  426. r2 = sys.getrefcount(a)
  427. gc.collect()
  428. gc.enable()
  429. assert_(r1 == r2)
  430. class TestPrintOptions:
  431. """Test getting and setting global print options."""
  432. def setup_method(self):
  433. self.oldopts = np.get_printoptions()
  434. def teardown_method(self):
  435. np.set_printoptions(**self.oldopts)
  436. def test_basic(self):
  437. x = np.array([1.5, 0, 1.234567890])
  438. assert_equal(repr(x), "array([1.5 , 0. , 1.23456789])")
  439. np.set_printoptions(precision=4)
  440. assert_equal(repr(x), "array([1.5 , 0. , 1.2346])")
  441. def test_precision_zero(self):
  442. np.set_printoptions(precision=0)
  443. for values, string in (
  444. ([0.], "0."), ([.3], "0."), ([-.3], "-0."), ([.7], "1."),
  445. ([1.5], "2."), ([-1.5], "-2."), ([-15.34], "-15."),
  446. ([100.], "100."), ([.2, -1, 122.51], " 0., -1., 123."),
  447. ([0], "0"), ([-12], "-12"), ([complex(.3, -.7)], "0.-1.j")):
  448. x = np.array(values)
  449. assert_equal(repr(x), "array([%s])" % string)
  450. def test_formatter(self):
  451. x = np.arange(3)
  452. np.set_printoptions(formatter={'all':lambda x: str(x-1)})
  453. assert_equal(repr(x), "array([-1, 0, 1])")
  454. def test_formatter_reset(self):
  455. x = np.arange(3)
  456. np.set_printoptions(formatter={'all':lambda x: str(x-1)})
  457. assert_equal(repr(x), "array([-1, 0, 1])")
  458. np.set_printoptions(formatter={'int':None})
  459. assert_equal(repr(x), "array([0, 1, 2])")
  460. np.set_printoptions(formatter={'all':lambda x: str(x-1)})
  461. assert_equal(repr(x), "array([-1, 0, 1])")
  462. np.set_printoptions(formatter={'all':None})
  463. assert_equal(repr(x), "array([0, 1, 2])")
  464. np.set_printoptions(formatter={'int':lambda x: str(x-1)})
  465. assert_equal(repr(x), "array([-1, 0, 1])")
  466. np.set_printoptions(formatter={'int_kind':None})
  467. assert_equal(repr(x), "array([0, 1, 2])")
  468. x = np.arange(3.)
  469. np.set_printoptions(formatter={'float':lambda x: str(x-1)})
  470. assert_equal(repr(x), "array([-1.0, 0.0, 1.0])")
  471. np.set_printoptions(formatter={'float_kind':None})
  472. assert_equal(repr(x), "array([0., 1., 2.])")
  473. def test_0d_arrays(self):
  474. assert_equal(str(np.array('café', '<U4')), 'café')
  475. assert_equal(repr(np.array('café', '<U4')),
  476. "array('café', dtype='<U4')")
  477. assert_equal(str(np.array('test', np.str_)), 'test')
  478. a = np.zeros(1, dtype=[('a', '<i4', (3,))])
  479. assert_equal(str(a[0]), '([0, 0, 0],)')
  480. assert_equal(repr(np.datetime64('2005-02-25')[...]),
  481. "array('2005-02-25', dtype='datetime64[D]')")
  482. assert_equal(repr(np.timedelta64('10', 'Y')[...]),
  483. "array(10, dtype='timedelta64[Y]')")
  484. # repr of 0d arrays is affected by printoptions
  485. x = np.array(1)
  486. np.set_printoptions(formatter={'all':lambda x: "test"})
  487. assert_equal(repr(x), "array(test)")
  488. # str is unaffected
  489. assert_equal(str(x), "1")
  490. # check `style` arg raises
  491. assert_warns(DeprecationWarning, np.array2string,
  492. np.array(1.), style=repr)
  493. # but not in legacy mode
  494. np.array2string(np.array(1.), style=repr, legacy='1.13')
  495. # gh-10934 style was broken in legacy mode, check it works
  496. np.array2string(np.array(1.), legacy='1.13')
  497. def test_float_spacing(self):
  498. x = np.array([1., 2., 3.])
  499. y = np.array([1., 2., -10.])
  500. z = np.array([100., 2., -1.])
  501. w = np.array([-100., 2., 1.])
  502. assert_equal(repr(x), 'array([1., 2., 3.])')
  503. assert_equal(repr(y), 'array([ 1., 2., -10.])')
  504. assert_equal(repr(np.array(y[0])), 'array(1.)')
  505. assert_equal(repr(np.array(y[-1])), 'array(-10.)')
  506. assert_equal(repr(z), 'array([100., 2., -1.])')
  507. assert_equal(repr(w), 'array([-100., 2., 1.])')
  508. assert_equal(repr(np.array([np.nan, np.inf])), 'array([nan, inf])')
  509. assert_equal(repr(np.array([np.nan, -np.inf])), 'array([ nan, -inf])')
  510. x = np.array([np.inf, 100000, 1.1234])
  511. y = np.array([np.inf, 100000, -1.1234])
  512. z = np.array([np.inf, 1.1234, -1e120])
  513. np.set_printoptions(precision=2)
  514. assert_equal(repr(x), 'array([ inf, 1.00e+05, 1.12e+00])')
  515. assert_equal(repr(y), 'array([ inf, 1.00e+05, -1.12e+00])')
  516. assert_equal(repr(z), 'array([ inf, 1.12e+000, -1.00e+120])')
  517. def test_bool_spacing(self):
  518. assert_equal(repr(np.array([True, True])),
  519. 'array([ True, True])')
  520. assert_equal(repr(np.array([True, False])),
  521. 'array([ True, False])')
  522. assert_equal(repr(np.array([True])),
  523. 'array([ True])')
  524. assert_equal(repr(np.array(True)),
  525. 'array(True)')
  526. assert_equal(repr(np.array(False)),
  527. 'array(False)')
  528. def test_sign_spacing(self):
  529. a = np.arange(4.)
  530. b = np.array([1.234e9])
  531. c = np.array([1.0 + 1.0j, 1.123456789 + 1.123456789j], dtype='c16')
  532. assert_equal(repr(a), 'array([0., 1., 2., 3.])')
  533. assert_equal(repr(np.array(1.)), 'array(1.)')
  534. assert_equal(repr(b), 'array([1.234e+09])')
  535. assert_equal(repr(np.array([0.])), 'array([0.])')
  536. assert_equal(repr(c),
  537. "array([1. +1.j , 1.12345679+1.12345679j])")
  538. assert_equal(repr(np.array([0., -0.])), 'array([ 0., -0.])')
  539. np.set_printoptions(sign=' ')
  540. assert_equal(repr(a), 'array([ 0., 1., 2., 3.])')
  541. assert_equal(repr(np.array(1.)), 'array( 1.)')
  542. assert_equal(repr(b), 'array([ 1.234e+09])')
  543. assert_equal(repr(c),
  544. "array([ 1. +1.j , 1.12345679+1.12345679j])")
  545. assert_equal(repr(np.array([0., -0.])), 'array([ 0., -0.])')
  546. np.set_printoptions(sign='+')
  547. assert_equal(repr(a), 'array([+0., +1., +2., +3.])')
  548. assert_equal(repr(np.array(1.)), 'array(+1.)')
  549. assert_equal(repr(b), 'array([+1.234e+09])')
  550. assert_equal(repr(c),
  551. "array([+1. +1.j , +1.12345679+1.12345679j])")
  552. np.set_printoptions(legacy='1.13')
  553. assert_equal(repr(a), 'array([ 0., 1., 2., 3.])')
  554. assert_equal(repr(b), 'array([ 1.23400000e+09])')
  555. assert_equal(repr(-b), 'array([ -1.23400000e+09])')
  556. assert_equal(repr(np.array(1.)), 'array(1.0)')
  557. assert_equal(repr(np.array([0.])), 'array([ 0.])')
  558. assert_equal(repr(c),
  559. "array([ 1.00000000+1.j , 1.12345679+1.12345679j])")
  560. # gh-10383
  561. assert_equal(str(np.array([-1., 10])), "[ -1. 10.]")
  562. assert_raises(TypeError, np.set_printoptions, wrongarg=True)
  563. def test_float_overflow_nowarn(self):
  564. # make sure internal computations in FloatingFormat don't
  565. # warn about overflow
  566. repr(np.array([1e4, 0.1], dtype='f2'))
  567. def test_sign_spacing_structured(self):
  568. a = np.ones(2, dtype='<f,<f')
  569. assert_equal(repr(a),
  570. "array([(1., 1.), (1., 1.)], dtype=[('f0', '<f4'), ('f1', '<f4')])")
  571. assert_equal(repr(a[0]), "(1., 1.)")
  572. def test_floatmode(self):
  573. x = np.array([0.6104, 0.922, 0.457, 0.0906, 0.3733, 0.007244,
  574. 0.5933, 0.947, 0.2383, 0.4226], dtype=np.float16)
  575. y = np.array([0.2918820979355541, 0.5064172631089138,
  576. 0.2848750619642916, 0.4342965294660567,
  577. 0.7326538397312751, 0.3459503329096204,
  578. 0.0862072768214508, 0.39112753029631175],
  579. dtype=np.float64)
  580. z = np.arange(6, dtype=np.float16)/10
  581. c = np.array([1.0 + 1.0j, 1.123456789 + 1.123456789j], dtype='c16')
  582. # also make sure 1e23 is right (is between two fp numbers)
  583. w = np.array(['1e{}'.format(i) for i in range(25)], dtype=np.float64)
  584. # note: we construct w from the strings `1eXX` instead of doing
  585. # `10.**arange(24)` because it turns out the two are not equivalent in
  586. # python. On some architectures `1e23 != 10.**23`.
  587. wp = np.array([1.234e1, 1e2, 1e123])
  588. # unique mode
  589. np.set_printoptions(floatmode='unique')
  590. assert_equal(repr(x),
  591. "array([0.6104 , 0.922 , 0.457 , 0.0906 , 0.3733 , 0.007244,\n"
  592. " 0.5933 , 0.947 , 0.2383 , 0.4226 ], dtype=float16)")
  593. assert_equal(repr(y),
  594. "array([0.2918820979355541 , 0.5064172631089138 , 0.2848750619642916 ,\n"
  595. " 0.4342965294660567 , 0.7326538397312751 , 0.3459503329096204 ,\n"
  596. " 0.0862072768214508 , 0.39112753029631175])")
  597. assert_equal(repr(z),
  598. "array([0. , 0.1, 0.2, 0.3, 0.4, 0.5], dtype=float16)")
  599. assert_equal(repr(w),
  600. "array([1.e+00, 1.e+01, 1.e+02, 1.e+03, 1.e+04, 1.e+05, 1.e+06, 1.e+07,\n"
  601. " 1.e+08, 1.e+09, 1.e+10, 1.e+11, 1.e+12, 1.e+13, 1.e+14, 1.e+15,\n"
  602. " 1.e+16, 1.e+17, 1.e+18, 1.e+19, 1.e+20, 1.e+21, 1.e+22, 1.e+23,\n"
  603. " 1.e+24])")
  604. assert_equal(repr(wp), "array([1.234e+001, 1.000e+002, 1.000e+123])")
  605. assert_equal(repr(c),
  606. "array([1. +1.j , 1.123456789+1.123456789j])")
  607. # maxprec mode, precision=8
  608. np.set_printoptions(floatmode='maxprec', precision=8)
  609. assert_equal(repr(x),
  610. "array([0.6104 , 0.922 , 0.457 , 0.0906 , 0.3733 , 0.007244,\n"
  611. " 0.5933 , 0.947 , 0.2383 , 0.4226 ], dtype=float16)")
  612. assert_equal(repr(y),
  613. "array([0.2918821 , 0.50641726, 0.28487506, 0.43429653, 0.73265384,\n"
  614. " 0.34595033, 0.08620728, 0.39112753])")
  615. assert_equal(repr(z),
  616. "array([0. , 0.1, 0.2, 0.3, 0.4, 0.5], dtype=float16)")
  617. assert_equal(repr(w[::5]),
  618. "array([1.e+00, 1.e+05, 1.e+10, 1.e+15, 1.e+20])")
  619. assert_equal(repr(wp), "array([1.234e+001, 1.000e+002, 1.000e+123])")
  620. assert_equal(repr(c),
  621. "array([1. +1.j , 1.12345679+1.12345679j])")
  622. # fixed mode, precision=4
  623. np.set_printoptions(floatmode='fixed', precision=4)
  624. assert_equal(repr(x),
  625. "array([0.6104, 0.9219, 0.4570, 0.0906, 0.3733, 0.0072, 0.5933, 0.9468,\n"
  626. " 0.2383, 0.4226], dtype=float16)")
  627. assert_equal(repr(y),
  628. "array([0.2919, 0.5064, 0.2849, 0.4343, 0.7327, 0.3460, 0.0862, 0.3911])")
  629. assert_equal(repr(z),
  630. "array([0.0000, 0.1000, 0.2000, 0.3000, 0.3999, 0.5000], dtype=float16)")
  631. assert_equal(repr(w[::5]),
  632. "array([1.0000e+00, 1.0000e+05, 1.0000e+10, 1.0000e+15, 1.0000e+20])")
  633. assert_equal(repr(wp), "array([1.2340e+001, 1.0000e+002, 1.0000e+123])")
  634. assert_equal(repr(np.zeros(3)), "array([0.0000, 0.0000, 0.0000])")
  635. assert_equal(repr(c),
  636. "array([1.0000+1.0000j, 1.1235+1.1235j])")
  637. # for larger precision, representation error becomes more apparent:
  638. np.set_printoptions(floatmode='fixed', precision=8)
  639. assert_equal(repr(z),
  640. "array([0.00000000, 0.09997559, 0.19995117, 0.30004883, 0.39990234,\n"
  641. " 0.50000000], dtype=float16)")
  642. # maxprec_equal mode, precision=8
  643. np.set_printoptions(floatmode='maxprec_equal', precision=8)
  644. assert_equal(repr(x),
  645. "array([0.610352, 0.921875, 0.457031, 0.090576, 0.373291, 0.007244,\n"
  646. " 0.593262, 0.946777, 0.238281, 0.422607], dtype=float16)")
  647. assert_equal(repr(y),
  648. "array([0.29188210, 0.50641726, 0.28487506, 0.43429653, 0.73265384,\n"
  649. " 0.34595033, 0.08620728, 0.39112753])")
  650. assert_equal(repr(z),
  651. "array([0.0, 0.1, 0.2, 0.3, 0.4, 0.5], dtype=float16)")
  652. assert_equal(repr(w[::5]),
  653. "array([1.e+00, 1.e+05, 1.e+10, 1.e+15, 1.e+20])")
  654. assert_equal(repr(wp), "array([1.234e+001, 1.000e+002, 1.000e+123])")
  655. assert_equal(repr(c),
  656. "array([1.00000000+1.00000000j, 1.12345679+1.12345679j])")
  657. # test unique special case (gh-18609)
  658. a = np.float64.fromhex('-1p-97')
  659. assert_equal(np.float64(np.array2string(a, floatmode='unique')), a)
  660. def test_legacy_mode_scalars(self):
  661. # in legacy mode, str of floats get truncated, and complex scalars
  662. # use * for non-finite imaginary part
  663. np.set_printoptions(legacy='1.13')
  664. assert_equal(str(np.float64(1.123456789123456789)), '1.12345678912')
  665. assert_equal(str(np.complex128(complex(1, np.nan))), '(1+nan*j)')
  666. np.set_printoptions(legacy=False)
  667. assert_equal(str(np.float64(1.123456789123456789)),
  668. '1.1234567891234568')
  669. assert_equal(str(np.complex128(complex(1, np.nan))), '(1+nanj)')
  670. def test_legacy_stray_comma(self):
  671. np.set_printoptions(legacy='1.13')
  672. assert_equal(str(np.arange(10000)), '[ 0 1 2 ..., 9997 9998 9999]')
  673. np.set_printoptions(legacy=False)
  674. assert_equal(str(np.arange(10000)), '[ 0 1 2 ... 9997 9998 9999]')
  675. def test_dtype_linewidth_wrapping(self):
  676. np.set_printoptions(linewidth=75)
  677. assert_equal(repr(np.arange(10,20., dtype='f4')),
  678. "array([10., 11., 12., 13., 14., 15., 16., 17., 18., 19.], dtype=float32)")
  679. assert_equal(repr(np.arange(10,23., dtype='f4')), textwrap.dedent("""\
  680. array([10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., 22.],
  681. dtype=float32)"""))
  682. styp = '<U4'
  683. assert_equal(repr(np.ones(3, dtype=styp)),
  684. "array(['1', '1', '1'], dtype='{}')".format(styp))
  685. assert_equal(repr(np.ones(12, dtype=styp)), textwrap.dedent("""\
  686. array(['1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1'],
  687. dtype='{}')""".format(styp)))
  688. def test_linewidth_repr(self):
  689. a = np.full(7, fill_value=2)
  690. np.set_printoptions(linewidth=17)
  691. assert_equal(
  692. repr(a),
  693. textwrap.dedent("""\
  694. array([2, 2, 2,
  695. 2, 2, 2,
  696. 2])""")
  697. )
  698. np.set_printoptions(linewidth=17, legacy='1.13')
  699. assert_equal(
  700. repr(a),
  701. textwrap.dedent("""\
  702. array([2, 2, 2,
  703. 2, 2, 2, 2])""")
  704. )
  705. a = np.full(8, fill_value=2)
  706. np.set_printoptions(linewidth=18, legacy=False)
  707. assert_equal(
  708. repr(a),
  709. textwrap.dedent("""\
  710. array([2, 2, 2,
  711. 2, 2, 2,
  712. 2, 2])""")
  713. )
  714. np.set_printoptions(linewidth=18, legacy='1.13')
  715. assert_equal(
  716. repr(a),
  717. textwrap.dedent("""\
  718. array([2, 2, 2, 2,
  719. 2, 2, 2, 2])""")
  720. )
  721. def test_linewidth_str(self):
  722. a = np.full(18, fill_value=2)
  723. np.set_printoptions(linewidth=18)
  724. assert_equal(
  725. str(a),
  726. textwrap.dedent("""\
  727. [2 2 2 2 2 2 2 2
  728. 2 2 2 2 2 2 2 2
  729. 2 2]""")
  730. )
  731. np.set_printoptions(linewidth=18, legacy='1.13')
  732. assert_equal(
  733. str(a),
  734. textwrap.dedent("""\
  735. [2 2 2 2 2 2 2 2 2
  736. 2 2 2 2 2 2 2 2 2]""")
  737. )
  738. def test_edgeitems(self):
  739. np.set_printoptions(edgeitems=1, threshold=1)
  740. a = np.arange(27).reshape((3, 3, 3))
  741. assert_equal(
  742. repr(a),
  743. textwrap.dedent("""\
  744. array([[[ 0, ..., 2],
  745. ...,
  746. [ 6, ..., 8]],
  747. ...,
  748. [[18, ..., 20],
  749. ...,
  750. [24, ..., 26]]])""")
  751. )
  752. b = np.zeros((3, 3, 1, 1))
  753. assert_equal(
  754. repr(b),
  755. textwrap.dedent("""\
  756. array([[[[0.]],
  757. ...,
  758. [[0.]]],
  759. ...,
  760. [[[0.]],
  761. ...,
  762. [[0.]]]])""")
  763. )
  764. # 1.13 had extra trailing spaces, and was missing newlines
  765. np.set_printoptions(legacy='1.13')
  766. assert_equal(
  767. repr(a),
  768. textwrap.dedent("""\
  769. array([[[ 0, ..., 2],
  770. ...,
  771. [ 6, ..., 8]],
  772. ...,
  773. [[18, ..., 20],
  774. ...,
  775. [24, ..., 26]]])""")
  776. )
  777. assert_equal(
  778. repr(b),
  779. textwrap.dedent("""\
  780. array([[[[ 0.]],
  781. ...,
  782. [[ 0.]]],
  783. ...,
  784. [[[ 0.]],
  785. ...,
  786. [[ 0.]]]])""")
  787. )
  788. def test_bad_args(self):
  789. assert_raises(ValueError, np.set_printoptions, threshold=float('nan'))
  790. assert_raises(TypeError, np.set_printoptions, threshold='1')
  791. assert_raises(TypeError, np.set_printoptions, threshold=b'1')
  792. assert_raises(TypeError, np.set_printoptions, precision='1')
  793. assert_raises(TypeError, np.set_printoptions, precision=1.5)
  794. def test_unicode_object_array():
  795. expected = "array(['é'], dtype=object)"
  796. x = np.array(['\xe9'], dtype=object)
  797. assert_equal(repr(x), expected)
  798. class TestContextManager:
  799. def test_ctx_mgr(self):
  800. # test that context manager actually works
  801. with np.printoptions(precision=2):
  802. s = str(np.array([2.0]) / 3)
  803. assert_equal(s, '[0.67]')
  804. def test_ctx_mgr_restores(self):
  805. # test that print options are actually restrored
  806. opts = np.get_printoptions()
  807. with np.printoptions(precision=opts['precision'] - 1,
  808. linewidth=opts['linewidth'] - 4):
  809. pass
  810. assert_equal(np.get_printoptions(), opts)
  811. def test_ctx_mgr_exceptions(self):
  812. # test that print options are restored even if an exception is raised
  813. opts = np.get_printoptions()
  814. try:
  815. with np.printoptions(precision=2, linewidth=11):
  816. raise ValueError
  817. except ValueError:
  818. pass
  819. assert_equal(np.get_printoptions(), opts)
  820. def test_ctx_mgr_as_smth(self):
  821. opts = {"precision": 2}
  822. with np.printoptions(**opts) as ctx:
  823. saved_opts = ctx.copy()
  824. assert_equal({k: saved_opts[k] for k in opts}, opts)