Message282468
I found a way to fix it, but as I'm just discovering cpython internals, I'm not sure it's the right way, review are very welcome.
I fixed it this way because:
The bytecode generated for "proxy.x = 0" (a STORE_ATTR) will call a
PyObject_SetAttr with FooProxy which will soon execute the __setattr__ of Meta, itself calling a PyObject_SetAttr with Foo.
The actual attribute setting is done from the PyObject_SetAttr with Foo (calling in turn type_setattro, and so on), but it's already too late to invalidate the FooProxy type: we no longer have a reference on it and can't guess that FooProxy delegated __setattr__ to Foo.
So the only place when we can invalidate correctly is in the first call of PyObject_SetAttr when we know on which type the attribute will be set, and it make sense: It does not matter what a __setattr__ does and how it does it: invalidation should happen for this attribute on the current type, so invalidating here seems logic.
I did not yet took the time to measure performance loss induced with this patch.
With the patch:
./python -i weird.py
>>> proxy.x
0
>>> proxy.x
0 |
|
| Date |
User |
Action |
Args |
| 2016-12-05 21:59:04 | mdk | set | recipients:
+ mdk, vstinner, serhiy.storchaka, abarry, sjpalt |
| 2016-12-05 21:59:04 | mdk | set | messageid: <[email protected]> |
| 2016-12-05 21:59:04 | mdk | link | issue28866 messages |
| 2016-12-05 21:59:04 | mdk | create | |
|