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
Priority: normal Keywords:

Created on 2011-05-06 20:07 by dholth, last changed 2011-05-23 14:09 by eric.araujo.

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