AttributeError: __exit__

I just learned about Python internals from The ZODB transaction module. In Python < 2.7, the module works as a transaction manager. More or less: manager = Foo() __exit__ = manager.__exit__ __enter__ = manager.__enter__ After Python 2.7, it doesn't work. import transaction with transaction: pass
AttributeError: __exit__
It should be obvious to even the most casual observer that the exception is because, after Python 2.7, the with: statement has its own opcode that bypasses transaction.__getattribute__('__exit__') -> transaction.__dict__['__exit__']. Instead, CPython calls special_lookup(), looks for __exit__ on the module type, not the instance, doesn't find it, and raises the AttributeError. Instead, import sys sys.__exit__
AttributeError: 'module' object has no attribute '__exit__'
The interpreter should at least explain the AttributeError in the same way as it does when the user triggers it directly.

Please file a bug. On May 6, 2011 5:17 PM, "Daniel Holth" <dholth@gmail.com> wrote:
I just learned about Python internals from The ZODB transaction module. In
Python < 2.7, the module works as a transaction manager. More or less:
is because, after Python 2.7, the with: statement has its own opcode that bypasses transaction.__getattribute__('__exit__') -> transaction.__dict__['__exit__']. Instead, CPython calls special_lookup(), looks for __exit__ on the module type, not the instance, doesn't find it, and raises the AttributeError.
as it does when the user triggers it directly.

OK. I will reopen the related bug that was immediately closed with a suggestion to check with the python-ideas mailing list.

Please file a bug. On May 6, 2011 5:17 PM, "Daniel Holth" <dholth@gmail.com> wrote:
I just learned about Python internals from The ZODB transaction module. In
Python < 2.7, the module works as a transaction manager. More or less:
is because, after Python 2.7, the with: statement has its own opcode that bypasses transaction.__getattribute__('__exit__') -> transaction.__dict__['__exit__']. Instead, CPython calls special_lookup(), looks for __exit__ on the module type, not the instance, doesn't find it, and raises the AttributeError.
as it does when the user triggers it directly.

OK. I will reopen the related bug that was immediately closed with a suggestion to check with the python-ideas mailing list.
participants (2)
-
Daniel Holth
-
Guido van Rossum