summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPan Jan <rumcajsgajos@gmail.com>2020-04-16 14:52:14 +0200
committerPan Jan <rumcajsgajos@gmail.com>2020-04-16 16:41:58 +0200
commit1511c1f267c35b8e619b3b1c913f336ae7505910 (patch)
tree4bd12e1a3b3fd27b7a49c995ae2be2ce3923e67d
parent52c9e6f2e3e72081576fc7f629fe3eb0c67b143b (diff)
downloadnumpy-1511c1f267c35b8e619b3b1c913f336ae7505910.tar.gz
ENH: improve printing of arrays with multi-line reprs
-rw-r--r--numpy/core/arrayprint.py31
-rw-r--r--numpy/core/tests/test_arrayprint.py31
2 files changed, 58 insertions, 4 deletions
diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py
index 456ef76f0..b08005700 100644
--- a/numpy/core/arrayprint.py
+++ b/numpy/core/arrayprint.py
@@ -695,7 +695,7 @@ def array2string(a, max_line_width=None, precision=None,
def _extendLine(s, line, word, line_width, next_line_prefix, legacy):
needs_wrap = len(line) + len(word) > line_width
if legacy != '1.13':
- s# don't wrap lines if it won't help
+ # don't wrap lines if it won't help
if len(line) <= len(next_line_prefix):
needs_wrap = False
@@ -706,6 +706,27 @@ def _extendLine(s, line, word, line_width, next_line_prefix, legacy):
return s, line
+def _extendLine_pretty(s, line, word, line_width, next_line_prefix, legacy):
+ """
+ Extends line with nicely formatted (possibly multi-line) string ``word``.
+ """
+ if legacy == '1.13':
+ return _extendLine(s, line, word, line_width, next_line_prefix, legacy)
+
+ words = word.splitlines()
+ line_length = len(line)
+ s, line = _extendLine(
+ s, line, words[0], line_width, next_line_prefix, legacy)
+ for word in words[1::]:
+ s += line.rstrip() + '\n'
+ if line_length + len(word) > line_width \
+ and line_length > len(next_line_prefix):
+ line = next_line_prefix + word
+ else:
+ line = line_length*' ' + word
+
+ return s, line
+
def _formatArray(a, format_function, line_width, next_line_prefix,
separator, edge_items, summary_insert, legacy):
"""formatArray is designed for two modes of operation:
@@ -758,7 +779,7 @@ def _formatArray(a, format_function, line_width, next_line_prefix,
line = hanging_indent
for i in range(leading_items):
word = recurser(index + (i,), next_hanging_indent, next_width)
- s, line = _extendLine(
+ s, line = _extendLine_pretty(
s, line, word, elem_width, hanging_indent, legacy)
line += separator
@@ -772,7 +793,7 @@ def _formatArray(a, format_function, line_width, next_line_prefix,
for i in range(trailing_items, 1, -1):
word = recurser(index + (-i,), next_hanging_indent, next_width)
- s, line = _extendLine(
+ s, line = _extendLine_pretty(
s, line, word, elem_width, hanging_indent, legacy)
line += separator
@@ -780,7 +801,7 @@ def _formatArray(a, format_function, line_width, next_line_prefix,
# width of the separator is not considered on 1.13
elem_width = curr_width
word = recurser(index + (-1,), next_hanging_indent, next_width)
- s, line = _extendLine(
+ s, line = _extendLine_pretty(
s, line, word, elem_width, hanging_indent, legacy)
s += line
@@ -824,6 +845,8 @@ def _formatArray(a, format_function, line_width, next_line_prefix,
# performance and PyPy friendliness, we break the cycle:
recurser = None
+
+
def _none_or_positive_arg(x, name):
if x is None:
return -1
diff --git a/numpy/core/tests/test_arrayprint.py b/numpy/core/tests/test_arrayprint.py
index e29217461..b14fcbf49 100644
--- a/numpy/core/tests/test_arrayprint.py
+++ b/numpy/core/tests/test_arrayprint.py
@@ -395,6 +395,37 @@ class TestArray2String:
"[ 'xxxxx']"
)
+ def test_multiline_repr(self):
+ class MultiLine:
+ def __repr__(self):
+ return "Line 1\nLine 2"
+
+ a = np.array([[None, MultiLine()], [MultiLine(), None]])
+
+ assert_equal(
+ np.array2string(a),
+ '[[None Line 1\n'
+ ' Line 2]\n'
+ ' [Line 1\n'
+ ' Line 2 None]]'
+ )
+ assert_equal(
+ np.array2string(a, max_line_width=5),
+ '[[None\n'
+ ' Line 1\n'
+ ' Line 2]\n'
+ ' [Line 1\n'
+ ' Line 2\n'
+ ' None]]'
+ )
+ assert_equal(
+ np.array_repr(a),
+ 'array([[None, Line 1\n'
+ ' Line 2],\n'
+ ' [Line 1\n'
+ ' Line 2, None]], dtype=object)'
+ )
+
@given(hynp.from_dtype(np.dtype("U")))
def test_any_text(self, text):
# This test checks that, given any value that can be represented in an