Message290843
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? |
|
Date |
User |
Action |
Args |
2017-03-30 14:48:55 | ncoghlan | set | recipients:
+ ncoghlan, xiang.zhang, bup |
2017-03-30 14:48:55 | ncoghlan | set | messageid: <1490885335.54.0.880588121106.issue29944@psf.upfronthosting.co.za> |
2017-03-30 14:48:55 | ncoghlan | link | issue29944 messages |
2017-03-30 14:48:55 | ncoghlan | create | |
|