Is this a bug?

Jeff Epler jepler at unpythonic.net
Tue Mar 9 18:31:37 EST 2004


Your example boils down to this:
>>> list.__new__(list, [1, 2])
[]

It's not a bug.  list.__new__ allocates a new (empty) instance, then
list.__init__ fills it in:

>>> l = list.__new__(list)
>>> l
[]
>>> list.__init__(l, [1, 2, 3])
>>> l
[1, 2, 3]

Mutable objects are free to do things in this way.  For immutable
objects, like tuple, __new__ must fill in the created instance, and
__init__ does nothing:

>>> t = tuple.__new__(tuple, [1, 2, 3])
>>> t
(1, 2, 3)
>>> t.__init__([1, 2, 3])
>>> t
(1, 2, 3)
>>> t.__init__([1, 2, 3, 4])
>>> t
(1, 2, 3)

As you can see from the last few lines, "nothing" includes not detecting
that __init__ has been called a second time with a different argument!

Here's a passage from the "descrintro" document that addresses this
topic:

    Overriding the __new__ method
    =============================

    When subclassing immutable built-in types like numbers and strings, and
    occasionally in other situations, the static method __new__ comes in
    handy. __new__ is the first step in instance construction, invoked
    before __init__. The __new__ method is called with the class as its
    first argument; its responsibility is to return a new instance of that
    class. Compare this to __init__: __init__ is called with an instance as
    its first argument, and it doesn't return anything; its responsibility
    is to initialize the instance. There are situations where a new instance
    is created without calling __init__ (for example when the instance is
    loaded from a pickle). There is no way to create a new instance without
    calling __new__ (although in some cases you can get away with calling a
    base class's __new__).

    Recall that you create class instances by calling the class. When the
    class is a new-style class, the following happens when it is called.
    First, the class's __new__ method is called, passing the class itself as
    first argument, followed by any (positional as well as keyword)
    arguments received by the original call. This returns a new instance.
    Then that instance's __init__ method is called to further initialize it.
    (This is all controlled by the __call__ method of the metaclass, by the
    way.) 
        http://www.python.org/2.2.2/descrintro.html#__new__    

Jeff




More information about the Python-list mailing list