classification
Title: AttributeError should report the same details when raised by lookup_special() as when raised in the REPL
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.11
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: serhiy.storchaka Nosy List: benjamin.peterson, daniel.urban, dholth, eric.araujo, gvanrossum, iritkatriel, serhiy.storchaka
Priority: normal Keywords: patch

Created on 2011-05-06 20:07 by dholth, last changed 2021-06-29 08:29 by serhiy.storchaka. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 26809 merged serhiy.storchaka, 2021-06-20 08:21
Messages (9)
msg135365 - (view) Author: Daniel Holth (dholth) * Date: 2011-05-06 20:07
"How much do we care about special method lookup?" Python recently bypasses __getattr__ entirely when looking up context managers. http://mail.python.org/pipermail/python-dev/2009-May/089535.html

Could this be the reason that ZODB's transaction module, which attempts to be a context manager by declaring

manager = ThreadTransactionManager()
__enter__ = manager.get
__exit__ = manager.__exit__

Does not work in Python 2.7.1 on Ubuntu 11.04 or RHEL5? Frustratingly, the exception is no more specific than an AttributeError, even though hasattr(transaction, '__exit__')?

I would prefer to never get AttributeError: transaction.__exit__ when hasattr(transaction, '__exit__') as I find that to be very confusing. Maybe the interpreter could raise SpecialAttributeError('transaction.__exit__ is not sufficiently special') instead.

http://svn.zope.org/repos/main/transaction/trunk/transaction/__init__.py
msg135388 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2011-05-06 23:50
Yes, that's why. I suggest you appeal to python-ideas about the new exception.
msg135484 - (view) Author: Daniel Holth (dholth) * Date: 2011-05-07 17:19
Python should explain AttributeError in the same way when it's raised by the interpreter. The with: statement below should raise the second AttributeError, not the first.

import transaction
with transaction: pass
>>> AttributeError: __exit__

import sys
sys.__exit__
>>> AttributeError: 'module' object has no attribute '__exit__'
msg135491 - (view) Author: Daniel Holth (dholth) * Date: 2011-05-07 17:42
Thank you Benjamin for following up on this issue
msg136640 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2011-05-23 14:09
> hasattr(transaction, '__exit__')

http://docs.python.org/dev/reference/datamodel#special-method-names explains that magic methods are looked up on the class, not on the instances.  There’s a lot of code out there that erroneously checks for __len__ or __call__ on instances, and this is the second time to my knowledge that a project abused a module-level __enter__ function.
msg354977 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2019-10-19 21:38
Would not be better to change an AttributeError to TypeError? Seems this is the only place in the core when missing special method causes an AttributeError and not TypeError.
msg396148 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2021-06-19 18:58
I've reproduced this on 3.11 (though the AttributeError is now on __enter__ and not __exit__ as was the case in msg135484):

>>> import transaction
>>> with transaction: pass
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: __enter__

>>> import sys
>>> sys.__exit__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'sys' has no attribute '__exit__'
>>>
msg396165 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2021-06-20 08:23
PR 26809 makes "with" and "async with" raising TypeError instead of AttributeError for wrong types.
msg396707 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2021-06-29 08:27
New changeset 20a88004bae8ead66a205a125e1fe979376fc3ea by Serhiy Storchaka in branch 'main':
bpo-12022: Change error type for bad objects in "with" and "async with" (GH-26809)
https://github.com/python/cpython/commit/20a88004bae8ead66a205a125e1fe979376fc3ea
History
Date User Action Args
2021-06-29 08:29:06serhiy.storchakasetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2021-06-29 08:27:28serhiy.storchakasetmessages: + msg396707
2021-06-21 07:53:47serhiy.storchakalinkissue44471 dependencies
2021-06-20 08:23:21serhiy.storchakasetmessages: + msg396165
2021-06-20 08:21:44serhiy.storchakasetnosy: + gvanrossum
2021-06-20 08:21:10serhiy.storchakasetkeywords: + patch
stage: patch review
pull_requests: + pull_request25391
2021-06-19 20:27:09serhiy.storchakasetassignee: serhiy.storchaka
2021-06-19 18:58:23iritkatrielsetnosy: + iritkatriel

messages: + msg396148
versions: + Python 3.11, - Python 2.7
2019-10-19 21:38:43serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg354977
2011-05-23 14:09:44eric.araujosetnosy: + eric.araujo
messages: + msg136640
2011-05-08 06:33:55daniel.urbansetnosy: + daniel.urban
2011-05-07 17:42:19dholthsetmessages: + msg135491
2011-05-07 17:19:47dholthsetmessages: + msg135484
title: improve special method lookup error message -> AttributeError should report the same details when raised by lookup_special() as when raised in the REPL
2011-05-07 16:13:43benjamin.petersonsetstatus: closed -> open
resolution: not a bug -> (no value)
title: 'transaction' module-as-context-manager thwarted by Python 2.7.1 -> improve special method lookup error message
2011-05-06 23:50:49benjamin.petersonsetstatus: open -> closed

nosy: + benjamin.peterson
messages: + msg135388

resolution: not a bug
2011-05-06 20:07:21dholthcreate