classification
Title: __setattr__ does not always overload operators
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.7, Python 3.6, Python 3.5, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: serhiy.storchaka Nosy List: Dominik Schmid, berker.peksag, eryksun, louielu, serhiy.storchaka
Priority: normal Keywords: patch

Created on 2015-12-04 08:52 by Dominik Schmid, last changed 2017-05-20 07:25 by serhiy.storchaka. This issue is now closed.

Files
File name Uploaded Description Edit
bug.py Dominik Schmid, 2015-12-04 08:52 source code reproducing the bug
issue25794_2.patch eryksun, 2015-12-04 12:15 review
Pull Requests
URL Status Linked Edit
PR 1652 merged serhiy.storchaka, 2017-05-18 17:49
PR 1673 merged serhiy.storchaka, 2017-05-20 05:55
PR 1674 merged serhiy.storchaka, 2017-05-20 05:59
PR 1675 merged serhiy.storchaka, 2017-05-20 06:41
Messages (8)
msg255853 - (view) Author: Dominik Schmid (Dominik Schmid) Date: 2015-12-04 08:52
While implementing my own Integer class that keeps track of when operations are applied I noticed that setattr had a strange behaviour when I tried to wrap operator functions.

When the attribute string had a different id to its literal it failed to overload the operator.
Are we doing a 'is' rather than a '==' somewhere in setattr?


expected result: 
139723705431168    a.__add__(b)= (5)    a+b= (5)
139723705431168    a.__add__(b)= (5)    a+b= (5)
139723704361584    a.__add__(b)= (5)    a+b= (5)


actual result:
139723705431168    a.__add__(b)= (5)    a+b= (5)
139723705431168    a.__add__(b)= (5)    a+b= (5)
139723704361584    a.__add__(b)= (5)    a+b=
Traceback (most recent call last):
  File "/home/dom/Documents/leastOps/bug.py", line 41, in <module>
    testSetattr(funcName3)
  File "/home/dom/Documents/leastOps/bug.py", line 28, in testSetattr
    print '   a+b=', a+b
TypeError: unsupported operand type(s) for +: 'Integer' and 'Integer'



version:
2.7.10 (default, Oct 14 2015, 16:09:02) 
[GCC 5.2.1 20151010]
ubuntu 14.10
msg255859 - (view) Author: Eryk Sun (eryksun) * Date: 2015-12-04 11:51
Normally Python code calls built-in setattr, which calls the C API PyObject_SetAttr. This API interns the attribute name before calling the type's tp_setattro or tp_setattr function. Interning the string is a critical step, since the implementation for updating slots assumes the name is interned. 

The __setattr__ slot wrapper calls wrap_setattr in Objects/typeobject.c. In line with how PyObject_SetAttr works, the attached patch interns the name in wrap_setattr before calling the wrapped setattrofunc. For good measure it also applies the same change to wrap_delattr, though that's not strictly necessary.
msg255862 - (view) Author: Eryk Sun (eryksun) * Date: 2015-12-04 12:15
This updated patch calls PyUnicode_Check to ensure the name is a string before calling PyUnicode_InternInPlace.
msg292176 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-04-23 18:13
Eryk, could you create a pull request? Please take into account my and Berker's comments on Rietveld.
msg294006 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-05-20 05:48
New changeset d896985bb2de49046f9b6879e906d1e4db255e23 by Serhiy Storchaka in branch 'master':
bpo-25794: Fix `type.__setattr__()` for non-interned attribute names. (#1652)
https://github.com/python/cpython/commit/d896985bb2de49046f9b6879e906d1e4db255e23
msg294015 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-05-20 07:04
New changeset e9f9b042781e3cb480315860bcdf7b7d22cba0f8 by Serhiy Storchaka in branch '2.7':
[2.7] bpo-25794: Fix `type.__setattr__()` for non-interned or unicode attribute names. (GH-1652) (#1675)
https://github.com/python/cpython/commit/e9f9b042781e3cb480315860bcdf7b7d22cba0f8
msg294017 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-05-20 07:23
New changeset 193f7e094f070cecbc6faea6dffafb80ea9e7536 by Serhiy Storchaka in branch '3.6':
[3.6] bpo-25794: Fix `type.__setattr__()` for non-interned attribute names. (GH-1652) (#1673)
https://github.com/python/cpython/commit/193f7e094f070cecbc6faea6dffafb80ea9e7536
msg294018 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-05-20 07:24
New changeset 4a86fe9d3f5e7af6f019ae22536eec228f04e22e by Serhiy Storchaka in branch '3.5':
[3.5] bpo-25794: Fix `type.__setattr__()` for non-interned attribute names. (GH-1652) (#1674)
https://github.com/python/cpython/commit/4a86fe9d3f5e7af6f019ae22536eec228f04e22e
History
Date User Action Args
2017-05-20 07:25:37serhiy.storchakasetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2017-05-20 07:24:00serhiy.storchakasetmessages: + msg294018
2017-05-20 07:23:33serhiy.storchakasetmessages: + msg294017
2017-05-20 07:04:55serhiy.storchakasetmessages: + msg294015
2017-05-20 06:41:46serhiy.storchakasetpull_requests: + pull_request1770
2017-05-20 05:59:27serhiy.storchakasetpull_requests: + pull_request1769
2017-05-20 05:55:03serhiy.storchakasetpull_requests: + pull_request1768
2017-05-20 05:48:08serhiy.storchakasetmessages: + msg294006
2017-05-18 17:49:49serhiy.storchakasetpull_requests: + pull_request1747
2017-04-23 18:13:32serhiy.storchakasetmessages: + msg292176
2017-04-17 05:02:51rhettingersetassignee: serhiy.storchaka
2017-04-14 17:03:48louielusetnosy: + louielu
2017-04-14 15:36:07serhiy.storchakasetnosy: + serhiy.storchaka

versions: + Python 3.7
2015-12-16 00:05:48berker.peksagsetnosy: + berker.peksag
stage: patch review

versions: - Python 3.4
2015-12-04 12:15:30eryksunsetfiles: + issue25794_2.patch

messages: + msg255862
2015-12-04 12:12:58eryksunsetfiles: - issue25794_1.patch
2015-12-04 11:51:56eryksunsetfiles: + issue25794_1.patch
versions: + Python 3.4, Python 3.5, Python 3.6
nosy: + eryksun

messages: + msg255859

keywords: + patch
2015-12-04 08:52:36Dominik Schmidcreate