Repository navigation
Offer suggestions on AttributeError and NameError #82711
Copy link
Copy link
Closed
Labels
3.9 (EOL)end of lifeend of lifeinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-featureA feature request or enhancementA feature request or enhancement
Description
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 = <Date 2021-04-14.23:32:49.056>
created_at = <Date 2019-10-19.18:57:31.623>
labels = ['interpreter-core', 'type-feature', '3.9']
title = 'Offer suggestions on AttributeError and NameError'
updated_at = <Date 2021-05-03.15:47:35.739>
user = 'https://github.com/pablogsal'bugs.python.org fields:
activity = <Date 2021-05-03.15:47:35.739>
actor = 'pablogsal'
assignee = 'none'
closed = True
closed_date = <Date 2021-04-14.23:32:49.056>
closer = 'pablogsal'
components = ['Interpreter Core']
creation = <Date 2019-10-19.18:57:31.623>
creator = 'pablogsal'
dependencies = []
files = []
hgrepos = []
issue_num = 38530
keywords = ['patch']
message_count = 40.0
messages = ['354954', '354955', '354956', '354957', '354958', '354959', '354960', '354964', '354965', '354967', '354969', '354970', '354971', '354972', '354973', '354975', '354979', '354981', '355499', '355503', '355527', '355530', '355531', '355533', '359977', '391026', '391080', '391090', '391108', '391123', '391219', '391224', '391312', '391316', '391834', '392007', '392513', '392543', '392581', '392817']
nosy_count = 9.0
nosy_names = ['vstinner', 'aroberge', 'serhiy.storchaka', 'yselivanov', 'james', 'pablogsal', 'xtreak', 'BTaskaya', 'Dennis Sweeney']
pr_nums = ['16850', '16856', '25397', '25408', '25412', '25443', '25444', '25460', '25462', '25473', '25584', '25776']
priority = 'normal'
resolution = 'fixed'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'enhancement'
url = 'https://bugs.python.org/issue38530'
versions = ['Python 3.9']Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
3.9 (EOL)end of lifeend of lifeinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-featureA feature request or enhancementA feature request or enhancement
Activity
pablogsal commentedon Oct 19, 2019
To improve the debugging experience in both interactive and non-interactive code, I propose to offer suggestions when attribute access fails. For example:
Did you mean: foo?
This also applies to imports from modules and other situations:
>>> import collections >>> collections.NamedTuple Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: module 'collections' has no attribute 'NamedTuple'Did you mean: namedtuple?
pablogsal commentedon Oct 19, 2019
PR 16850 shows an initial prototype for the idea
isidentical commentedon Oct 19, 2019
It already exists as a 3rd party module and it would be really cool to have this in core level.
https://github.com/dutc/didyoumean (by James Powell)
pablogsal commentedon Oct 19, 2019
I am not super convinced that this is a great idea because it has some performance cost (although somewhat controlled) but I want to open a discussion.
tirkarthi commentedon Oct 19, 2019
Ruby has it integrated into the core : https://bugs.ruby-lang.org/issues/11252 . It was initially a gem that got merged into core.
pablogsal commentedon Oct 19, 2019
Idea: we could only do this in interactive mode if we consider that is expensive enough.
pablogsal commentedon Oct 19, 2019
I am running pyperformance to check the performance cost of this.
pablogsal commentedon Oct 19, 2019
Slower (27):
The current approach is too expensive, so I'm closing PR 16850.
serhiy-storchaka commentedon Oct 19, 2019
AFAIK there is existing issue for this idea.
I have doubts about performance. I added _PyObject_LookupAttr in particularly to avoid an overhead of raising and silencing an AttributeError. I believe most performance sensitive code in the core now uses it and will not be affected, but there is other code which silences it (_PyObject_LookupAttr itself silences an AttributeError raised in called functions), third-party code which uses PyObject_HasAttr or PyObject_GetAttr can be affected.
It might be simpler to implement it in sys.excepthook or sys.displayhook, but at that point we do not have attribute name and a reference to the object. There is an issues and a PEP about adding references to AttributeError. It could help to implement this feature.
serhiy-storchaka commentedon Oct 19, 2019
I am surprised that it was SO expensive.
Pathlib would largely benefit from cached_property if it be compatible with slots.
pablogsal commentedon Oct 19, 2019
Serhiy, do you think we could attach the object and the name to some private fields of the AttributeError and check that in sys.excepthook if they are present?
pablogsal commentedon Oct 19, 2019
I will also repeat the pyperformance results locally just in case something was off on the speed.python.org server.
17 remaining items
pablogsal commentedon Apr 14, 2021
New changeset 3fc65b9 by Pablo Galindo in branch 'master':
bpo-38530: Optimize the calculation of string sizes when offering suggestions (GH-25412)
3fc65b9
vstinner commentedon Apr 15, 2021
I like the https://docs.python.org/dev/whatsnew/3.10.html#better-error-messages section: well done, thanks ;-)
pablogsal commentedon Apr 16, 2021
New changeset 3b82cae by Pablo Galindo in branch 'master':
bpo-38530: Properly extend UnboundLocalError from NameError (GH-25444)
3b82cae
pablogsal commentedon Apr 16, 2021
New changeset 0ad81d4 by Pablo Galindo in branch 'master':
bpo-38530: Match exactly AttributeError and NameError when offering suggestions (GH-25443)
0ad81d4
pablogsal commentedon Apr 17, 2021
New changeset 3ab4bea by Pablo Galindo in branch 'master':
bpo-38530: Include builtins in NameError suggestions (GH-25460)
3ab4bea
pablogsal commentedon Apr 17, 2021
New changeset 0b1c169 by Pablo Galindo in branch 'master':
bpo-38530: Cover more error paths in error suggestion functions (GH-25462)
0b1c169
sweeneyde commentedon Apr 25, 2021
I opened PR 25584 to fix this current behavior:
pablogsal commentedon Apr 27, 2021
New changeset 284c52d by Dennis Sweeney in branch 'master':
bpo-38530: Require 50% similarity in NameError and AttributeError suggestions (GH-25584)
284c52d
sweeneyde commentedon Apr 30, 2021
Some research of other projects:
LLVM [1][2]
-----------
GCC [3]
-------
Rust [4]
--------
Ruby [5]
--------
I think there are some good ideas here.
[1] https://github.com/llvm/llvm-project/blob/d480f968ad8b56d3ee4a6b6df5532d485b0ad01e/llvm/include/llvm/ADT/edit_distance.h#L42
[2] https://github.com/llvm/llvm-project/blob/e2b3b89bf1ce74bf889897e0353a3e3fa93e4452/clang/lib/Sema/SemaLookup.cpp#L4263
[3] https://github.com/gcc-mirror/gcc/blob/16e2427f50c208dfe07d07f18009969502c25dc8/gcc/spellcheck.c
[4] https://github.com/rust-lang/rust/blob/673d0db5e393e9c64897005b470bfeb6d5aec61b/compiler/rustc_span/src/lev_distance.rs#L44
[5] https://github.com/ruby/ruby/blob/48b94b791997881929c739c64f95ac30f3fd0bb9/lib/did_you_mean/spell_checker.rb
pablogsal commentedon Apr 30, 2021
Hi Dennis, this is a fantastic investigation!
I think I really like GCC approach here. We may want to invest into porting some of their ideas into our solution.
sweeneyde commentedon May 1, 2021
PR 25776 is a work in progress for what it might look like to do a few things:
"Multiset Jaccard similarity" >= 2/3
matching letters / total letters >= 2/3
(name_size - distance + item_size - distance) / (name_size + item_size) >= 2/3
1 - (2*distance) / (name_size + item_size) >= 2/3
1/3 >= (2*distance) / (name_size + item_size)
(name_size + item_size) / 6 >= distance
With rounding:
(name_size + item_size + 3) // 6 >= distance
Re: Damerau-Levenshtein (transpositions as single edits), if that were to get implemented, I don't see a way to do that without using a buffer of at least 3x the size, storing the most recent 3 rows of the matrix.
pablogsal commentedon May 3, 2021
New changeset 80a2a4e by Dennis Sweeney in branch 'master':
bpo-38530: Refactor and improve AttributeError suggestions (GH-25776)
80a2a4e