Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve prettyprinting of multidimensional numpy arrays. #50

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

anntzer
Copy link
Contributor

@anntzer anntzer commented Mar 26, 2019

Items are now aligned by relying on numpy's own implementation.

Fixes most of #49.

It looks like I needed to insert hard linebreaks myself to get the right indentation. One minor remaining problematic point is that the array's dtype gets printed on the same line as the array (if it fits) rather than on a separate line:

In [1]: np.arange(4, dtype=np.uint8).reshape((2, 2))                                                                 
Out[1]: 
numpy.ndarray(
    [[0, 1],
     [2, 3]], dtype='uint8')  # dtype='uint8' should go to the next line...

I guess the proper fix would be to move the dtype-handling logic from pretty_numpy to pretty_arraywrapper as well, but this would also require (I think?) duplicating some of the pretty_call logic, so it won't be for this PR...

Items are now aligned by relying on numpy's own implementation.
@anntzer
Copy link
Contributor Author

anntzer commented Mar 26, 2019

After some more investigation, looks like the desired result (forcing a newline before the dtype if the array repr goes over multiple lines) can be achieved with

diff --git i/prettyprinter/extras/numpy.py w/prettyprinter/extras/numpy.py
index e9aa1f6..7dffb34 100644
--- i/prettyprinter/extras/numpy.py
+++ w/prettyprinter/extras/numpy.py
@@ -47,8 +47,8 @@ def pretty_arraywrapper(value, ctx):
     if len(lines) == 1:
         return s
     else:
-        interspersed = [HARDLINE] * 2 * len(lines)
-        interspersed[1::2] = lines
+        interspersed = [HARDLINE] * (2 * len(lines) - 1)
+        interspersed[::2] = lines
         return Concat(interspersed)
 
 
diff --git i/prettyprinter/prettyprinter.py w/prettyprinter/prettyprinter.py
index 521ad01..e249284 100644
--- i/prettyprinter/prettyprinter.py
+++ w/prettyprinter/prettyprinter.py
@@ -893,6 +893,7 @@ def build_fncall(
         fndoc = general_identifier(fndoc)
 
     has_comment = bool(trailing_comment)
+    has_hardline = False
 
     argdocs = list(argdocs)
     kwargdocs = list(kwargdocs)
@@ -957,6 +958,10 @@ def build_fncall(
         else:
             comment_str = None
 
+        from .doctypes import Concat, HARDLINE
+        if isinstance(doc, Concat) and any(doc is HARDLINE for doc in doc.docs):
+            has_hardline = True
+
         part = concat([doc, NIL if last else COMMA])
 
         if comment_str:
@@ -982,7 +987,7 @@ def build_fncall(
 
     outer = (
         always_break
-        if has_comment
+        if has_comment or has_hardline
         else group
     )

(on top of this PR's patch).

I guess always breaking when a subdoc has hardlines makes sense? Not sure about possible unintended consequences, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant