[Python-bugs-list] [ python-Bugs-466125 ] PyLong_AsLongLong works for any integer

noreply@sourceforge.net noreply@sourceforge.net
Sun, 30 Sep 2001 11:28:31 -0700


Bugs item #466125, was opened at 2001-09-28 09:45
You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=466125&group_id=5470

Category: Python Interpreter Core
Group: Feature Request
Status: Closed
Resolution: Fixed
Priority: 5
Submitted By: Tom Epperly (tepperly)
Assigned to: Tim Peters (tim_one)
Summary: PyLong_AsLongLong works for any integer

Initial Comment:
It would be nice if PyLong_AsLongLong worked more like
PyInt_AsLong. When the value can be coerced into an
integer, it should be.

The current behavior is that PyLong_AsLongLong only
works (without raising an exception) on instances of a
PyLongObject.  I would be far better for my
application, http://www.llnl.gov/casc/components/, if
PyLong_AsLongLong called PyInt_AsLong in cases where
the argument is not a PyLongObject. The return value of
PyInt_AsLong can safely be promoted to a long long.

The end result that I would like is that an 'L' in a
PyArg_ParseTuple call return any integer value (int or
long) as a C long long. PyArg_ParseTuple ultimately
uses PyLong_AsLongLong to handle the L format code.

It would be nice to have this behavior in past versions
too (i.e. 1.5.2, 2.0 and 2.1).

Here is an example of how one might do this.  This
patch also changes the behavior of PyLong_AsLong to
fall back on PyInt_AsLong.

$ diff -c longobject.c~ longobject.c
*** longobject.c~	Wed Jan 17 07:33:18 2001
--- longobject.c	Fri Sep 28 09:42:45 2001
***************
*** 144,153 ****
  	unsigned long x, prev;
  	int i, sign;
  
! 	if (vv == NULL || !PyLong_Check(vv)) {
  		PyErr_BadInternalCall();
  		return -1;
  	}
  	v = (PyLongObject *)vv;
  	i = v->ob_size;
  	sign = 1;
--- 144,156 ----
  	unsigned long x, prev;
  	int i, sign;
  
! 	if (vv == NULL) {
  		PyErr_BadInternalCall();
  		return -1;
  	}
+ 	if (!PyLong_Check(vv)) {
+ 		return PyInt_AsLong(vv);
+         }
  	v = (PyLongObject *)vv;
  	i = v->ob_size;
  	sign = 1;
***************
*** 387,395 ****
  	LONG_LONG x, prev;
  	int i, sign;
  	
! 	if (vv == NULL || !PyLong_Check(vv)) {
  		PyErr_BadInternalCall();
  		return -1;
  	}
  
  	v = (PyLongObject *)vv;
--- 390,401 ----
  	LONG_LONG x, prev;
  	int i, sign;
  	
! 	if (vv == NULL) {
  		PyErr_BadInternalCall();
  		return -1;
+ 	}
+ 	if (!PyLong_Check(vv)) {
+ 		return PyInt_AsLong(vv);
  	}
  
  	v = (PyLongObject *)vv;


----------------------------------------------------------------------

>Comment By: Tom Epperly (tepperly)
Date: 2001-09-30 11:28

Message:
Logged In: YES 
user_id=94539

Thanks to all for making the change.  It will make my Python
language bindings easier and better.

When I spoke of changing it in past version, I did not mean
to suggest time travel or some method of altering everyone's
installations of previously released version. I was
wondering if it could be included in future bug fix releases
to previously released versions. However, this appears to be
against your policy for bug fixes that I've gleaned from
your WWW pages.

----------------------------------------------------------------------

Comment By: Tim Peters (tim_one)
Date: 2001-09-29 22:12

Message:
Logged In: YES 
user_id=31435

PyLong_AsLongLong (and so also PyArg_ParseTuple 'L') now 
accepts longs and ints (but not types other than those and 
subclasses of those), for 2.2:

Doc/ext/extending.tex; new revision: 1.3
Misc/ACKS; new revision: 1.113
Misc/NEWS; new revision: 1.260
Modules/_testcapimodule.c; new revision: 1.12
Objects/longobject.c; new revision: 1.110

----------------------------------------------------------------------

Comment By: Tim Peters (tim_one)
Date: 2001-09-29 21:36

Message:
Logged In: YES 
user_id=31435

Oops!  What Guido did in PyLong_AsLong is back off to 
PyInt_AsLong but only if PyInt_Check is true.  What the 
suggested patch does is call PyInt_AsLong in *any* non-NULL 
case where PyLong_Check is false, and that includes dubious 
things like converting floats to ints.

I don't think we want that, and it isn't needed for your 
stated goal ("'L' in a PyArg_ParseTuple call return any 
integer value (int or long) as a C long long").

----------------------------------------------------------------------

Comment By: Tim Peters (tim_one)
Date: 2001-09-29 21:20

Message:
Logged In: YES 
user_id=31435

Hmm.  The patch is against some older version of Python 
that doesn't bear much textual resemblance to current 
longobject.c (i.e., patch can't make head or tail of this).

I believe Guido already changed PyLong_AsLong(), about 2 
weeks ago, to back off to PyInt_AsLong if an int object is 
passed in.

PyLong_AsLongLong() does not, though, and I agree it's a 
good idea.  So I'll do that.

Tom, I hope you didn't intend your "It would be nice to 
have this behavior in past versions too (i.e. 1.5.2, 2.0 
and 2.1)" to have more actual content than "It would be 
nice if people never died before they were ready to go" 
<0.9 wink>.  But if so, we obviously can't change the 
behavior of code that's already been released.

----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2001-09-28 10:05

Message:
Logged In: YES 
user_id=6380

Makes sense to me. Tim, what do you think?

----------------------------------------------------------------------

You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=466125&group_id=5470