[BUG] IMO, but no opinions? Uncle Tim? was: int(float(sys.maxint)) buglet ?

Bengt Richter bokr at oz.net
Thu Dec 9 02:00:01 CET 2004

On Tue, 7 Dec 2004 16:44:56 -0500, Tim Peters <tim.peters at gmail.com> wrote:

>[Tim Peters]
>>> ... there's no promise anywhere, e.g., that Python will return an int
>>> whenever it's physically possible to do so.
>[Bengt Richter]
>> Ok, I understand the expediency of that policy, but what is now the meaning
>> of int, in that case? Is it now just a vestigial artifact on the way to
>> transparent unification of int and long to a single integer type?
>I don't really know what you mean by "int".  Python isn't C, and the
Me neither, now that I'd been nudged into thinking about it -- that's why I was *asking* ;-)
>distinction between Python's historical short integers and unbounded
>integers is indeed going away.  "int" is the name of a specific Python
>type, and the constructor for that type (which old-timers will think
>of as the builtin function named "int()") is happy to return unbounded
>integers in modern Pythons too.  Python-level distinctions here have
>become increasingly meaningless over time; I expect that "int" and
>"long" will eventually become synonyms for the same type at the Python
I guess the above is a long spelling of "yes" as an answer to my question ;-)

I assumed that python int was not indifferent to the underlying platform's
native C integer representations, and that its presence was a compromise
(now being deprecated) to permit armslength internal representation control,
for whatever reason (most likely to ease interfacing with something using a fixed
representation deriving from a C library).

>The distinction remains very visible at the Python C API level, for
>obvious reasons, but even C code has to be prepared to deal with that
>a PyIntObject or a PyLongObject may be given in contexts where "an
>integer" is required.
>> Promises or not, ISTM that if int->float succeeds in preserving all significant bits,
>> then then a following float->int should also succeed without converting to long.
>Yes, that was obvious <wink>.  But you haven't explained why you
>*care*, or, more importantly, why someone else should care.  It just
IME a corner-case discrepancy in a 1:1 correspondence is a bug waiting to appear
and bite. I admit to an aesthetic component to my unease with it though ;-)

>as obviously doesn't bother me, and I'm bold enough to claim that it
>"shouldn't" bother anyone.  This seems as peripheral to me as arguing
>that "there's something wrong" about returning "a long" in either of
>these cases:
>>>> import os
>>>> os.path.getsize("a.py")
>>>> f = open("a.py")
>>>> f.tell()
>The implementations of getsize() and .tell() certainly could have
>endured complications to ensure that "an int", and not "a long", was
>returned whenever physically possible to do so -- but why bother?
Those calls have obvious reasons for handling large-file sizes, but
they don't explicitly call for an int representation (whatever it means).

Help on class int in module __builtin__:

class int(object)
 |  int(x[, base]) -> integer
 |  Convert a string or number to an integer, if possible.  A floating point
 |  argument will be truncated towards zero (this does not include a string
 |  representation of a floating point number!)  When converting a string, use
 |  the optional base.  It is an error to supply a base when converting a
 |  non-string. If the argument is outside the integer range a long object
 |  will be returned instead.
Maybe the above should be amended to say that the "integer range"
is [-sys.maxint, sys.maxint-1] when the argument is a float ;-)

Or explain what "an integer" means ;-)

>> The 2.3.2 source snippet in floatobject.c :
>> --------------
>> static PyObject *
>> float_int(PyObject *v)
>> {
>> But this is apparently accessed through a table of pointers, so would you oppose
>> an auto-configuration that one time tested whether
>> int(float(sys.maxint))==sys.maxint and int(float(-sys.maxint-1))==-sys.maxint-1
>> (assuming that's sufficient, of which I'm not 100% sure ;-) and if so switched
>> the pointer to a version that tested if(LONG_MIN <= wholepart &&
>>> wholepart<=LONG_MAX)
>> instead of the safe-for-some-obscure-system version?
>In the absence of identifying an actual problem this would solve, I
>would oppose adding *gratuitous* complication.  Abusing your sense of
>aesthetics isn't "an actual problem" in this sense to me, although it
>may be to you.  Of course you're welcome to make any code changes you
>like in your own copy of Python <wnk>.
>> Of course, if int isn't all that meaningful any more, I guess the problem can be
>> moved to the ctypes module, if that gets included amongst the batteries ;-)
>What problem?  If there's an actual bug here, please open a bug report.
I guess there won't be a bug until it bites, so we have to imagine an app
where it would matter not to be able to get sys.maxint from a float
(except via int(int(floatarg)) ;-)

However unlikely, that seemed to me most likely to happen if there was
interfacing to some external function requiring a C-derived integer
representation, which is why I thought ctypes might be where a corner case
long that should have been an int might be detected, and the "problem"
might be solved there with a corner-case test and conversion, so as not
to fail on a legitimate value whose specific representation is something
the Python language per se is disassociating itself from ;-)

Not saying it's a bug wrt Python's unified integer future, just noting
the slow death of legacy expectations, and I guess tending to view it
as a bug so long as int implies anything at all about representation,
and sys.maxint purports to mean something specific about that ;-)

Bengt Richter

More information about the Python-list mailing list