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

Created on 2011-05-06 20:07 by dholth, last changed 2019-10-19 21:38 by serhiy.storchaka.

Messages (6)
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.
History
Date User Action Args
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 ->
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