[Python-3000] PyLong_Check() behaviour clarification (test_getargs2 failing on Windows x64)

Trent Nelson tnelson at onresolve.com
Thu Mar 20 08:13:00 CET 2008


test_getargs2 is failing on Windows x64:
test test_getargs2 failed -- Traceback (most recent call last):
  File "S:\buildbots\python.x64\3.0.nelson-win64\build\lib\test\test_getargs2.py", line 190, in test_n
    self.failUnlessEqual(99, getargs_n(Long()))
TypeError: 'Long' object cannot be interpreted as an integer

Drilling down into the source, this code arrives at Python/getargs.c:convertsimple().  On Windows x64, SIZEOF_SIZE_T != SIZEOF_LONG, so there's a case 'n' statement that is defined that does the following:

    iobj = PyNumber_Index(arg);

I'm a little confused.  At this point, arg is a PyObject *, and arg->obj_type->tp_as_number->nb_int has a non-zero value.  However, PyNumber_Index(arg) performs two checks, and this object fails both, which results in the TypeError being raised.

The first check is PyLong_Check(arg), which is handled via PyType_FastSubclass, which ends up doing the following:

    ((arg->obj_type->tp_flags & Py_TPFLAGS_LONG_SUBCLASS) != 0)

tp_flags is 284160 at this point.  Py_TPFLAGS_LONG_SUBCLASS is 16777216 and Py_TPFLAGS_INT_SUBCLASS is 8388608, so this check fails.  Why doesn't tp_flags have either one of these values here?  obj_type->nb_int has a value, so shouldn't flags reflect the type?

I've just checked a 32-bit build and PyNumber_Index for a PyObject * representing a literal 99 also exhibits the same behaviour as above.

Also, if we're a 32-bit build, the 'n' code path visits PyLong_AsLong(), which calls PyLong_AsLongAndOverflow() -- the test cases calling getargs_n() test for the overflow being raised correctly.  Notionally, on x64 Windows where ((size_t == long long) > long), shouldn't we have a PyLong_AsLongLongAndOverflow() method?

    Trent.


More information about the Python-3000 mailing list