classification
Title: super() and property inheritance behavior
Type: behavior Stage: patch review
Components: Interpreter Core Versions: Python 3.11, Python 3.10, Python 3.9
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Aaron Gallagher, Ronny.Pfannschmidt, THRlWiTi, Victor Milovanov, alex, asvetlov, christian.heimes, cvrebert, dabeaz, daniel.urban, eric.araujo, ethan.furman, habnabit, jcasale, josmiley, kenodegard, kynan, ncoghlan, piotr.dobrogost, simonzack, torsten, willrazen, 猫.黒
Priority: normal Keywords: patch

Created on 2012-05-31 03:04 by 猫.黒, last changed 2021-05-28 13:14 by habnabit.

Files
File name Uploaded Description Edit
super_setattr.patch daniel.urban, 2012-06-04 19:26 __setattr__ and __delattr__ for super review
44560_44559.diff torsten, 2012-08-22 16:00 Alternate patch, targeted at Python 2.7
superprop.py simonzack, 2014-12-27 08:26
duper.py willrazen, 2021-05-21 01:47 Python workaround
Pull Requests
URL Status Linked Edit
PR 26194 open Aaron Gallagher, 2021-05-17 18:38
Messages (17)
msg161980 - (view) Author: 猫 黒 (猫.黒) Date: 2012-05-31 03:04
super() objects allow access to inherited properties fget() but not fset() or fdel(), resulting in unexpected behavior.

Today on pydev thread 'Property inheritance in Python' GvR said "I
don't see the need for a Python-Ideas detour. It seems worth fixing"

>>> class BaseProp(object):
...     @property
...     def p(self):
...         return self._p
...     @p.setter
...     def p(self, value):
...         self._p = value
>>> class DerivedProp(BaseProp):
...     @property
...     def p(self):
...         return super(DerivedProp, self).p * 2
...     @p.setter
...     def p(self, value):
...         super(DerivedProp, self).p = value / 2
>>> d = DerivedProp()
>>> d._p = 21
>>> d.p
42
>>> d.p = 50
Traceback (most recent call last):
   ...
AttributeError: 'super' object has no attribute 'p'
msg162050 - (view) Author: josmiley (josmiley) Date: 2012-06-01 05:31
>>> class DerivedProp(BaseProp):
...     @property
...     def p(self):
...         return super(DerivedProp, self).p * 2
...     @p.setter
...     def p(self, value):
...         BaseProp.p.__set__(self,value / 2)
msg162283 - (view) Author: Daniel Urban (daniel.urban) * (Python triager) Date: 2012-06-04 19:26
I'm attaching a patch implementing super.__setattr__ (and __delattr__).

The implementation in the patch only works, if super can find a data descriptor in the MRO, otherwise it throws an AttributeError. As it can be seen in the tests, in some cases this may result in counter-intuitive behaviour. But I wasn't able to find another behaviour, that is consistent with both super.__getattr__ and normal __setattr__ semantics.
msg168895 - (view) Author: Torsten Landschoff (torsten) * Date: 2012-08-22 16:00
I stumbled across this omission as well in 2010 and brought this up on python-dev:

http://mail.python.org/pipermail/python-dev/2010-April/099672.html

There were no replies, but perhaps my post adds a bit of information and also there is another patch linked from there. I attached my patch from 2010 for reference.
msg174404 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2012-11-01 12:04
I'm -0 for proposed changes, these changes reduce code readability from my perspective.
I think better to use existing approach: explicitly specify what do you want to do with overloaded properties.
msg174863 - (view) Author: 猫 黒 (猫.黒) Date: 2012-11-05 05:02
I'm not a python dev, but would you say

super(self.__class__, self.__class__).x.fset(self, value)

is more readable than

super().x = value
msg174911 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2012-11-05 14:37
I would say

@x.deleter
def x(self):
    del super().x

confuses me a bit. 
But I'm only -0, let's see other developers for their opinions.
msg179217 - (view) Author: David Beazley (dabeaz) Date: 2013-01-06 20:20
Just as a note, there is a distinct possibility that a "property" in a superclass could be some other kind of descriptor object that's not a property.  To handle that case, the solution of

super(self.__class__, self.__class__).x.fset(self, value)

would actually have to be rewritten as

super(self.__class__, self.__class__).x.__set__(self, value)

