Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No way to create an abstract classmethod #50117

Closed
della mannequin opened this issue Apr 28, 2009 · 13 comments
Closed

No way to create an abstract classmethod #50117

della mannequin opened this issue Apr 28, 2009 · 13 comments
Labels
stdlib Python modules in the Lib dir type-feature A feature request or enhancement

Comments

@della
Copy link
Mannequin

della mannequin commented Apr 28, 2009

BPO 5867
Nosy @gvanrossum, @terryjreedy, @pitrou, @benjaminp, @merwok, @durban
Files
  • issue5867.diff: Patch (py3k branch)
  • issue5867a.diff: New patch (+ tests) (py3k branch)
  • abstractclassstaticmethod.diff: Patch adding the abc.abstractclassmethod and abc.abstractstatismethod decorators
  • abstractclassstaticmethod+doc.diff: New patch (+doc)
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2010-08-17.00:53:12.003>
    created_at = <Date 2009-04-28.14:24:11.112>
    labels = ['type-feature', 'library']
    title = 'No way to create an abstract classmethod'
    updated_at = <Date 2010-08-17.00:53:12.001>
    user = 'https://bugs.python.org/della'

    bugs.python.org fields:

    activity = <Date 2010-08-17.00:53:12.001>
    actor = 'benjamin.peterson'
    assignee = 'none'
    closed = True
    closed_date = <Date 2010-08-17.00:53:12.003>
    closer = 'benjamin.peterson'
    components = ['Library (Lib)']
    creation = <Date 2009-04-28.14:24:11.112>
    creator = 'della'
    dependencies = []
    files = ['18510', '18512', '18519', '18542']
    hgrepos = []
    issue_num = 5867
    keywords = ['patch']
    message_count = 13.0
    messages = ['86744', '86922', '113790', '113820', '113822', '113826', '113833', '113838', '113877', '113973', '114038', '114088', '114091']
    nosy_count = 7.0
    nosy_names = ['gvanrossum', 'terry.reedy', 'pitrou', 'benjamin.peterson', 'eric.araujo', 'della', 'daniel.urban']
    pr_nums = []
    priority = 'normal'
    resolution = 'accepted'
    stage = 'patch review'
    status = 'closed'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue5867'
    versions = ['Python 3.2']

    @della
    Copy link
    Mannequin Author

    della mannequin commented Apr 28, 2009

    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

    @della della mannequin added type-bug An unexpected behavior, bug, or error stdlib Python modules in the Lib dir labels Apr 28, 2009
    @benjaminp benjaminp added type-feature A feature request or enhancement and removed type-bug An unexpected behavior, bug, or error labels Apr 28, 2009
    @terryjreedy
    Copy link
    Member

    Please ask questions like this first on python-list or the c.l.p or
    gmane mirrors.

    @durban
    Copy link
    Mannequin

    durban mannequin commented Aug 13, 2010

    @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.

    @durban
    Copy link
    Mannequin

    durban mannequin commented Aug 13, 2010

    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)

    @pitrou
    Copy link
    Member

    pitrou commented Aug 13, 2010

    The patch doesn't check that instantiating these methods work at all.

    @durban
    Copy link
    Mannequin

    durban mannequin commented Aug 13, 2010

    If I understand correctly, some tests are needed for the instantiation of classes with abstract static/classmethods. I added them in issue5867a.diff.

    @pitrou
    Copy link
    Member

    pitrou commented Aug 13, 2010

    Thank you. I'm not an ABC expert but it looks ok. Guido, what do you think?

    @gvanrossum
    Copy link
    Member

    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.

    @durban
    Copy link
    Mannequin

    durban mannequin commented Aug 14, 2010

    I'm attaching a new patch adding the abc.abstractclassmethod and abc.abstractstaticmethod decorators.

    @pitrou
    Copy link
    Member

    pitrou commented Aug 15, 2010

    The patch looks fine code-wise, but it also needs a doc addition in Doc/library/abc.rst.

    @durban
    Copy link
    Mannequin

    durban mannequin commented Aug 16, 2010

    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.

    @merwok
    Copy link
    Member

    merwok commented Aug 17, 2010

    Looks good.

    @benjaminp
    Copy link
    Contributor

    Applied in r84124. Thanks for the patch.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    stdlib Python modules in the Lib dir type-feature A feature request or enhancement
    Projects
    None yet
    Development

    No branches or pull requests

    5 participants