msg168757 - (view) |
Author: James (james.sanders) |
Date: 2012-08-21 11:52 |
For example:
Python 3.2.2 (default, Feb 10 2012, 09:23:17)
[GCC 4.4.5 20110214 (Red Hat 4.4.5-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class A:
... def f(*args):
... print(super().__repr__())
...
>>> A().f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in f
SystemError: super(): no arguments
(There is no change in the current development version 3.3.0b2+)
I guess that the problem here is related to the fact that the super call makes sense if we call A().f() but not if we call A.f() (which is allowed by the method signature)? I understand that not including self in the signature is almost always bad style, but occasionally it is necessary, for example if you want to allow arbitrary keyword arguments as dict.update does.
Also, how come using the no-argument form of super outside a method raises SystemError - isn't that supposed to be for internal errors?
|
msg168959 - (view) |
Author: James (james.sanders) |
Date: 2012-08-23 19:13 |
I've attached a patch that I think fixes the variable arguments problem, and changes the SystemErrors that can be obtained by misusing super() into RuntimeErrors (I assume that's more appropriate?). There are three more SystemErrors I'm not sure about: "super(): no code object", "super(): bad __class__ cell", and "super(): empty __class__ cell" - can they only be caused by internal bugs?
|
msg168989 - (view) |
Author: James (james.sanders) |
Date: 2012-08-24 09:01 |
It turns out I don't really understand how frame objects work. My patch can crash python if you do this:
>>> class A:
... def f(*args):
... args = 1
... print(super())
...
>>> A().f()
python: Objects/typeobject.c:6516: super_init: Assertion `((((((PyObject*)(obj))->ob_type))->tp_flags & ((1L<<26))) != 0)' failed.
Aborted
Is there a way of checking if the first argument has been overwritten, or do you just have to assume that if it is still a tuple, it hasn't been? Should the super documentation mention that assigning to self (or args in this case) can make the no-argument version work incorrectly?
|
msg168995 - (view) |
Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * |
Date: 2012-08-24 10:28 |
The failing assertion is the "assert(PyTuple_Check(obj))" added by your patch.
At this point, "obj" is not the arguments tuple, but the first entry in "f->f_localsplus". Maybe this block should be moved a bit earlier?
|
msg168997 - (view) |
Author: James (james.sanders) |
Date: 2012-08-24 11:19 |
Sorry, I wasn't very clear. super() currently works by assuming that self is the first entry in f_localsplus, which is defeated, for example, by doing:
>>> class A:
... def f(self):
... del self
... super()
...
>>> A().f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in f
SystemError: super(): arg[0] deleted
>>> class B:
... def f(self):
... self = 1
... super()
...
>>> B().f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in f
TypeError: super(type, obj): obj must be an instance or subtype of type
I don't know if this is the intended behaviour (in which case, my assertion that obj is a tuple should be replaced by just checking whether it is a tuple and raising an exception otherwise; and I suppose the super documentation should mention this caveat), or whether this should be fixed somehow.
|
msg169002 - (view) |
Author: Andrew Svetlov (asvetlov) * |
Date: 2012-08-24 12:02 |
Changing exception type is not backward compatible and should be documented at least if that change is really required.
Personally I slightly prefer to leave SystemError untouched
|
msg169720 - (view) |
Author: Andrew Svetlov (asvetlov) * |
Date: 2012-09-02 20:07 |
BTW see #15839: super now raises RuntimeError.
After that I revoke my objection for exception type changing.
|
msg236499 - (view) |
Author: Mark Lawrence (BreamoreBoy) * |
Date: 2015-02-24 14:25 |
RuntimeError is now given instead of SystemError.
Python 3.4.2 (v3.4.2:ab2c023a9432, Oct 6 2014, 22:16:31) [MSC v.1600 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> class A:
... def f(*args):
... print(super().__repr__())
...
>>> A().f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in f
RuntimeError: super(): no arguments
so presumably this can be closed as "out of date"?
|
msg236554 - (view) |
Author: Josh Rosenberg (josh.r) * |
Date: 2015-02-24 23:37 |
Wasn't the objection that super shouldn't screw up, not the specific type of the exception?
|
msg245571 - (view) |
Author: Cristóbal Ganter (Cristóbal Ganter) |
Date: 2015-06-20 19:42 |
I have the same question as Josh Rosenberg.
Also, do you know any workarounds for this problem?
|
msg245578 - (view) |
Author: Martin Panter (martin.panter) * |
Date: 2015-06-21 00:15 |
The obvious workaround is to include an explicit “self” parameter (name shouldn’t matter):
def f(arbitrary, *positional, **most_keywords):
all_positional = (arbitrary,) + positional
...
If you need to reserve all keyword parameter names, you could try the manual version of super():
class A:
def f(*all_positional, **all_keywords):
print(super(A, all_positional[0]).__repr__())
|
msg335472 - (view) |
Author: Josh Rosenberg (josh.r) * |
Date: 2019-02-13 18:33 |
Moving from pending back to open (not sure what was "pending" about it?).
The workaround is viable (and used by Python implemented dict subclasses in the standard library since they must accept **kwargs with arbitrary strings, including self), but it does seem a little silly that it's required. Leaving it as low priority since the workaround exists.
Still, would be nice to make super() seamless, pulling the first argument if the function accepts it as non-varargs, and the first element of the first argument if it's varargs. If someone reassigns self/args, that's on them; it's fine to raise a RuntimeError if they use no-arg super(), requiring them to use two-arg super explicitly in that case.
|
|
Date |
User |
Action |
Args |
2022-04-11 14:57:35 | admin | set | github: 59958 |
2019-02-14 10:09:42 | BreamoreBoy | set | nosy:
- BreamoreBoy
|
2019-02-13 18:51:17 | remi.lapeyre | set | nosy:
+ remi.lapeyre
|
2019-02-13 18:33:09 | josh.r | set | priority: normal -> low status: pending -> open messages:
+ msg335472
versions:
+ Python 3.8, - Python 3.2, Python 3.3, Python 3.4 |
2016-05-06 08:33:35 | serhiy.storchaka | set | status: open -> pending |
2015-06-21 00:15:42 | martin.panter | set | nosy:
+ martin.panter messages:
+ msg245578
|
2015-06-20 19:42:03 | Cristóbal Ganter | set | nosy:
+ Cristóbal Ganter
messages:
+ msg245571 versions:
+ Python 3.4 |
2015-02-24 23:37:14 | josh.r | set | nosy:
+ josh.r messages:
+ msg236554
|
2015-02-24 14:56:06 | serhiy.storchaka | set | nosy:
+ benjamin.peterson
|
2015-02-24 14:25:05 | BreamoreBoy | set | nosy:
+ BreamoreBoy messages:
+ msg236499
|
2012-09-02 20:07:33 | asvetlov | set | messages:
+ msg169720 |
2012-08-26 19:58:04 | Arfrever | set | nosy:
+ Arfrever
|
2012-08-26 02:32:32 | eric.araujo | set | nosy:
+ eric.araujo
|
2012-08-24 12:02:00 | asvetlov | set | nosy:
+ asvetlov messages:
+ msg169002
|
2012-08-24 11:19:17 | james.sanders | set | messages:
+ msg168997 |
2012-08-24 11:17:16 | ezio.melotti | set | nosy:
+ ezio.melotti
|
2012-08-24 10:28:25 | amaury.forgeotdarc | set | nosy:
+ amaury.forgeotdarc messages:
+ msg168995
|
2012-08-24 09:01:40 | james.sanders | set | messages:
+ msg168989 |
2012-08-23 19:13:45 | james.sanders | set | files:
+ issue15753_varargsuper.patch keywords:
+ patch messages:
+ msg168959
|
2012-08-21 12:28:08 | r.david.murray | set | nosy:
+ r.david.murray
|
2012-08-21 11:52:40 | james.sanders | create | |