That said, I agree it would be nice to have a simplified means of accomplishing this.
msg232438 - (view) Author: Simon Zack (simonzack) Date: 2014-12-10 18:39
+1 to this feature, this will dramatically simplify property setting code.
msg233127 - (view) Author: Simon Zack (simonzack) Date: 2014-12-27 08:26
For those who want to use this right away, I've added a python implementation of the patch, which passes the unit tests. There's a slight difference in usage, where instead of using super() directly, super_prop(super()) needs to be used, so we can still use super without arguments.
msg275855 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2016-09-11 21:00
I had to add a workaround to ssl.SSLContext and would appreciate a better solution.
msg391838 - (view) Author: Victor Milovanov (Victor Milovanov) Date: 2021-04-25 05:31
There's a patch attached to this bug. Why is its stage "needs patch"?
msg393838 - (view) Author: Aaron Gallagher (habnabit) Date: 2021-05-17 22:26
@daniel.urban I'm attempting to move this patch along, but since the contributing process has changed in the years since your patch, you'll need to sign the CLA. Are you interested in picking this back up at all? I haven't been given any indication of how to proceed if I'm doing this on your behalf, but hopefully the core team will enlighten us.
msg394071 - (view) Author: Will Razen (willrazen) Date: 2021-05-20 21:46
@simonzack Your superprop.py doesn't work for multiple inheritance, because you're using __thisclass__.__mro__ in each step instead of the initial object mro
msg394074 - (view) Author: Daniel Urban (daniel.urban) * (Python triager) Date: 2021-05-20 22:03
@habnabit I believe I've already signed some contributor form some years ago. If there is a new one, I can sign that one too.
msg394094 - (view) Author: Will Razen (willrazen) Date: 2021-05-21 01:47
Fixed superprop.py workaround, now works with multiple inheritance and follows mro adequately. Renamed to duper.py as inspired by Torsten. Uploading here and also to https://gist.github.com/willrazen/bef3fcb26a83dffb6692e5e10d3e67ac
msg394657 - (view) Author: Aaron Gallagher (habnabit) Date: 2021-05-28 13:14
@daniel.urban would you kindly resubmit your patch as a PR to the cpython repo? I've learned out-of-band from someone else that putting patches on bpo is considered obsolete. you can use the PR I've submitted (https://github.com/python/cpython/pull/26194) and reset the author. 

I'd be happy to do it myself (giving you a branch that's all set up, so all you need to do is click the 'new PR' button) if you tell me what to set the author to.
History
Date User Action Args
2021-05-28 13:14:49habnabitsetmessages: + msg394657
2021-05-21 01:47:46willrazensetfiles: + duper.py

messages: + msg394094
2021-05-20 22:03:37daniel.urbansetmessages: + msg394074
2021-05-20 21:46:53willrazensetnosy: + willrazen
messages: + msg394071
2021-05-17 22:26:44habnabitsetnosy: + habnabit
messages: + msg393838
2021-05-17 18:38:58Aaron Gallaghersetnosy: + Aaron Gallagher

pull_requests: + pull_request24811
stage: needs patch -> patch review
2021-05-05 04:57:27wyz23x2setcomponents: + Interpreter Core, - Extension Modules
versions: + Python 3.9, Python 3.10, Python 3.11, - Python 3.7
2021-04-25 05:31:46Victor Milovanovsetnosy: + Victor Milovanov
messages: + msg391838
2017-03-23 04:47:00Mariattasetversions: + Python 3.7, - Python 3.5
2017-03-20 16:57:48kenodegardsetnosy: + kenodegard
2017-02-05 03:59:36THRlWiTisetnosy: + THRlWiTi
2016-09-11 21:00:29christian.heimessetnosy: + christian.heimes
messages: + msg275855
2016-09-11 19:03:50jcasalesetnosy: + jcasale
2016-09-08 20:27:41ethan.furmansetnosy: + ethan.furman
2015-02-04 14:32:49piotr.dobrogostsetnosy: + piotr.dobrogost
2014-12-27 08:26:39simonzacksetfiles: + superprop.py

messages: + msg233127
2014-12-10 18:39:27simonzacksetnosy: + simonzack
messages: + msg232438
2014-01-31 22:28:33yselivanovsetversions: + Python 3.5, - Python 3.2, Python 3.3
2013-03-21 20:23:49kynansetnosy: + kynan
2013-02-24 01:08:24r.david.murraylinkissue783528 superseder
2013-01-06 20:20:16dabeazsetnosy: + dabeaz
messages: + msg179217
2012-11-05 14:37:02asvetlovsetmessages: + msg174911
2012-11-05 05:02:48猫.黒setmessages: + msg174863
2012-11-01 12:04:42asvetlovsetnosy: + asvetlov
messages: + msg174404
2012-10-30 20:21:14Ronny.Pfannschmidtsetnosy: + Ronny.Pfannschmidt
2012-10-30 13:42:37r.david.murraylinkissue16363 superseder
2012-08-24 08:30:38cvrebertsetnosy: + cvrebert
2012-08-22 16:00:02torstensetfiles: + 44560_44559.diff
nosy: + torsten
messages: + msg168895

2012-06-04 19:27:15daniel.urbansetcomponents: + Extension Modules, - Library (Lib)
2012-06-04 19:26:52daniel.urbansetfiles: + super_setattr.patch

nosy: + daniel.urban
messages: + msg162283

keywords: + patch
2012-06-02 05:04:28ncoghlansetnosy: + ncoghlan
2012-06-01 05:31:41josmileysetnosy: + josmiley
messages: + msg162050
2012-06-01 02:53:22eric.araujosetnosy: + eric.araujo
stage: needs patch

versions: + Python 3.3
2012-05-31 03:07:08alexsetnosy: + alex
2012-05-31 03:04:01猫.黒create