test_arrayprint.py 36 KB

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