classification
Title: Python 2.6 object.__new__ argument calling autodetection faulty
Type: behavior Stage:
Components: Versions: Python 2.6
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Ringding, Trundle, aronacher, benjamin.peterson, gvanrossum, pitrou, prologic, sebastinas
Priority: normal Keywords: patch

Created on 2009-02-19 20:34 by aronacher, last changed 2011-10-10 00:03 by benjamin.peterson.

Files
File name Uploaded Description Edit
update_one_slot.patch Trundle, 2009-03-24 20:25 review
Messages (7)
msg82497 - (view) Author: Armin Ronacher (aronacher) * (Python committer) Date: 2009-02-19 20:34
In 2.6 a deprecation warning was added if `object.__new__` was called
with arguments.  Per se this is fine, but the detection seems to be faulty.

The following code shows the problem:

>>> class A(object):
...     def __new__(self):
...         raise TypeError('i do not exist')
... 
>>> class B(A):
...     __new__ = object.__new__
...     def __init__(self, x):
...         self.x = x
... 
>>> B(1)
__main__:1: DeprecationWarning: object.__new__() takes no parameters
<__main__.B object at 0x88dd0>

In the `B` case `__new__` is not overridden (in the sense that it
differs from object.__new__) but `__init__` is.  Which is the default
behaviour.  Nonetheless a warning is raised.

I used the pattern with the "__new__ switch" to achieve a
cStringIO.StringIO behavior that supports typechecks:  IterIO() returns
either a IterI or IterO object, both instances of IterIO so that
typechecks can be performed.

Real-world use case here:
http://dev.pocoo.org/projects/werkzeug/browser/werkzeug/contrib/iterio.py
msg82505 - (view) Author: Armin Ronacher (aronacher) * (Python committer) Date: 2009-02-19 22:48
The problem seems to be caused by tp_new being slot_tp_new which then
invokes whatever __new__ in the class dict is.

I'm not so sure what would be the solution to this.  One could of course
check if tp_new is either object_new or slot_tp_new and in the latter
case check if the class dict's __new__ item is object_new...
msg84112 - (view) Author: Andreas Stührk (Trundle) Date: 2009-03-24 20:25
I think the real problem here is `update_one_slot` and not `object_new`. It
is impossible to set "__new__" to a PyCFunction inside Python code, which
may be a feature, but is in fact very irritating.

For example the following snippet:

>>> class Dict(dict): __new__ = object.__new__
...
>>> Dict.__new__ is object.__new__
True
>>> Dict()
{}

I would rather expect this behaviour (or at least that Dict.__new__ is not
object.__new__):

>>> Dict.__new__ is object.__new__
True
>>> Dict()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object.__new__(Dict) is not safe, use dict.__new__()

The attached patch leads to that behaviour, which also fixes the argument
calling autodetection of `object.__new__`.
msg85828 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2009-04-09 21:46
I'm sorry, I don't have any opinion on this.
msg86111 - (view) Author: Andreas Stührk (Trundle) Date: 2009-04-18 08:56
The problem is that `type_setattro()` sets the new "__new__" attribute
in the type's dict (through `PyObject_GenericSetAttr()`), but the
corresponding slot will never be updated if the new "__new__" is a
PyCFunction.

The affected code in `update_one_slot()` was added by Guido van Rossum
in r28090, so maybe he would like to comment on that.
msg86702 - (view) Author: Andreas Stührk (Trundle) Date: 2009-04-27 21:55
See also issue #1694663.
msg145289 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2011-10-10 00:03
I think it needs tests.
History
Date User Action Args
2011-10-10 00:03:54benjamin.petersonsetnosy: + benjamin.peterson
messages: + msg145289
2009-05-06 10:53:32Ringdingsetnosy: + Ringding
2009-04-27 21:55:44Trundlesetmessages: + msg86702
2009-04-26 19:16:47Trundlesetnosy: + gvanrossum
2009-04-18 08:56:09Trundlesetmessages: + msg86111
2009-04-09 21:46:45pitrousetassignee: pitrou ->
messages: + msg85828
2009-04-09 20:08:01georg.brandlsetassignee: pitrou

nosy: + pitrou
2009-03-24 22:19:35sebastinassetnosy: + sebastinas
2009-03-24 20:25:09Trundlesetfiles: + update_one_slot.patch

nosy: + Trundle
messages: + msg84112

keywords: + patch
2009-02-26 19:25:21prologicsetnosy: + prologic
2009-02-19 22:48:04aronachersetmessages: + msg82505
2009-02-19 20:34:23aronachercreate