Nick Coghlan added the comment:

Interestingly, even `types.new_class` misbehaves in this case:

```
>>> def mydec(cls):
...     return types.new_class(cls.__name__, cls.__bases__, exec_body=lambda 
ns: ns.update(cls.__dict__))
... 
>>> @mydec
... class MyList(list):
...     def insert(self, idx, obj):
...         super().insert(idx, obj)
... 
>>> MyList().insert(0, 1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in insert
TypeError: super(type, obj): obj must be an instance or subtype of type
```

The error message is confusing here because it's using 'type' as a metavariable 
to refer to the first argument of super(), *not* to the builtin called "type".

If we poke around in the MyList.insert closure, we can see the origin of the 
problem:

```
>>> MyList.insert.__closure__[0].cell_contents
<class '__main__.MyList'>
>>> MyList.insert.__closure__[0].cell_contents is MyList
False
```

The class cell is still bound to the originally created class object, but the 
decorator threw that away and returned a completely different object. As a 
result, the "self" passed to the bound method is *not* an instance of the type 
stored in the "__class__" cell, and super() complains.

Given that super() doesn't take keyword arguments, perhaps we should propose on 
python-dev that "type" be changed to "starting_type" in the super() error 
messages and documentation?

----------

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

Reply via email to