Eric Snow <[email protected]> added the comment:
I'm not sure that this is a duplicate of #5322. That one's about a warning
when arguments are passed to object.__new__(). Yours is about using an
incompatible __new__ when creating a new class in Python. I agree that
behavior you're seeing is unexpected and should probably be fixed.
Let's look at the situation a little more closely. Here's what I understood
you reported:
>>> class X:
... __new__ = tuple.__new__
...
>>> x1 = X() # This does not fail!
However, that is a little misleading because you might think it is calling
tuple.__new__(). It isn't. Apparently type.__call__() is invoking
object.__new__() instead of X.__new__():
>>> x2 = X([1, 2])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object() takes no parameters
>>> object.__new__(X, [1, 2])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object() takes no parameters
If I had a little more time I'd look into the relevant code to see what's going
on. In the meantime, let's see if we can find the edges of this problem.
We can verify that X.__new__ is still set to tuple.__new__:
>>> X.__new__ is object.__new__
False
>>> X.__new__ is tuple.__new__
True
>>> X.__new__(X)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: tuple.__new__(X): X is not a subtype of tuple
>>> X.__new__(X, [1, 2])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: tuple.__new__(X): X is not a subtype of tuple
>>> X.__new__(tuple)
()
>>> X.__new__(tuple, [1, 2])
(1, 2)
If we explicitly defer to tuple.__new__() then we get an error that matches our
expectations better:
>>> class Y:
... def __new__(cls, *args, **kwargs):
... return tuple.__new__(cls, *args, **kwargs)
...
>>> y = Y()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __new__
TypeError: tuple.__new__(Y): Y is not a subtype of tuple
This reinforces the conclusion that tuple.__call__() is doing something funny
here. We can take that conclusion further by seeing that the unexpected
behavior is not specific to using tuple.__new__:
>>> class Z:
... __new__ = int.__new__
...
>>> z1 = Z()
>>> z2 = Z(42)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object() takes no parameters
>>> Z.__new__(Z)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: int.__new__(Z): Z is not a subtype of int
----------
nosy: +eric.snow
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue34362>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com