
The following change in behavior is causing one of my tests to fail. Is it intentional? Should isinstance(int(x),int) really ever return False? $ python Python 2.2.2 (#1, Feb 3 2003, 14:10:37) [GCC 3.2 20020927 (prerelease)] on cygwin Type "help", "copyright", "credits" or "license" for more information.
dave@penguin ~ $ /usr/local/pydebug/bin/python Python 2.3a2+ (#1, Feb 24 2003, 15:02:10) [GCC 3.2 20020927 (prerelease)] on cygwin Type "help", "copyright", "credits" or "license" for more information.

[David Abrahams]
The following change in behavior is causing one of my tests to fail.
Dear Lord, another buggy test <wink>.
Is it intentional?
Yes, as part of the ongoing push toward int/long unification. If you tried the same test in Python 2.1, it would have blown up in the "sys.maxint * 2" part. In 2.2, it blows up in the "int()" part. In 2.3, it doesn't blow up at all. In 2.4 or 2.5, __builtin__.int and __builtin__.long may well be the same object.
Should isinstance(int(x),int) really ever return False?
In 2.3, yes (albeit unfortunately).
Adding one more: Python 2.1.3 (#35, Apr 8 2002, 17:47:50) [MSC 32 bit (Intel)] on win32

Tim Peters <tim.one@comcast.net> writes:
Yes, but in the meantime, PyInt_AS_LONG( invoke_int_conversion(x) ) might be a crash instead of raising an exception. That's what is causing my test to fail. I guess I just need to lowercase a few characters, but it's worth noting that this change breaks existing extension module code. -- Dave Abrahams Boost Consulting www.boost-consulting.com

[David Abrahams]
Yes, but in the meantime, PyInt_AS_LONG( invoke_int_conversion(x) ) might be a crash instead of raising an exception.
As the comment before that macro's definition says, /* Macro, trading safety for speed */ PyInt_AsLong() won't crash, but its result needs to be checked for an error return. Note that your example: PyInt_AS_LONG( invoke_int_conversion(x) ) wasn't safe before either: I'm not sure what invoke_int_conversion(x) means exactly, but the plausible meanings I can think of for it *could* yield a NULL pointer, or a pointer to a non-int object, in any version of Python (e.g., PyNumber_Int() calls tp_as_number->nb_int but doesn't check the return value for sanity). In either of those cases PyInt_AS_LONG blindly applied to the result could crash.
That's what is causing my test to fail. I guess I just need to lowercase a few characters,
You also need to check for an error return -- PyInt_AsLong() can fail.
but it's worth noting that this change breaks existing extension module code.
I'm not sure it can break any I wouldn't have considered broken before. It's normal (& expected) not to use the macro unless you *know* you've got an int object, usually by virtue of passing a PyInt_Check() test first.

Tim Peters <tim.one@comcast.net> writes:
Yeah, actually invoke_int_conversion basically invoked the nb_int slot, and I _was_ doing the NULL check (don't forget, C++ has exceptions).
I knew that, but thanks. I was exaggerating for effect; did it, it works.
I guess I was reading http://www.python.org/doc/current/ref/numeric-types.html#l2h-184 a little too strongly when I wrote the code: __complex__(self) __int__(self) __long__(self) __float__(self) Called to implement the built-in functions complex() int() long() and float(). Should return a value of the appropriate type. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ That's pretty weak language, and even if it were strong I should've known better. Some joker would eventually add an __int__ method, that returns, say, a Long. I just didn't expect it to happen in the core (for some reason). -- Dave Abrahams Boost Consulting www.boost-consulting.com

[David Abrahams]
The following change in behavior is causing one of my tests to fail.
Dear Lord, another buggy test <wink>.
Is it intentional?
Yes, as part of the ongoing push toward int/long unification. If you tried the same test in Python 2.1, it would have blown up in the "sys.maxint * 2" part. In 2.2, it blows up in the "int()" part. In 2.3, it doesn't blow up at all. In 2.4 or 2.5, __builtin__.int and __builtin__.long may well be the same object.
Should isinstance(int(x),int) really ever return False?
In 2.3, yes (albeit unfortunately).
Adding one more: Python 2.1.3 (#35, Apr 8 2002, 17:47:50) [MSC 32 bit (Intel)] on win32

Tim Peters <tim.one@comcast.net> writes:
Yes, but in the meantime, PyInt_AS_LONG( invoke_int_conversion(x) ) might be a crash instead of raising an exception. That's what is causing my test to fail. I guess I just need to lowercase a few characters, but it's worth noting that this change breaks existing extension module code. -- Dave Abrahams Boost Consulting www.boost-consulting.com

[David Abrahams]
Yes, but in the meantime, PyInt_AS_LONG( invoke_int_conversion(x) ) might be a crash instead of raising an exception.
As the comment before that macro's definition says, /* Macro, trading safety for speed */ PyInt_AsLong() won't crash, but its result needs to be checked for an error return. Note that your example: PyInt_AS_LONG( invoke_int_conversion(x) ) wasn't safe before either: I'm not sure what invoke_int_conversion(x) means exactly, but the plausible meanings I can think of for it *could* yield a NULL pointer, or a pointer to a non-int object, in any version of Python (e.g., PyNumber_Int() calls tp_as_number->nb_int but doesn't check the return value for sanity). In either of those cases PyInt_AS_LONG blindly applied to the result could crash.
That's what is causing my test to fail. I guess I just need to lowercase a few characters,
You also need to check for an error return -- PyInt_AsLong() can fail.
but it's worth noting that this change breaks existing extension module code.
I'm not sure it can break any I wouldn't have considered broken before. It's normal (& expected) not to use the macro unless you *know* you've got an int object, usually by virtue of passing a PyInt_Check() test first.

Tim Peters <tim.one@comcast.net> writes:
Yeah, actually invoke_int_conversion basically invoked the nb_int slot, and I _was_ doing the NULL check (don't forget, C++ has exceptions).
I knew that, but thanks. I was exaggerating for effect; did it, it works.
I guess I was reading http://www.python.org/doc/current/ref/numeric-types.html#l2h-184 a little too strongly when I wrote the code: __complex__(self) __int__(self) __long__(self) __float__(self) Called to implement the built-in functions complex() int() long() and float(). Should return a value of the appropriate type. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ That's pretty weak language, and even if it were strong I should've known better. Some joker would eventually add an __int__ method, that returns, say, a Long. I just didn't expect it to happen in the core (for some reason). -- Dave Abrahams Boost Consulting www.boost-consulting.com
participants (2)
-
David Abrahams
-
Tim Peters