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

Provide a limit arguments for __repr__ #85555

Closed
BernatGabor mannequin opened this issue Jul 24, 2020 · 7 comments
Closed

Provide a limit arguments for __repr__ #85555

BernatGabor mannequin opened this issue Jul 24, 2020 · 7 comments
Labels
3.10 interpreter-core (Objects, Python, Grammar, and Parser dirs)

Comments

@BernatGabor
Copy link
Mannequin

BernatGabor mannequin commented Jul 24, 2020

BPO 41383
Nosy @rhettinger, @ericvsmith, @remilapeyre

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = None
created_at = <Date 2020-07-24.14:04:53.420>
labels = ['interpreter-core', '3.10']
title = 'Provide a limit arguments for __repr__'
updated_at = <Date 2020-07-26.17:51:07.402>
user = 'https://bugs.python.org/BernatGabor'

bugs.python.org fields:

activity = <Date 2020-07-26.17:51:07.402>
actor = 'rhettinger'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Interpreter Core']
creation = <Date 2020-07-24.14:04:53.420>
creator = 'Bernat Gabor'
dependencies = []
files = []
hgrepos = []
issue_num = 41383
keywords = []
message_count = 4.0
messages = ['374179', '374182', '374191', '374335']
nosy_count = 4.0
nosy_names = ['rhettinger', 'eric.smith', 'remi.lapeyre', 'Bernat Gabor']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = None
url = 'https://bugs.python.org/issue41383'
versions = ['Python 3.10']

@BernatGabor
Copy link
Mannequin Author

BernatGabor mannequin commented Jul 24, 2020

Quoting Elizaveta Shashkova from EuroPython 2020 chat about how can we improve debug experience for users:

I would like to have a lazy repr evaluation for the objects! Sometimes users have many really large objects, and when debugger is trying to show them in Variables View (=show their string representation) it can takes a lot of time. We do some tricks, but they not always work. It would be really-really cool to have parameter in repr, which defines max number of symbols we want to evaluate during repr for this object.

What do people, would this optional str limit be a good thing? Does anyone has a better idea?

@BernatGabor BernatGabor mannequin added 3.10 interpreter-core (Objects, Python, Grammar, and Parser dirs) labels Jul 24, 2020
@remilapeyre
Copy link
Mannequin

remilapeyre mannequin commented Jul 24, 2020

Hi Bernat, have you looked into reprlib.repr()? It's an alternative implementation of repr() made for cases like this.

You may be interested in this PR too: #20925

Alternatively, I think pprint.pformat() may be useful for your purpose too.

@BernatGabor
Copy link
Mannequin Author

BernatGabor mannequin commented Jul 24, 2020

Thanks Rémi, did not know about it. Played around with it, and is not entirely what we'd need here. That class still generates the long string repr, just truncates it afterwards. That is unless teh Repr implements custom formatting for the types, however the Repr would be the IDEs code, and that doesn't understand enough the user code to be able to tell what's a good short representation for it. This was the idea with adding it as a parameter to the repr function, that the user can customize/override the outcome depenending how many characters it has left to use up for repr.

@rhettinger
Copy link
Contributor

rhettinger commented Jul 26, 2020

I suggest taking this to Python ideas. While there is a legitimate concern about large objects in a Variable View, the idea impacts long-standing core APIs. Accordingly, it needs to be thought through, become better specified, and be evaluated against alternatives. If the language impact is pervasive, it would likely need a PEP as well.

Some questions immediately come to mind:

  • Would the existing standard and third party libraries need to recode every __repr__ or __str__ implementation for every container that has ever been written? Would that include C code as well?

  • It there something this limit parameter could do that couldn't already be achieved with __format__()?

  • Should limits be a responsibility of individual classes or it is a debugger responsibility? On the one hand, it is hard to see how a debugger could implement this without blind truncation; on the other hand, I don't think other languages make a similar inversion of responsibility.

  • How would the parameter be accessed via the !r and !s codes in f-strings?

  • How easy or hard would this be to implement for typical classes, lists for example?

  • What is meant by "max number of symbols we want to evaluate"? Would the repr for ['x'*1_000_000] count as one symbol or as one million?

  • For tree-like structures (JSON for example), does a symbol limit make sense? Wouldn't you want a depth limit instead.

  • Would some variant of "..." be added to indicate that limits were applied and to prevent someone for accidentally running eval() on the output?

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
@gvanrossum
Copy link
Member

gvanrossum commented Sep 8, 2022

@gaborbernat:

I don't know if this was ever taken to python-ideas, so I'll continue here.

I don't think there is any chance we can override the __repr__ API to add an optional parameter indicating some limit. For the parameter to be usable it needs to be supported by every __repr__ implementation, since the debugger presumably has to call repr(x, limit=N) which must call x.__repr__(limit=N), and if x.__repr__ doesn't support the limit parameter this will raise TypeError. Using introspection to determine whether a particular class' __repr__ implementation has a limit parameter is cumbersome and unreliable, and there's no way to do this for types implemented in C.

Consequently the only way to do this would be to define a new API (strawman: __repr_with_limit__) that types can optionally implement. This is a really high bar (there are lots of other things we would want if we could add a new repr-like dunder) and would require a really well-written PEP supported by high-ranking core devs.

Alternatively, you could lobby for specific improvements to pprint or reprlib (both of which seem to be halfway there). In particular it would seem that if we make one or the other extensible so that user code can register additional handlers for its own types. This is somewhat similar to defining a new dunder but as a feature request for either pprint or reprlib it is much easier to get this idea approved. I don't know exactly what your use case is, so please look at these two modules carefully and come back with a specific proposal.

@gaborbernat
Copy link
Contributor

gaborbernat commented Sep 8, 2022

I think @Elizaveta239 would be able to describe better what she had in mind 👍

@Elizaveta239
Copy link

Elizaveta239 commented Sep 11, 2022

Hi @gvanrossum! Thank you for your explanation and for the suggestions! Looks like reprlib does exactly what we need inside our debugger! I don't know how I missed it, but we really can use it without adding any new API into Python. Thank you very much!

@gvanrossum gvanrossum closed this as not planned Won't fix, can't repro, duplicate, stale Sep 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.10 interpreter-core (Objects, Python, Grammar, and Parser dirs)
Projects
None yet
Development

No branches or pull requests

4 participants