# Is it time to deprecate unbound super methods?

**URL:** <https://discuss.python.org/t/is-it-time-to-deprecate-unbound-super-methods/1833>\
**Category:** Ideas\
**Created:** [June 8, 2019, 3:54am UTC](https://discuss.python.org/t/is-it-time-to-deprecate-unbound-super-methods/1833 "2019-06-08T03:54:42Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![steven.daprano](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/steven.daprano/32/1083_2.png) [@steven.daprano](https://discuss.python.org/u/steven.daprano)\
**Post date:** [June 8, 2019, 3:54am UTC](https://discuss.python.org/t/is-it-time-to-deprecate-unbound-super-methods/1833/1 "2019-06-08T03:54:42Z")

</div>

As long ago as Python 3.0, there was [talk about deprecating  
unbound super objects](https://mail.python.org/pipermail/python-3000/2007-September/010181.html), which aren’t documented very well, and are often confusing. [Many people](https://stackoverflow.com/questions/22403897/what-does-it-mean-by-the-super-object-returned-is-unbound-in-python) assume that if bound super objects dispatch to bound methods:

```
super(T, obj).method # returns method bound to obj

```

then obviously unbound super objects must dispatch to unbound methods:

```
super(T).method # returns unbound method

```

(I know that’s what I assumed) but that’s not the case.

[Michele Simionato suggested](https://www.artima.com/weblogs/viewpost.jsp?thread=236278) that (1) there’s only a single use-case for unbound super objects, and (2) they don’t even work correctly for that use-case.

Now that we have the zero-argument form of super(), does that remove the motivation for unbound super objects? Should they be deprecated in 3.9 for removal in 3.10?

Or keep them and document them better?

---

<div class="post-metadata">

**Author:** ![mjpieters](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/mjpieters/32/710_2.png) [@mjpieters](https://discuss.python.org/u/mjpieters)\
**Post date:** [June 9, 2019, 8:52am UTC](https://discuss.python.org/t/is-it-time-to-deprecate-unbound-super-methods/1833/2 "2019-06-09T08:52:06Z")

</div>

For those that wonder about what the single-argument version does: it creates an unbound `super()` instance, you bind that instance, then look up attributes. E.g. store `super(Type)` on the class then look that up on the instance. See [my answer on a Stack Overflow question](https://stackoverflow.com/questions/30190185/how-can-i-use-super-with-one-argument-in-python).

The idea was that you’d be able to avoid repeating the class all the time:

```python
class Foo(Bar):
    def override(self):
        return "spam" + self.__sup.override()

# set manually or have a metaclass or __init_subclass__ take care of this attribute
Foo._Foo__sup = super(Foo)

```

And the case were that doesn’t work is classmethods, because `cls.__sup` won’t be bound.

With `super()` now picking up the class from a closure the primary use case is gone, I wouldn’t expect anyone to be using the single-argument version.

---

<div class="post-metadata">

**Author:** ![pitrou](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pitrou/32/28_2.png) [@pitrou](https://discuss.python.org/u/pitrou)\
**Post date:** [June 9, 2019, 10:36am UTC](https://discuss.python.org/t/is-it-time-to-deprecate-unbound-super-methods/1833/3 "2019-06-09T10:36:53Z")

</div>

I didn’t even know the single-argument version existed. The only two forms I’ve ever used are `super(Type, self)` and `super()`.

---

<div class="post-metadata">

**Author:** ![guido](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/guido/32/21_2.png) [@guido](https://discuss.python.org/u/guido)\
**Post date:** [July 1, 2019, 4:45am UTC](https://discuss.python.org/t/is-it-time-to-deprecate-unbound-super-methods/1833/4 "2019-07-01T04:45:30Z")

</div>

Yeah, let’s start deprecating this.

---

<div class="post-metadata">

**Author:** ![steven.daprano](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/steven.daprano/32/1083_2.png) [@steven.daprano](https://discuss.python.org/u/steven.daprano)\
**Post date:** [August 10, 2019, 8:19am UTC](https://discuss.python.org/t/is-it-time-to-deprecate-unbound-super-methods/1833/5 "2019-08-10T08:19:21Z")

</div>

[https://bugs.python.org/issue37808](https://bugs.python.org/issue37808)

---

<div class="post-metadata">

**Author:** ![maggyero](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/maggyero/32/1505_2.png) [@maggyero](https://discuss.python.org/u/maggyero)\
**Post date:** [May 8, 2021, 11:15pm UTC](https://discuss.python.org/t/is-it-time-to-deprecate-unbound-super-methods/1833/6 "2021-05-08T23:15:03Z")

</div>

> [@steven.daprano](#):
>
> [Michele Simionato suggested](https://www.artima.com/weblogs/viewpost.jsp?thread=236278) that (1) there’s only a single use-case for unbound super objects, and (2) they don’t even work correctly for that use-case.

> [@mjpieters](#):
>
> And the case were that doesn’t work is classmethods, because `cls.__sup` won’t be bound.

The `classmethod` case will work if we update the method `super. __get__ ` to bind an unbound `super` object to the argument `owner` when there is no argument `instance` to bind to. The patch of the C function [super\_descr\_get](https://github.com/python/cpython/blob/v3.9.5/Objects/typeobject.c#L8029-L8061) in Objects/typeobject.c is given here as a pure Python equivalent 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)

```

Demo:

```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

```

So I would rather apply this patch which solves the only flaw of one-argument `super` than deprecate it. What do you guys think? @guido?

---

<div class="post-metadata">

**Author:** ![maggyero](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/maggyero/32/1505_2.png) [@maggyero](https://discuss.python.org/u/maggyero)\
**Post date:** [May 9, 2021, 5:13pm UTC](https://discuss.python.org/t/is-it-time-to-deprecate-unbound-super-methods/1833/7 "2021-05-09T17:13:06Z")

</div>

I have just opened a pull request providing the patch described previously:

> <https://github.com/python/cpython/pull/26009>
>
> https://bugs.python.org/issue44090
> \<!-- /issue-number --\>
