This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: float_subtype_new() bug
Type: Stage:
Components: Interpreter Core Versions:
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: nascheme Nosy List: arigo, gvanrossum, insomnike, nascheme, tim.peters
Priority: normal Keywords:

Created on 2004-06-04 15:39 by arigo, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
rv_check2.patch nascheme, 2004-06-18 22:07
Messages (12)
msg21019 - (view) Author: Armin Rigo (arigo) * (Python committer) Date: 2004-06-04 15:39
A rather obsure bug in the subclassing code:

>>> class A:
...   def __float__(self): return 'hello'
...
>>> float(A())
'hello'

>>> class f(float): pass
...
>>> f(A())
-5.7590155905901735e-56

In debug mode, the assert() in float_subtype_new() fails instead.  In non-debug mode, the value we get is the result of typecasting the PyStringObject* to a PyFloatObject*.
msg21020 - (view) Author: Aaron Brady (insomnike) Date: 2004-06-05 13:01
Logged In: YES 
user_id=1057404

floatobject.c contains an assertion that the value can be
coerced into a float, but not a runtime if. I've changed it
to be in line with what int_subtype_new() does.

This may not be 100% correct, however, as they both allow a
string to be returned from __int__() and __float__(),
respectively. complex() does not allow this, however, and it
throws TypeError (while int_subtype_new() and
float_subtype_new() throw ValueError).
msg21021 - (view) Author: Aaron Brady (insomnike) Date: 2004-06-05 13:11
Logged In: YES 
user_id=1057404

(Inline, I can't seem to attach things)

###
--- floatobject.c-      Sat Jun  5 13:21:07 2004
+++ floatobject.c       Sat Jun  5 13:23:00 2004
@@ -765,7 +765,13 @@
        tmp = float_new(&PyFloat_Type, args, kwds);
        if (tmp == NULL)
                return NULL;
-       assert(PyFloat_CheckExact(tmp));
+       if(!PyFloat_CheckExact(tmp)) {
+               PyErr_SetString(PyExc_ValueError,
+                               "value must convertable to a
float");
+               Py_DECREF(tmp);
+               return NULL;
+       }
+
        new = type->tp_alloc(type, 0);
        if (new == NULL) {
                Py_DECREF(tmp);
###
msg21022 - (view) Author: Aaron Brady (insomnike) Date: 2004-06-05 13:13
Logged In: YES 
user_id=1057404

(ack, spelling error copied from intobject.c)

###
--- floatobject.c-      Sat Jun  5 13:21:07 2004
+++ floatobject.c       Sat Jun  5 13:23:00 2004
@@ -765,7 +765,13 @@
        tmp = float_new(&PyFloat_Type, args, kwds);
        if (tmp == NULL)
                return NULL;
-       assert(PyFloat_CheckExact(tmp));
+       if(!PyFloat_CheckExact(tmp)) {
+               PyErr_SetString(PyExc_ValueError,
+                               "value must be convertable
to a float");
+               Py_DECREF(tmp);
+               return NULL;
+       }
+
        new = type->tp_alloc(type, 0);
        if (new == NULL) {
                Py_DECREF(tmp);
###
msg21023 - (view) Author: Neil Schemenauer (nascheme) * (Python committer) Date: 2004-06-05 19:46
Logged In: YES 
user_id=35752

I think the right fix is to have PyNumber_Int,
PyNumber_Float, and PyNumber_Long check the return value of
slot function (i.e. nb_int, nb_float).  That matches the
behavior of PyObject_Str and PyObject_Repr.
msg21024 - (view) Author: Neil Schemenauer (nascheme) * (Python committer) Date: 2004-06-05 21:00
Logged In: YES 
user_id=35752

I've got an alternative patch.  SF cvs is down at the moment
so I'll have to generate a patch later.  My change makes
CPython match the behavior of Jython.
msg21025 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2004-06-07 15:37
Logged In: YES 
user_id=31435

Assigned to Neil, as a reminder to attach his patch.
msg21026 - (view) Author: Neil Schemenauer (nascheme) * (Python committer) Date: 2004-06-08 02:54
Logged In: YES 
user_id=35752

Attaching patch.  One outstanding issue is that it may make
sense to search for and remove unnecessary type checks (e.g.
PyNumber_Int followed by PyInt_Check).  Also, this change
only broke one test case but I have no idea how much user
code this might break.
msg21027 - (view) Author: Armin Rigo (arigo) * (Python committer) Date: 2004-06-16 22:23
Logged In: YES 
user_id=4771

Let's be careful here.  I can imagine that some __int__() implementations in user code would return a long instead, as it is the behavior of int(something_too_big) already.

As far as I know, the original bug this tracker is for is the only place where it was blindly assumed that a specific conversion method returned an object of a specific type.  I'm fine with just fixing that case.
msg21028 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2004-06-17 17:02
Logged In: YES 
user_id=6380

(BTW, shouldn't it be "convertible"?)

I'm torn. For practical reasons, I'm for the minimal patch
originally proposed. Also because I want to allow __int__
returning a long (and vice versa!).

But according to my post this morning to python-dev, I would
like to ensure that the return type of int(), float(), etc.
can be relied upon by type inferencing engines. It would be
a shame to have to assume that after x = int(y) the type of
x could be anything...

Neil, can you rework your patch to be lenient about int/long
but otherwise be strict? It means callers of PyNumber_Int()
should still be careful, but that's the way of the future
anyway.
msg21029 - (view) Author: Neil Schemenauer (nascheme) * (Python committer) Date: 2004-06-18 22:07
Logged In: YES 
user_id=35752

My patch allows nb_int and nb_long to return either long or
int objects.  That means callers of PyNumber_Long need to be
careful too.  I'm uploading a new version of the patch that
adds a test for int/long interchangeability.
msg21030 - (view) Author: Neil Schemenauer (nascheme) * (Python committer) Date: 2004-07-19 16:30
Logged In: YES 
user_id=35752

Checked in as:

Lib/test/test_class.py 1.11
Misc/NEWS 1.1046
Objects/abstract.c 2.130
Objects/intobject.c 2.111
Python/bltinmodule.c 2.312
History
Date User Action Args
2022-04-11 14:56:04adminsetgithub: 40345
2004-06-04 15:39:13arigocreate