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
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 "", 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;
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.
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)