New submission from Géry <gery.o...@gmail.com>:

A use case of one-argument `super` (aka unbound `super`) is Guido van Rossum’s 
autosuper described in his 2002 article [*Unifying types and classes in Python 
2.2*](https://www.python.org/download/releases/2.2.3/descrintro/#cooperation).

It works with functions, but not with `classmethod` as Michele Simionato noted 
in his 2008 article [*Things to Know About Python 
Super*](https://www.artima.com/weblogs/viewpost.jsp?thread=236278).

I suggest fixing this by updating the method `super.__get__` to bind an unbound 
`super` object to the argument `owner` when there is no argument `instance` to 
bind to. Here is the patch applied to the C function 
[super_descr_get](https://github.com/python/cpython/blob/v3.9.5/Objects/typeobject.c#L8029-L8061)
 in Objects/typeobject.c, given in pure Python for better readability:

```python
    def __get__(self, instance, owner=None):
        if instance is None and owner is None:
            raise TypeError('__get__(None, None) is invalid')
-       if instance is None or self.__self__ is not None:
+       if self.__self__ is not None:
            return self
+       if instance is None:
+           return type(self)(self.__thisclass__, owner)
        return type(self)(self.__thisclass__, instance)
```

Demonstration:

```python
>>> class A:
...     def f(self): return 'A.f'
...     @classmethod
...     def g(cls): return 'A.g'
... 
>>> class B(A):
...     def f(self): return 'B.f ' + self.__super.f()
...     @classmethod
...     def g(cls): return 'B.g ' + cls.__super.g()
... 
>>> B._B__super = super(B)  # the CURRENT broken version of super
>>> print(B().f())  # function succeeds (instance binding)
B.f A.f
>>> print(B.g())    # classmethod fails (no binding)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in g
AttributeError: 'super' object has no attribute 'g'
>>> B._B__super = super(B)  # the PROPOSED fixed version of super
>>> print(B().f())  # function succeeds (instance binding)
B.f A.f
>>> print(B.g())    # classmethod succeeds (class binding)
B.g A.g
```

----------
components: Interpreter Core
messages: 393326
nosy: maggyero
priority: normal
severity: normal
status: open
title: Add class binding to unbound super objects for allowing autosuper with 
class methods
type: enhancement
versions: Python 3.10, Python 3.11, Python 3.9

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue44090>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to