classification
Title: Confusing message with AttributeError when attribute name matches suggestion
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.11, Python 3.10
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: eric.smith, miss-islington, pablogsal
Priority: normal Keywords: patch

Created on 2021-07-16 19:14 by eric.smith, last changed 2021-07-17 00:02 by pablogsal. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 27197 merged pablogsal, 2021-07-16 20:26
PR 27198 merged miss-islington, 2021-07-16 20:58
PR 27199 merged pablogsal, 2021-07-16 21:35
PR 27201 merged miss-islington, 2021-07-16 23:34
Messages (12)
msg397652 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2021-07-16 19:14
This is related to issue 44649. This is the simplest non-dataclasses case I could come up with.

Given:

class Example:
    __slots__ = ('a', 'b')
    def __init__(self, a):
        self.a = a

obj = Example(42)
print(obj.b)

I get this in 3.10 and main:

Traceback (most recent call last):
  File "C:\home\eric\local\python\cpython\testdc.py", line 7, in <module>
    print(obj.b)
          ^^^^^
AttributeError: b. Did you mean: 'b'?


The error message is confusing.

3.8 gives:

Traceback (most recent call last):
  File "testdc.py", line 7, in <module>
    print(obj.b)
AttributeError: b

I don't have 3.9 around to test with.

Maybe don't print the "Did you mean" part if the suggestion is the same as the requested attribute?

The fact that the instance variable isn't initialized is the actual error in issue 44649, and I'll fix it there.
msg397654 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2021-07-16 19:21
Also, the dot after the first 'b' was confusing to me: I thought it had something to do with an attribute of b. And the quotes around the second 'b' were also confusing, but that's mostly because the original example initialized a class variable named 'b' with the str value 'b'.

Maybe a better error would use a colon:

AttributeError: foo: Did you mean: 'foo1'?

Looking at 3.10s behavior, I can't decide what logic it's using to suggest something:

>>> 'foo'.formatx
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'formatx'. Did you mean: 'format'?
>>> class C: pass
...
>>> C().a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'C' object has no attribute 'a'
msg397656 - (view) Author: Pablo Galindo Salgado (pablogsal) * (Python committer) Date: 2021-07-16 19:29
For attribute errors we just call dir() on the object and we do a suggestion based on the names so if a name appears in the dir() then we will consider it for the suggestion.
msg397657 - (view) Author: Pablo Galindo Salgado (pablogsal) * (Python committer) Date: 2021-07-16 19:36
> Maybe don't print the "Did you mean" part if the suggestion is the same as the requested attribute?

I think this is a good idea and will take care of many other similar cases. Thanks for the suggestion, Eric! I will prepare a PR
msg397658 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2021-07-16 19:37
It's obviously not super important, but it would be nicer if the version with the suggestion were more like the version without the suggestion. Specifically, mentioning the object type:

>>> class E:
...     __slots__=('a')
...
>>> E().a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: a. Did you mean: 'a'?
>>> E().b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'E' object has no attribute 'b'
>>>
msg397659 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2021-07-16 19:38
Thanks, Pablo!
msg397663 - (view) Author: Pablo Galindo Salgado (pablogsal) * (Python committer) Date: 2021-07-16 20:32
> it would be nicer if the version with the suggestion were more like the version without the suggestion

Agreed, but that is actually not related with the suggestions. We only append a string at the end of whatever exception it was there. This difference is based on the attribute error for a slot not initialized vs an attribute error for something that is not there. For example, in 3.9:

---

class E:
    __slots__=('blech')

E().blech

Traceback (most recent call last):
  File "/home/pablogsal/github/cpython/lel.py", line 6, in <module>
    E().blech
AttributeError: blech


while

class E:
    __slots__=('blech')

E().bluch

Traceback (most recent call last):
  File "/home/pablogsal/github/cpython/lel.py", line 4, in <module>
    E().bluch
AttributeError: 'E' object has no attribute 'bluch'
msg397668 - (view) Author: Pablo Galindo Salgado (pablogsal) * (Python committer) Date: 2021-07-16 20:58
New changeset 6714dec5e104bdee4a0ed4d9966de27d1bfa1e3d by Pablo Galindo Salgado in branch 'main':
bpo-44655: Don't include suggestions for attributes that are the same as the missing one (GH-27197)
https://github.com/python/cpython/commit/6714dec5e104bdee4a0ed4d9966de27d1bfa1e3d
msg397670 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2021-07-16 21:01
Got it. Thanks for jumping on this quickly.
msg397671 - (view) Author: Pablo Galindo Salgado (pablogsal) * (Python committer) Date: 2021-07-16 21:16
New changeset a0b1d401db52391d13479c53ee3880e6640df98c by Miss Islington (bot) in branch '3.10':
bpo-44655: Don't include suggestions for attributes that are the same as the missing one (GH-27197) (GH-27198)
https://github.com/python/cpython/commit/a0b1d401db52391d13479c53ee3880e6640df98c
msg397675 - (view) Author: Pablo Galindo Salgado (pablogsal) * (Python committer) Date: 2021-07-16 23:34
New changeset f783428a2313a729ca8b539c5a86ff114b9ff375 by Pablo Galindo Salgado in branch 'main':
bpo-44655: Include the name of the type in unset __slots__ attribute errors (GH-27199)
https://github.com/python/cpython/commit/f783428a2313a729ca8b539c5a86ff114b9ff375
msg397676 - (view) Author: Pablo Galindo Salgado (pablogsal) * (Python committer) Date: 2021-07-17 00:02
New changeset efda9054b9fc91e69ecb34eae84fdd2ca8e6feef by Miss Islington (bot) in branch '3.10':
bpo-44655: Include the name of the type in unset __slots__ attribute errors (GH-27199) (GH-27201)
https://github.com/python/cpython/commit/efda9054b9fc91e69ecb34eae84fdd2ca8e6feef
History
Date User Action Args
2021-07-17 00:02:22pablogsalsetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2021-07-17 00:02:18pablogsalsetmessages: + msg397676
2021-07-16 23:34:59miss-islingtonsetpull_requests: + pull_request25735
2021-07-16 23:34:54pablogsalsetmessages: + msg397675
2021-07-16 21:35:31pablogsalsetpull_requests: + pull_request25734
2021-07-16 21:17:53eric.smithsettitle: Confusing message with AttributreError when attribute name matches suggestion -> Confusing message with AttributeError when attribute name matches suggestion
2021-07-16 21:16:20pablogsalsetmessages: + msg397671
2021-07-16 21:01:29eric.smithsettitle: Confusing message with AttributreError suggestions -> Confusing message with AttributreError when attribute name matches suggestion
2021-07-16 21:01:01eric.smithsetmessages: + msg397670
title: Confusing error with __slots__ -> Confusing message with AttributreError suggestions
2021-07-16 20:58:48miss-islingtonsetnosy: + miss-islington
pull_requests: + pull_request25733
2021-07-16 20:58:29pablogsalsetmessages: + msg397668
2021-07-16 20:32:10pablogsalsetmessages: + msg397663
2021-07-16 20:26:11pablogsalsetkeywords: + patch
stage: patch review
pull_requests: + pull_request25732
2021-07-16 19:38:32eric.smithsetmessages: + msg397659
2021-07-16 19:37:59eric.smithsetmessages: + msg397658
2021-07-16 19:36:38pablogsalsetmessages: + msg397657
2021-07-16 19:29:11pablogsalsetmessages: + msg397656
2021-07-16 19:21:56eric.smithsetmessages: + msg397654
2021-07-16 19:14:32eric.smithcreate