-
-
Notifications
You must be signed in to change notification settings - Fork 482
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
Sort dictionaries for doctests independent of ipythons pretty print #29042
Comments
Branch: u/arojas/remove_sorting_of_dicts |
Author: Antonio Rojas |
This comment has been minimized.
This comment has been minimized.
New commits:
|
Commit: |
comment:3
This is going to be quite fragile, because now you're encoding a rather arbitrary dictionary order into the doctests, where no order matters (in py3 it's probably insertion order; a change in code somewhere that changes insertion order would break tests again!). Why not introduce a little utility function
but with an appropriate routine you could print the result in a more dict-compatible way so that you can fix each doctest with a single-line edit. That way you end up with a more future-proof fix, and it makes total sense to insert such a print routine at least into the doctest namespace (but then almost by necessity also in the interactive namespace) |
comment:4
Sounds reasonable but that's beyond my ability, so someone else will have to do it. |
comment:5
The idiom
could be used to print a dict sorted by keys, which also seems to take care of nested dictionaries. On the other hand, if one really wants to keep the sorted output of dicts in general, another solution would be to add a displayhook during doctests that imitates what is currently done by IPython. This would be more robust than using |
comment:6
Replying to @mwageringel:
Thanks for the suggestion! The routine I was thinking about already exists!. I think in "examples" doctests, the
True, but that would cause a deviation between doctest output and the output that the actual example in the command line would give. The I also think that there are legitimate reasons to make doctests that do print the dict in the "Py3" order, for instance if used to compare with the iteration order. In those cases it would be possible to formulate the doctests differently, no doubt, but I would rather not preempt such use. I think putting up with having to use |
comment:7
Replying to @nbruin:
In that case, rather than injecting
This deviation already exists, as the IPython sorting of dicts is only active during doctests. That said though, I do not have a strong preference for either solution – though I agree it is generally desirable to keep doctest output as close as possible to the actual output. |
comment:8
Replying to @mwageringel:
It seems pretty_print aims at a different target: its default is latex output in the command line (that's a bad default), and in general "this function chooses the highest-quality output supported by the user interface", so that doesn't quite hit the goals of doctests (which should be concise and human-readable). If we do
we end up with better results for our doctesting purposes. But that would be worse than |
comment:9
Replying to @nbruin:
I fail to see the rationale behind defaulting to latex, or the intended use case of Should we add |
comment:10
It seems to me that it would be good to discuss this at sage-devel, because it affects all developers. Let me add that it is unclear to me what the best solution is. Initially, I liked the idea of |
Branch pushed to git repo; I updated commit sha1. New commits:
|
Branch pushed to git repo; I updated commit sha1. New commits:
|
comment:15
This needs rebasing. My own thinking is that calling the structure dictionary lead humans to have an expectation for it to be ordered the way the physical object is. In fact we have look up tables which are very handy for the computer to manipulate but not necessarily meant for full display. In most case sorting doesn't matter objectively. So I am not sure we should compare whole dictionaries for doctests. Size of the dictionary and some key elements should be enough. |
Branch pushed to git repo; I updated commit sha1. New commits:
|
comment:45
I don't quite understand what this ticket is about: 9.2 has nothing to do with python2. We can break it, why not? |
comment:46
Replying to @dimpase:
This was opened in January |
comment:47
is anything needed here for py3 ? |
comment:48
Yes - this is meant to fix the breakage that will happen in tests when upgrading ipython. "This will break the affected doctests (but not functionality) on python2" refers to the proposed patch at the time. |
comment:49
Could someone knowledgeable about the ticket please amend its description? |
This comment has been minimized.
This comment has been minimized.
comment:51
Maybe removing the sorting of dictionaries isn't necessary. We can just overwrite the pretty print function during testing: +++ b/src/sage/doctest/forker.py
@@ -61,6 +61,7 @@ from .parsing import SageOutputChecker, pre_hash, get_source
from sage.repl.user_globals import set_globals
from sage.cpython.atexit import restore_atexit
from sage.cpython.string import bytes_to_str, str_to_bytes
+import IPython.lib.pretty
# All doctests run as if the following future imports are present
@@ -86,6 +87,27 @@ _OSError_SUBCLASSES = [
exc is not OSError
]
+def _sorted_dict_pprinter_factory(start, end):
+ """
+ Factory that returns a pprint function used by the default pprint of
+ dicts and dict proxies.
+ """
+ def inner(obj, p, cycle):
+ if cycle:
+ return p.text('{...}')
+ step = len(start)
+ p.begin_group(step, start)
+ keys = obj.keys()
+ keys = IPython.lib.pretty._sorted_for_pprint(keys)
+ for idx, key in p._enumerate(keys):
+ if idx:
+ p.text(',')
+ p.breakable()
+ p.pretty(key)
+ p.text(': ')
+ p.pretty(obj[key])
+ p.end_group(step, end)
+ return inner
def init_sage():
@@ -185,11 +207,11 @@ def init_sage():
# IPython's pretty printer sorts the repr of dicts by their keys by default
# (or their keys' str() if they are not otherwise orderable). However, it
# disables this for CPython 3.6+ opting to instead display dicts' "natural"
- # insertion order, which is preserved in those versions). This makes for
- # inconsistent results with Python 2 tests that return dicts, so here we
- # force the Python 2 style dict printing
- import IPython.lib.pretty
- IPython.lib.pretty.DICT_IS_ORDERED = False
+ # insertion order, which is preserved in those versions).
+ # However, this order is random in some instances.
+ # Also code changes may change the order, but the result stays correct.
+ # So we force sorting the dictionary.
+ IPython.lib.pretty.for_type(dict, _sorted_dict_pprinter_factory('{', '}'))
# Switch on extra debugging
from sage.structure.debug_options import debug This appears to do the job. I'm testing the entire library now. |
This comment has been minimized.
This comment has been minimized.
comment:52
New commits:
|
Changed author from Antonio Rojas to Jonathan Kliem, Antonio Rojas |
Changed branch from u/fbissey/dictionaries to public/29042 |
comment:53
I can do some testing tomorrow. It looks so much simpler. |
comment:54
I was suprised how easy this actually is. Took me a number of hours to figure out though. |
comment:55
Does this need new iPython? |
comment:56
No, I didn't upgrade and it worked for me. The function https://github.com/ipython/ipython/blob/5.x/IPython/lib/pretty.py If that is a problem or if this is ever removed, we can just copy paste this tiny function. The function |
comment:57
Works for me. That's one of the things I would like to see merged soon. |
Reviewer: François Bissey |
comment:58
Thank you. |
comment:59
hopefully it simplifies the thankless task of allowing multiple versions of pari/gp, etc. |
Changed branch from public/29042 to |
This is a prerequisite for #28197 - ipython does no longer honor the DICT_IS_ORDERED variable since 7.10 [1].
[1] ipython/ipython@dffa2c3
For doctesting we overwrite the default pretty print function for dictionaries to sort the keys and behave exactly as before.
CC: @jhpalmieri @dimpase @tscrim @antonio-rojas
Component: refactoring
Author: Jonathan Kliem, Antonio Rojas
Branch/Commit:
68b10e1
Reviewer: François Bissey
Issue created by migration from https://trac.sagemath.org/ticket/29042
The text was updated successfully, but these errors were encountered: