[ python-Bugs-1633630 ] class derived from float evaporates under +=
SourceForge.net
noreply at sourceforge.net
Tue Jan 16 18:40:55 CET 2007
Bugs item #1633630, was opened at 2007-01-11 15:49
Message generated for change (Comment added) made by josiahcarlson
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1633630&group_id=5470
Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: Type/class unification
Group: Python 2.5
Status: Open
Resolution: None
Priority: 5
Private: No
Submitted By: Matthias Klose (doko)
Assigned to: Nobody/Anonymous (nobody)
Summary: class derived from float evaporates under +=
Initial Comment:
[forwarded from http://bugs.debian.org/345373]
There seems to be a bug in classes derived from float.
For instance, consider the following:
>>> class Float(float):
... def __init__(self, v):
... float.__init__(self, v)
... self.x = 1
...
>>> a = Float(2.0)
>>> b = Float(3.0)
>>> type(a)
<class '__main__.Float'>
>>> type(b)
<class '__main__.Float'>
>>> a += b
>>> type(a)
<type 'float'>
Now, the type of a has silently changed. It was a Float, a derived class with
all kinds of properties, and it became a float -- a plain vanilla number.
My understanding is that this is incorrect, and certainly unexpected.
If it *is* correct, it certainly deserves mention somewhere in the documentation.
It seems that Float.__iadd__(a, b) should be called.
This defaults to float.__iadd__(a, b), which should increment the float
part of the object while leaving the rest intact.
A possible explanation for this problem is that float.__iadd__ is not actually
defined, and so it falls through to
a = float.__add__(a, b), which assigns a float to a.
This interpretation seems to be correct, as one can add a destructor to the Float class:
>>> class FloatD(float):
... def __init__(self, v):
... float.__init__(self, v)
... self.x = 1
... def __del__(self):
... print 'Deleting FloatD class, losing x=', self.x
...
>>> a = FloatD(2.0)
>>> b = FloatD(3.0)
>>> a += b
Deleting FloatD class, losing x= 1
>>>
----------------------------------------------------------------------
Comment By: Josiah Carlson (josiahcarlson)
Date: 2007-01-16 09:40
Message:
Logged In: YES
user_id=341410
Originator: NO
The current behavior is as designed. Not a bug. Suggested move to RFE or
close as "Not a bug".
There has been discussion on either the python-dev or python-3000 mailing
lists discussing how subclasses of builtin types (int, long, float, str,
unicode, list, tuple, ...) should behave when confronted with one of a set
of "standard" operators. While there has been general "it would be nice"
if 'a + b' produced 'type(a)(a + b)' on certain occasions, this would
change the semantics of all such operations in a backwards incompatible
way (so has not been implemented).
If you want to guarantee such behavior (without writing all of the
__special__ methods) I would suggest that you instead create a __getattr__
method to automatically handle the coercion back into your subtype.
----------------------------------------------------------------------
Comment By: Georg Brandl (gbrandl)
Date: 2007-01-13 09:57
Message:
Logged In: YES
user_id=849994
Originator: NO
You don't need augmented assign for that, just doing "a+b" will give you a
float too.
----------------------------------------------------------------------
Comment By: Jim Jewett (jimjjewett)
Date: 2007-01-12 13:26
Message:
Logged In: YES
user_id=764593
Originator: NO
Python float objects are immutable and can be shared.
Therefore, their values cannot be modified -- which is why it falls back
to not-in-place assignment.
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1633630&group_id=5470
More information about the Python-bugs-list
mailing list