This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: structmember T_LONG won't accept a python long
Type: Stage:
Components: None Versions: Python 2.5
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: loewis, nnorwitz, rupole
Priority: high Keywords:

Created on 2006-08-24 05:07 by rupole, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (7)
msg29658 - (view) Author: Roger Upole (rupole) Date: 2006-08-24 05:07
An attribute defined as T_LONG throws a vague error
when set to a python long, even when the value is 
within the range of a LONG.

TypeError: bad argument type for built-in operation
msg29659 - (view) Author: Neal Norwitz (nnorwitz) * (Python committer) Date: 2006-08-24 18:30
Logged In: YES 
user_id=33168

Can you provide example code that demonstrates what you mean?
msg29660 - (view) Author: Roger Upole (rupole) Date: 2006-08-24 19:56
Logged In: YES 
user_id=771074

The DEVMODE object from pywintypes has attributes defined 
as T_LONG via the structmember API.

>>> import pywintypes
>>> dm=pywintypes.DEVMODEType()
>>> dm.Position_x=3
>>> dm.Position_x
3
>>> dm.Position_x=long(3)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: bad argument type for built-in operation
>>>

Here's the relevant code from structmember.c
that throws the error:
	case T_LONG:
		if (!PyInt_Check(v)) {
			PyErr_BadArgument();
			return -1;
		}
		*(long*)addr = PyInt_AsLong(v);
		break;
msg29661 - (view) Author: Neal Norwitz (nnorwitz) * (Python committer) Date: 2006-08-25 00:52
Logged In: YES 
user_id=33168

Ugh.  This code is lax in checking/conversion.  Do you think
you could provide a patch?

All of the int cases should call PyInt_AsLong() if this call
fails (returns -1), then that should be returned from
PyMember_SetOne.  If it succeeds, there should be a range
check that ensures the value is valid.  If that fails a
warning should be produced.  We need to issue a warning
rather than an error for backwards compatability (at least
for 2.6).

The float/double cases can be simplified some by calling
PyFloat_AsDouble and doing similar checks as in the int cases.
msg29662 - (view) Author: Roger Upole (rupole) Date: 2006-08-28 02:23
Logged In: YES 
user_id=771074

In the process of creating a patch for this, I came across 
some more 'ugh'-liness.  T_UINT's are returned via 
PyInt_FromLong, so you actually get back a negative value 
for large numbers.  Changing it to use 
PyLong_FromUnsignedLong will break backward compatibility, 
but this is so wrong I can't possibly see keeping it.  Your 
call. (plus it makes it impossible to test T_UINT with 
values larger than INT_MAX)
msg29663 - (view) Author: Roger Upole (rupole) Date: 2006-08-30 05:06
Logged In: YES 
user_id=771074

Submitted patch 1549049.
msg29664 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2006-10-27 06:19
Logged In: YES 
user_id=21627

Patch committed, so this is now fixed.
History
Date User Action Args
2022-04-11 14:56:19adminsetgithub: 43887
2006-08-24 05:07:18rupolecreate