You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The problem is initially presented in this post on python discussion forum (under topic "python help")
========== BEGIN Mirror of original post ==========
Background:
In my latest commit 3375c80, I have a builtin function expose that creates a DeferExprExposed object which provides access to otherwise hidden attributes on DeferExpr objects (link to code).
Observed Problem:
The attributes are provided through PyTypeObject.tp_getset hooks (link to code). However, I observed some really wired behavior with them:
First attribute access fails, 2nd time OK (and so on):
>>> x => 1 # Creates a DeferExpr object `x`
>>> expose(x).callable # 1st try fails
AttributeError: 'DeferExprExposed' object has no attribute 'callable'
>>> expose(x).callable # 2nd try works
<function <lambda> at 0x10395a560>
Note that expose(x) returns a new DeferExprExposed object each time. It does not reuse the same exposed object. (i.e. two tries happens on two different objects).
Accessing attribute on the same object fails on 1st try, but succeed otherwise:
In commit 3e3b7d4, tp_getset was replaced by tp_setattr and tp_getattr, and the problem no longer exists. This indicates the problem is unlikely to be caused by internal logic of tp_getset hooks.
Possible Solution
In C API PyObject_GetAttr(), add a for-loop to traverse tp_getset and match listed attributes with given name. Traversal of tp_getset should be the last resort (i.e. only executed when tp_getattr and tp_getattro are both NULL).
This logic is not found anywhere in the current code.
P.S. I do not really understand why the second access to the same attribute "magically" works. According to the logic shown in linked code, it should always raise the same attribute error.
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
The text was updated successfully, but these errors were encountered:
Bug report
Bug description:
The problem is initially presented in this post on python discussion forum (under topic "python help")
Background:
In my latest commit 3375c80, I have a builtin function
expose
that creates aDeferExprExposed
object which provides access to otherwise hidden attributes onDeferExpr
objects (link to code).Observed Problem:
The attributes are provided through
PyTypeObject.tp_getset
hooks (link to code). However, I observed some really wired behavior with them:First attribute access fails, 2nd time OK (and so on):
Note that expose(x) returns a new
DeferExprExposed
object each time. It does not reuse the same exposed object. (i.e. two tries happens on two different objects).Accessing attribute on the same object fails on 1st try, but succeed otherwise:
Expected behavior
Attribute access should alway success.
Reproducible Example
Commit
958f53e
@ zhangyx1998/cpython can be used to reproduce this problem.In commit
3e3b7d4
,tp_getset
was replaced bytp_setattr
andtp_getattr
, and the problem no longer exists. This indicates the problem is unlikely to be caused by internal logic oftp_getset
hooks.Possible Solution
In C API
PyObject_GetAttr()
, add a for-loop to traversetp_getset
and match listed attributes with given name. Traversal oftp_getset
should be the last resort (i.e. only executed whentp_getattr
andtp_getattro
are bothNULL
).This logic is not found anywhere in the current code.
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
The text was updated successfully, but these errors were encountered: