Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

hex/oct constants > sys.maxint will return positive values in Python 2.4 and up

41 views
Skip to first unread message

Jon Ribbens

unread,
Nov 6, 2002, 1:57:45 PM11/6/02
to
My jonpy modules are producing the following warning when compiled
under Python 2.3 (current cvs):

FutureWarning: hex/oct constants > sys.maxint will return positive
values in Python 2.4 and up

The offending line of code is as follows:

data = struct.pack("!I", len(nameval[0]) | 0x80000000)

As far as I can tell, this change, when it comes in, will make no
difference at all to the way this code works. Am I right? What am
I supposed to do to make the warning go away? Rewrite 0x80000000 as
0x40000000 * 2 ? ;-)

Fredrik Lundh

unread,
Nov 6, 2002, 2:26:59 PM11/6/02
to
Jon Ribbens wrote:

add the sign?

or disable the warning? (see docs for the warning module)

the answer might be hidden somewhere in here, but I'm not
sure (we're at transition phase B0, I think):

http://www.python.org/peps/pep-0237.html

</F>


Tim Peters

unread,
Nov 6, 2002, 2:47:07 PM11/6/02
to
[Jon Ribbens]

> My jonpy modules are producing the following warning when compiled
> under Python 2.3 (current cvs):
>
> FutureWarning: hex/oct constants > sys.maxint will return positive
> values in Python 2.4 and up
>
> The offending line of code is as follows:
>
> data = struct.pack("!I", len(nameval[0]) | 0x80000000)
>
> As far as I can tell, this change, when it comes in, will make no
> difference at all to the way this code works. Am I right?

Probably, because the ultimate consumer of the computed value is a pack
format using a platform-independent definition of "I". Without the leading
"!" in the format, though, you get a platform-dependent pack, and 0x80000000
doesn't mean the same thing across all platforms today (but will starting in
Python 2.4).

> What am I supposed to do to make the warning go away? Rewrite 0x80000000
> as 0x40000000 * 2 ? ;-)

Write it in a platform-independent way. If you *intended* this literal to
mean "a 1 bit followed by 31 zero bits", then stick an L on the end of the
literal.


Fredrik Lundh

unread,
Nov 6, 2002, 3:58:23 PM11/6/02
to
Tim Peters wrote:

> > What am I supposed to do to make the warning go away? Rewrite 0x80000000
> > as 0x40000000 * 2 ? ;-)
>
> Write it in a platform-independent way. If you *intended* this literal to
> mean "a 1 bit followed by 31 zero bits", then stick an L on the end of the
> literal.

...and remove it again when you get to Python 2.5.

</F>


Jon Ribbens

unread,
Nov 6, 2002, 4:40:51 PM11/6/02
to
In article <mailman.103661215...@python.org>, Tim Peters wrote:
>> What am I supposed to do to make the warning go away? Rewrite 0x80000000
>> as 0x40000000 * 2 ? ;-)
>
> Write it in a platform-independent way. If you *intended* this literal to
> mean "a 1 bit followed by 31 zero bits", then stick an L on the end of the
> literal.

That'll generate a warning when we get to stage B2 of PEP237 and an
error by stage B4 so that makes things worse... (not much worse since
B4 is so far off, but still...)

I don't really like the idea of hacking around with the warning
module, so I guess I'll replace 0x80000000 with (-0x7fffffff-1) which
won't generate a warning on any version of Python and will work on all
versions... I think ;-)

John Baxter

unread,
Nov 6, 2002, 5:41:25 PM11/6/02
to
In article <slrnasj332.v...@snowy.squish.net>,
Jon Ribbens <jon+u...@unequivocal.co.uk> wrote:

> I don't really like the idea of hacking around with the warning
> module, so I guess I'll replace 0x80000000 with (-0x7fffffff-1) which
> won't generate a warning on any version of Python and will work on all
> versions... I think ;-)

64bit integers?

--John

Martin v. Loewis

unread,
Nov 6, 2002, 6:11:58 PM11/6/02
to
Jon Ribbens <jon+u...@unequivocal.co.uk> writes:

> The offending line of code is as follows:
>
> data = struct.pack("!I", len(nameval[0]) | 0x80000000)
>
> As far as I can tell, this change, when it comes in, will make no
> difference at all to the way this code works. Am I right? What am
> I supposed to do to make the warning go away? Rewrite 0x80000000 as
> 0x40000000 * 2 ? ;-)

If you think it makes no difference, add an L to the constant: it will
be a long int when the change is implemented (unless you are using
64-bit systems by then).

Regards,
Martin

Martin v. Loewis

unread,
Nov 6, 2002, 6:14:35 PM11/6/02
to
"Fredrik Lundh" <fre...@pythonware.com> writes:

> > Write it in a platform-independent way. If you *intended* this literal to
> > mean "a 1 bit followed by 31 zero bits", then stick an L on the end of the
> > literal.
>
> ...and remove it again when you get to Python 2.5.

Why that?

Regards,
Martin

Jon Ribbens

unread,
Nov 6, 2002, 6:40:46 PM11/6/02
to
In article <jwbaxter-E8FADF...@corp-radius.supernews.com>, John Baxter wrote:
>> I don't really like the idea of hacking around with the warning
>> module, so I guess I'll replace 0x80000000 with (-0x7fffffff-1) which
>> won't generate a warning on any version of Python and will work on all
>> versions... I think ;-)
>
> 64bit integers?

Why do you think that will make any difference? I just want to set
bit 31 of the integer, and I don't care if the integer is 32 bits
signed, 32 bits unsigned, or >32 bits, I just want to set bit 31,
the addition operator and struct.pack("!I") will still make the same
output no matter what type of integer they're getting (unless they're
buggy ;-) )

Tim Peters

unread,
Nov 6, 2002, 9:51:16 PM11/6/02
to
[Tim]

>> Write it in a platform-independent way. If you *intended* this
>> literal to mean "a 1 bit followed by 31 zero bits", then stick an
>> L on the end of the literal.

[/F]


> ...and remove it again when you get to Python 2.5.

You can if you want. The PEP continues to allow it until Python 3.0.

Tim Peters

unread,
Nov 6, 2002, 9:36:45 PM11/6/02
to
[Jon Ribbens]

> Why do you think that will make any difference? I just want to set
> bit 31 of the integer, and I don't care if the integer is 32 bits
> signed, 32 bits unsigned, or >32 bits, I just want to set bit 31,

Python the language doesn't have 32 bit integers, and that's the point. The
literal 0x80000000 means entirely different things on different Python
platforms today. In Python 2.4, it will mean the same thing across
platforms.


Tim Peters

unread,
Nov 6, 2002, 9:54:42 PM11/6/02
to
[Jon Ribbens]
>...

> I don't really like the idea of hacking around with the warning
> module, so I guess I'll replace 0x80000000 with (-0x7fffffff-1) which
> won't generate a warning on any version of Python and will work on all
> versions... I think ;-)

You didn't answer the question about what you *intended* 0x80000000 to mean.
The answer to your question follows from that. If you intended a 1 bit
followed by 31 zero bits, then, no, -0x7fffffff-1 doesn't mean that on some
platforms even today (or even in 1993, for that matter <wink>).


Fredrik Lundh

unread,
Nov 7, 2002, 3:05:52 AM11/7/02
to
Tim Peters wrote:

According to the PEP, Python 2.5 will print warnings whenever you use
long literals. If the OP doesn't want warnings, he'll have to change his
code for 2.3, and change it back for 2.5.

Looks like the only portable way to use large "unsigned" constants is to
use long("0x80000000")...

</F>


Thomas Heller

unread,
Nov 7, 2002, 3:18:35 AM11/7/02
to
"Fredrik Lundh" <fre...@pythonware.com> writes:

> Looks like the only portable way to use large "unsigned" constants is to
> use long("0x80000000")...
>
> </F>

Doesn't work for me in *any* Python version I have:

Python 2.2.2 (#37, Oct 14 2002, 17:02:34) [MSC 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> long("0x80000000")
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ValueError: invalid literal for long(): 0x80000000
>>>

long("0x80000000", 16) works starting with 2.0, but not in 1.5.2.

Thomas

Martin v. Löwis

unread,
Nov 7, 2002, 4:04:45 AM11/7/02
to
Jon Ribbens <jon+u...@unequivocal.co.uk> writes:

> I don't really like the idea of hacking around with the warning
> module, so I guess I'll replace 0x80000000 with (-0x7fffffff-1) which
> won't generate a warning on any version of Python and will work on all
> versions... I think ;-)

I would still recommend to use 0x8000000L instead; it saves you one
computation, and is more readable.

Regards,
Martin

Martin v. Löwis

unread,
Nov 7, 2002, 4:11:10 AM11/7/02
to
"Fredrik Lundh" <fre...@pythonware.com> writes:

> > You can if you want. The PEP continues to allow it until Python 3.0.
>
> According to the PEP, Python 2.5 will print warnings whenever you use
> long literals. If the OP doesn't want warnings, he'll have to change his
> code for 2.3, and change it back for 2.5.

It is quite difficult to predict the future, and I would suggest that
the OP ignores predictions that the PEP makes about what phases will
be implemented in what Python version.

My personal prediction is that Python 2.5 will not warn about long
literals.

> Looks like the only portable way to use large "unsigned" constants is to
> use long("0x80000000")...

You mean, long("80000000",16)?

Python 1.5.2 (#4, Jul 4 2000, 19:57:05) [GCC 2.95.2 19991024
(release)] on sunos5
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> long("80000000",16)
Traceback (innermost last):


File "<stdin>", line 1, in ?

TypeError: long requires exactly 1 argument; 2 given

Regards,
Martin

Tim Peters

unread,
Nov 7, 2002, 11:04:40 AM11/7/02
to
[/F]

> According to the PEP, Python 2.5 will print warnings whenever you use
> long literals. If the OP doesn't want warnings, he'll have to
> change his code for 2.3, and change it back for 2.5.

Except that's so silly on the face of it, you know that won't actually
happen. I mentioned it to Guido, and he removed the warnings business
from the PEP with no fuss. So, no, there won't be warnings for long
literals in the Python 2 line, the obvious solution is the correct
solution (tack on an L to make ambiguous literals platform-
independent), and Python 3 is a new ballgame.


Jon Ribbens

unread,
Nov 7, 2002, 12:12:02 PM11/7/02
to
In article <j465v93...@informatik.hu-berlin.de>, Martin v. Löwis wrote:
>> I don't really like the idea of hacking around with the warning
>> module, so I guess I'll replace 0x80000000 with (-0x7fffffff-1) which
>> won't generate a warning on any version of Python and will work on all
>> versions... I think ;-)
>
> I would still recommend to use 0x8000000L instead; it saves you one
> computation, and is more readable.

But that *won't work* on later versions of Python! It means I will
have a line in my code which I know will suddenly stop working at some
point in the future and I will have to make a new release and everyone
will have to upgrade their copies of my module just because I put in
code which I knew wasn't going to work.

Jon Ribbens

unread,
Nov 7, 2002, 12:16:53 PM11/7/02
to
In article <mailman.103663776...@python.org>, Tim Peters wrote:
> You didn't answer the question about what you *intended* 0x80000000 to mean.

I intend it to mean a set bit followed by 31 cleared bits.

> The answer to your question follows from that. If you intended a 1 bit
> followed by 31 zero bits, then, no, -0x7fffffff-1 doesn't mean that on some
> platforms even today (or even in 1993, for that matter <wink>).

What platforms doesn't it mean that on? What does it mean on those
platforms? Are you talking about platforms with 16-bit integers?
If so, I don't care.

Bengt Richter

unread,
Nov 7, 2002, 12:56:44 PM11/7/02
to

How about

BIT31 = 1<<31

and then use BIT31 wherever?

Regards,
Bengt Richter

Tim Peters

unread,
Nov 7, 2002, 12:23:51 PM11/7/02
to
[Martin v. Löwis]

> I would still recommend to use 0x8000000L instead;

I recommend another trailing 0 <wink>.

> it saves you one computation, and is more readable.

[Jon Ribbens]


> But that *won't work* on later versions of Python! It means I will
> have a line in my code which I know will suddenly stop working at some
> point in the future and I will have to make a new release and everyone
> will have to upgrade their copies of my module just because I put in
> code which I knew wasn't going to work.

There's no code you can write today that's guaranteed to work in Python 3.0.

In the Python 2 line, do as Martin keeps suggesting you do. Note that the
line about adding warnings for long literals in 2.5 has been removed from
the PEP.

Martin v. Löwis

unread,
Nov 7, 2002, 1:35:52 PM11/7/02
to
Jon Ribbens <jon+u...@unequivocal.co.uk> writes:

> > I would still recommend to use 0x8000000L instead; it saves you one
> > computation, and is more readable.
>
> But that *won't work* on later versions of Python!

How do you know? Later versions of Python have not been released!

> It means I will have a line in my code which I know will suddenly
> stop working at some point in the future and I will have to make a
> new release and everyone will have to upgrade their copies of my
> module just because I put in code which I knew wasn't going to work.

Yes, provided your code is still in use when that happens.

Regards,
Martin

Martin v. Löwis

unread,
Nov 7, 2002, 1:37:35 PM11/7/02
to
Jon Ribbens <jon+u...@unequivocal.co.uk> writes:

> > The answer to your question follows from that. If you intended a
> > 1 bit followed by 31 zero bits, then, no, -0x7fffffff-1 doesn't
> > mean that on some platforms even today (or even in 1993, for that
> > matter <wink>).
>
> What platforms doesn't it mean that on? What does it mean on those
> platforms? Are you talking about platforms with 16-bit integers?
> If so, I don't care.

64-bit platforms. -0x7fffffff-1 is 33 1 bits, followed by 31 zero
bits, on such systems. In future Python versions, it is an infinite
number of 1 bits followed by 31 zero bits.

Regards,
Martin

Tim Peters

unread,
Nov 7, 2002, 1:42:13 PM11/7/02
to
[Bengt Richter

> How about
>
> BIT31 = 1<<31
>
> and then use BIT31 wherever?

That's currently platform-dependent in exactly the same way as 0x80000000,
will also become platform-independent in Python 2.4, and also generates a
warning in 2.3:

>>> 1 << 31
__main__:1: FutureWarning: x<<y losing bits or changing sign will
return a long in Python 2.4 and up
-2147483648
>>>


Jon Ribbens

unread,
Nov 7, 2002, 2:20:29 PM11/7/02
to
In article <j4k7jpz...@informatik.hu-berlin.de>, Martin v. Löwis wrote:
>> > I would still recommend to use 0x8000000L instead; it saves you one
>> > computation, and is more readable.
>>
>> But that *won't work* on later versions of Python!
>
> How do you know? Later versions of Python have not been released!

Because PEP237 tells me so ;-)

>> It means I will have a line in my code which I know will suddenly
>> stop working at some point in the future and I will have to make a
>> new release and everyone will have to upgrade their copies of my
>> module just because I put in code which I knew wasn't going to work.
>
> Yes, provided your code is still in use when that happens.

Ooh, bitchy.

Jon Ribbens

unread,
Nov 7, 2002, 2:22:32 PM11/7/02
to
In article <j4fzudz...@informatik.hu-berlin.de>, Martin v. Löwis wrote:
>> What platforms doesn't it mean that on? What does it mean on those
>> platforms? Are you talking about platforms with 16-bit integers?
>> If so, I don't care.
>
> 64-bit platforms. -0x7fffffff-1 is 33 1 bits, followed by 31 zero
> bits, on such systems. In future Python versions, it is an infinite
> number of 1 bits followed by 31 zero bits.

Oh, OK. I don't care about that either because struct.pack("!I") will
still take the least-significant 32 bits and discard the 32-to-infinity
extra set bits.

Sheesh. Metaphors involving "blood" and "stones" come to mind.

Bengt Richter

unread,
Nov 7, 2002, 3:12:21 PM11/7/02
to

Ok, sorry, does
BIT31 = 1L<<31
work?

Regards,
Bengt Richter

Martin v. Loewis

unread,
Nov 7, 2002, 4:00:19 PM11/7/02
to
Jon Ribbens <jon+u...@unequivocal.co.uk> writes:

> >> But that *won't work* on later versions of Python!
> >
> > How do you know? Later versions of Python have not been released!
>
> Because PEP237 tells me so ;-)

No, it doesn't. It tells that this is the plan. It does not tell you
what the future will bring.

I recommend you ignore this part of the plan.

Regards,
Martin

Tim Peters

unread,
Nov 7, 2002, 3:37:44 PM11/7/02
to
[Bengt Richter]

> Ok, sorry, does
> BIT31 = 1L<<31
> work?

Yes, and means exactly the same thing as 0x80000000L. Both are identical in
respect of what the OP doesn't like about them too (that accepting trailing
'L' is slated to be removed in Python 3).


Martin v. Loewis

unread,
Nov 7, 2002, 4:11:41 PM11/7/02
to
bo...@oz.net (Bengt Richter) writes:

> Ok, sorry, does
> BIT31 = 1L<<31
> work?

Not if you assume the original complaint from Jon Ribbens: If long
literals become an error in some future Python release, this code will
stop working.

Regards,
Martin

Dennis Lee Bieber

unread,
Nov 7, 2002, 5:38:20 PM11/7/02
to
Jon Ribbens fed this fish to the penguins on Thursday 07 November 2002
09:12 am:


> But that *won't work* on later versions of Python! It means I will
> have a line in my code which I know will suddenly stop working at some
> point in the future and I will have to make a new release and everyone
> will have to upgrade their copies of my module just because I put in
> code which I knew wasn't going to work.

Well, can't you make use of something like sys.version_info to
determine which version you are running under, and use the form of
assignment appropriate to that version when defining your constant?

import sys

pver = sys.version_info

if pver[0] == 2: #2.x line
if pver[1] == 2: #2.2
do assignment
elif pver[2] == 3: #2.3 expected
do assignment
...

Might need to store the assignments as strings, and do an eval/exec
type operation on just the correct string if Python tries to interpret
the assignments in false branches...

--
--
> ============================================================== <
> wlf...@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
> wulf...@dm.net | Bestiaria Support Staff <
> ============================================================== <
> Bestiaria Home Page: http://www.beastie.dm.net/ <
> Home Page: http://www.dm.net/~wulfraed/ <

Aahz

unread,
Nov 14, 2002, 3:14:05 PM11/14/02
to
In article <Pnfy9.2862$h%5.10...@newsb.telia.net>,
Fredrik Lundh <fre...@pythonware.com> wrote:

>Tim Peters wrote:
>>>
>>> What am I supposed to do to make the warning go away? Rewrite 0x80000000
>>> as 0x40000000 * 2 ? ;-)
>>
>> Write it in a platform-independent way. If you *intended* this literal to
>> mean "a 1 bit followed by 31 zero bits", then stick an L on the end of the
>> literal.
>
>...and remove it again when you get to Python 2.5.

Why?
--
Aahz (aa...@pythoncraft.com) <*> http://www.pythoncraft.com/

A: No.
Q: Is top-posting okay?

Fredrik Lundh

unread,
Nov 17, 2002, 10:07:02 AM11/17/02
to
Aahz wrote:

> >> Write it in a platform-independent way. If you *intended* this literal to
> >> mean "a 1 bit followed by 31 zero bits", then stick an L on the end of the
> >> literal.
> >
> >...and remove it again when you get to Python 2.5.
>
> Why?

hint:

*** pep-0237.txt 12 Aug 2002 00:55:43 -0000 1.15
--- pep-0237.txt 7 Nov 2002 15:41:19 -0000 1.16
***************
*** 213,217 ****
option, but it is off by default.

! B2. The warning for long literals is turned on by default.

B3. The warnings about operations that give different results than
--- 213,217 ----
option, but it is off by default.

! B2. (This stage is deleted.)

B3. The warnings about operations that give different results than

</F>


0 new messages