homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: No way to create an abstract classmethod
Type: enhancement Stage: patch review
Components: Library (Lib) Versions: Python 3.2
process
Status: closed Resolution: accepted
Dependencies: Superseder:
Assigned To: Nosy List: benjamin.peterson, daniel.urban, della, eric.araujo, gvanrossum, pitrou, terry.reedy
Priority: normal Keywords: patch

Created on 2009年04月28日 14:24 by della, last changed 2022年04月11日 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
issue5867.diff daniel.urban, 2010年08月13日 19:35 Patch (py3k branch)
issue5867a.diff daniel.urban, 2010年08月13日 20:26 New patch (+ tests) (py3k branch)
abstractclassstaticmethod.diff daniel.urban, 2010年08月14日 07:27 Patch adding the abc.abstractclassmethod and abc.abstractstatismethod decorators
abstractclassstaticmethod+doc.diff daniel.urban, 2010年08月16日 07:14 New patch (+doc)
Messages (13)
msg86744 - (view) Author: Matteo Dell'Amico (della) Date: 2009年04月28日 14:24
Is there a way to define an abstract classmethod? The two obvious ways
don't seem to work properly.
Python 3.0.1+ (r301:69556, Apr 15 2009, 17:25:52) 
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import abc
>>> class C(metaclass=abc.ABCMeta):
... @abc.abstractmethod
... @classmethod
... def f(cls): print(42)
... 
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "<stdin>", line 3, in C
 File "/usr/lib/python3.0/abc.py", line 24, in abstractmethod
 funcobj.__isabstractmethod__ = True
AttributeError: 'classmethod' object has no attribute '__isabstractmethod__'
>>> class C(metaclass=abc.ABCMeta):
... @classmethod
... @abc.abstractmethod
... def f(cls): print(42)
... 
>>> class D(C): pass
... 
>>> D.f()
42
msg86922 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2009年05月01日 22:09
Please ask questions like this first on python-list or the c.l.p or
gmane mirrors.
msg113790 - (view) Author: Daniel Urban (daniel.urban) * (Python triager) Date: 2010年08月13日 15:57
@abstractmethod
@classmethod
def ...
doesn't work because classmethod objects doesn't have a __dict__, so setting arbitrary attributes don't work, and abstractmethod tries to set the __isabstractmethod__ atribute to True.
The other order:
@classmethod
@abstractmethod
def ...
doesn't work, because the abstractmethod decorator sets the function's __isabstractmethod__ attribute to True, but when ABCMeta.__new__ checks the object in the namespace of the class, it won't find it, because the classmethod object won't have an __isabstractmethod__ attribute.
The situation is the same with staticmethod.
One possible solution would be adding a descriptor to classmethod (and staticmethod), with the name "__isabstractmethod__", which on __get__ would check its underlying callable for this attribute, and on __set__ would set this attribute on that callable. I think this way both order should work.
msg113820 - (view) Author: Daniel Urban (daniel.urban) * (Python triager) Date: 2010年08月13日 19:35
Here is a patch, which adds a descriptor to classmethod and staticmethod.
Pseudocode:
__get__(self, inst, owner):
 if getattr(inst.callable, '__isabstractmethod__', False):
 return True
 return False
__set__(self, inst, value):
 inst.callable.__isabstractmethod__ = bool(value)
msg113822 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2010年08月13日 19:53
The patch doesn't check that instantiating these methods work at all.
msg113826 - (view) Author: Daniel Urban (daniel.urban) * (Python triager) Date: 2010年08月13日 20:26
If I understand correctly, some tests are needed for the instantiation of classes with abstract static/classmethods. I added them in issue5867a.diff.
msg113833 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2010年08月13日 21:20
Thank you. I'm not an ABC expert but it looks ok. Guido, what do you think?
msg113838 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2010年08月13日 21:42
As you figured out it is not yet supported.
I object to making changes to the classmethod implementation.
I expect the best thing to do is to add a new
@abc.abstractclassmethod
decorator defined in pure Python (maybe the definition of abstractproperty provides a hint on how to do this).
You may want to define @abc.abstractstaticmethod as well.
msg113877 - (view) Author: Daniel Urban (daniel.urban) * (Python triager) Date: 2010年08月14日 07:27
I'm attaching a new patch adding the abc.abstractclassmethod and abc.abstractstaticmethod decorators.
msg113973 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2010年08月15日 16:17
The patch looks fine code-wise, but it also needs a doc addition in Doc/library/abc.rst.
msg114038 - (view) Author: Daniel Urban (daniel.urban) * (Python triager) Date: 2010年08月16日 07:14
I'm attaching a new patch containing also some documentation for the two new decorators. The doc is rather terse, and english is not my first language, so please let me know if some corrections are needed.
msg114088 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2010年08月17日 00:03
Looks good.
msg114091 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2010年08月17日 00:53
Applied in r84124. Thanks for the patch.
History
Date User Action Args
2022年04月11日 14:56:48adminsetgithub: 50117
2010年08月17日 00:53:12benjamin.petersonsetstatus: open -> closed
resolution: accepted
messages: + msg114091
2010年08月17日 00:03:07eric.araujosetnosy: + eric.araujo
messages: + msg114088
2010年08月16日 07:14:44daniel.urbansetfiles: + abstractclassstaticmethod+doc.diff

messages: + msg114038
2010年08月15日 16:17:35pitrousetmessages: + msg113973
2010年08月14日 07:27:55daniel.urbansetfiles: + abstractclassstaticmethod.diff

messages: + msg113877
2010年08月13日 21:42:41gvanrossumsetmessages: + msg113838
2010年08月13日 21:20:38pitrousetnosy: + gvanrossum
messages: + msg113833
2010年08月13日 20:26:00daniel.urbansetfiles: + issue5867a.diff

messages: + msg113826
2010年08月13日 19:53:38pitrousetversions: + Python 3.2, - Python 3.1
nosy: + pitrou, benjamin.peterson

messages: + msg113822

stage: patch review
2010年08月13日 19:35:13daniel.urbansetfiles: + issue5867.diff
keywords: + patch
messages: + msg113820
2010年08月13日 15:57:47daniel.urbansetmessages: + msg113790
2010年08月12日 18:44:49daniel.urbansetnosy: + daniel.urban
2009年05月01日 22:09:58terry.reedysetnosy: + terry.reedy
messages: + msg86922
2009年04月28日 18:28:52benjamin.petersonsetpriority: normal
type: behavior -> enhancement
versions: + Python 3.1, - Python 3.0
2009年04月28日 14:24:11dellacreate

AltStyle によって変換されたページ (->オリジナル) /