classification
Title: Context managers written as C types no longer work in Python 2.7
Type: Stage: resolved
Components: Documentation Versions: Python 2.7
process
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: docs@python Nosy List: benjamin.peterson, christian.heimes, docs@python, lemburg, zach.ware
Priority: normal Keywords:

Created on 2013-02-21 16:31 by lemburg, last changed 2020-04-26 16:57 by zach.ware. This issue is now closed.

Messages (6)
msg182598 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2013-02-21 16:31
We have implemented the context manager API for connections and cursors in our mxODBC module and this works fine in Python 2.6.

In Python 2.7 we get the following error:

Traceback (most recent call last):
  File "context-manager.py", line 6, in <module>
    with db.cursor() as cursor:
AttributeError: __exit__

Here's the code snippet:

import mx.ODBC.unixODBC as ODBC
connectionString = '...'
db = ODBC.DriverConnect(connectionString)
with db.cursor() as cursor:
    print cursor

The mxODBC cursor is not an instance, it's implemented as Python type in C. It implements the tp_getattr slot, but not the tp_desc_get slot.

Looking at the apparently new API _PyObject_LookupSpecial(), this does not appear to support the tp_getattr slot and goes straight for the tp_desc_get slot.
msg182599 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2013-02-21 16:36
After some experiments, it turned out that by simply filling in the tp_methods slot, the problem went away.

Still, the change to use _PyObject_LookupSpecial() appears to have missed the (older) use case where you don't define tp_members, but instead implement method lookup as part of the tp_getattr slot.

Not sure whether this is worth fixing. I just filed this report so that others running into the same problem can find it.
msg182600 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2013-02-21 16:40
The change should also be documented here, http://docs.python.org/2.7/whatsnew/2.7.html#porting-to-python-2-7
msg182602 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2013-02-21 17:49
On 21.02.2013 17:36, Marc-Andre Lemburg wrote:
> After some experiments, it turned out that by simply filling in the tp_methods slot, the problem went away.
> 
> Still, the change to use _PyObject_LookupSpecial() appears to have missed the (older) use case where you don't define tp_members, but instead implement method lookup as part of the tp_getattr slot.

Sorry: *tp_methods*, not tp_members.
msg182608 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2013-02-21 20:44
This is a property of all special methods not just __enter__ and __exit__.
msg367316 - (view) Author: Zachary Ware (zach.ware) * (Python committer) Date: 2020-04-26 16:57
As 2.7 has reached EOL, I'm going to go ahead and close the issue.
History
Date User Action Args
2020-04-26 16:57:43zach.waresetstatus: open -> closed

nosy: + zach.ware
messages: + msg367316

resolution: out of date
stage: needs patch -> resolved
2013-02-21 20:44:06benjamin.petersonsetmessages: + msg182608
2013-02-21 20:11:53pitrousetnosy: + benjamin.peterson
2013-02-21 17:49:04lemburgsetmessages: + msg182602
2013-02-21 17:48:22lemburgsetmessages: - msg182601
2013-02-21 17:37:19lemburgsetmessages: + msg182601
2013-02-21 16:40:30christian.heimessetnosy: + docs@python, christian.heimes
messages: + msg182600

assignee: docs@python
components: + Documentation
stage: needs patch
2013-02-21 16:36:38lemburgsetmessages: + msg182599
2013-02-21 16:31:51lemburgcreate