Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fe8f862

Browse files
author
Thomas Heller
committed
Integrate patch from Neal Norwitz. He writes:
""" The attached patch fixes all the ctypes tests so they pass on amd64. It also fixes several warnings. I'm not sure what else to do with the patch. Let me know how you want to handle these in the future. I'm not sure the patch is 100% correct. You will need to decide what can be 64 bits and what can't. I believe sq_{item,slice,ass_item,ass_slice} all need to use Py_ssize_t. The types in ctypes.h may not require all the changes I made. I don't know how you want to support older version, so I unconditionally changed the types to Py_ssize_t. """ The patch is also in the ctypes SVN repository now, after small changes to add compatibility with older Python versions.
1 parent cb35b95 commit fe8f862

3 files changed

Lines changed: 60 additions & 56 deletions

File tree

Modules/_ctypes/_ctypes.c

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ static PyMethodDef CDataType_methods[] = {
335335
};
336336

337337
static PyObject *
338-
CDataType_repeat(PyObject *self, int length)
338+
CDataType_repeat(PyObject *self, Py_ssize_t length)
339339
{
340340
return CreateArrayType(self, length);
341341
}
@@ -695,7 +695,7 @@ static int
695695
CharArray_set_raw(CDataObject *self, PyObject *value)
696696
{
697697
char *ptr;
698-
int size;
698+
Py_ssize_t size;
699699
if (PyBuffer_Check(value)) {
700700
size = value->ob_type->tp_as_buffer->bf_getreadbuffer(value, 0, (void *)&ptr);
701701
if (size < 0)
@@ -1789,13 +1789,11 @@ unique_key(CDataObject *target, int index)
17891789
{
17901790
char string[256]; /* XXX is that enough? */
17911791
char *cp = string;
1792-
int len;
17931792
*cp++ = index + '0';
17941793
while (target->b_base) {
17951794
*cp++ = target->b_index + '0';
17961795
target = target->b_base;
17971796
}
1798-
len = cp - string;
17991797
return PyString_FromStringAndSize(string, cp-string);
18001798
}
18011799
/* Keep a reference to 'keep' in the 'target', at index 'index' */
@@ -1806,7 +1804,7 @@ unique_key(CDataObject *target, int index)
18061804
* key int the root object's _objects dict.
18071805
*/
18081806
static int
1809-
KeepRef(CDataObject *target, int index, PyObject *keep)
1807+
KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep)
18101808
{
18111809
int result;
18121810
CDataObject *ob;
@@ -1875,7 +1873,7 @@ static PyMemberDef CData_members[] = {
18751873
{ NULL },
18761874
};
18771875

1878-
static int CData_GetBuffer(CDataObject *self, int seg, void **pptr)
1876+
static Py_ssize_t CData_GetBuffer(CDataObject *self, Py_ssize_t seg, void **pptr)
18791877
{
18801878
if (seg != 0) {
18811879
/* Hm. Must this set an exception? */
@@ -1885,18 +1883,18 @@ static int CData_GetBuffer(CDataObject *self, int seg, void **pptr)
18851883
return self->b_size;
18861884
}
18871885

1888-
static int CData_GetSegcount(CDataObject *self, int *lenp)
1886+
static Py_ssize_t CData_GetSegcount(CDataObject *self, Py_ssize_t *lenp)
18891887
{
18901888
if (lenp)
18911889
*lenp = 1;
18921890
return 1;
18931891
}
18941892

18951893
static PyBufferProcs CData_as_buffer = {
1896-
(getreadbufferproc)CData_GetBuffer,
1897-
(getwritebufferproc)CData_GetBuffer,
1898-
(getsegcountproc)CData_GetSegcount,
1899-
(getcharbufferproc)NULL,
1894+
(readbufferproc)CData_GetBuffer,
1895+
(writebufferproc)CData_GetBuffer,
1896+
(segcountproc)CData_GetSegcount,
1897+
(charbufferproc)NULL,
19001898
};
19011899

19021900
/*
@@ -1985,7 +1983,7 @@ static void CData_MallocBuffer(CDataObject *obj, StgDictObject *dict)
19851983
}
19861984

19871985
PyObject *
1988-
CData_FromBaseObj(PyObject *type, PyObject *base, int index, char *adr)
1986+
CData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr)
19891987
{
19901988
CDataObject *cmem;
19911989
StgDictObject *dict;
@@ -2064,7 +2062,7 @@ int IsSimpleSubType(PyObject *obj)
20642062

20652063
PyObject *
20662064
CData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
2067-
int index, int size, char *adr)
2065+
Py_ssize_t index, Py_ssize_t size, char *adr)
20682066
{
20692067
StgDictObject *dict;
20702068
if (getfunc)
@@ -2081,7 +2079,7 @@ CData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
20812079
*/
20822080
static PyObject *
20832081
_CData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
2084-
int size, char *ptr)
2082+
Py_ssize_t size, char *ptr)
20852083
{
20862084
CDataObject *src;
20872085

@@ -2177,7 +2175,7 @@ _CData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
21772175
*/
21782176
int
21792177
CData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
2180-
int index, int size, char *ptr)
2178+
Py_ssize_t index, Py_ssize_t size, char *ptr)
21812179
{
21822180
CDataObject *mem = (CDataObject *)dst;
21832181
PyObject *result;
@@ -3318,7 +3316,7 @@ Struct_init(PyObject *self, PyObject *args, PyObject *kwds)
33183316

33193317
if (kwds) {
33203318
PyObject *key, *value;
3321-
int pos = 0;
3319+
Py_ssize_t pos = 0;
33223320
while(PyDict_Next(kwds, &pos, &key, &value)) {
33233321
if (-1 == PyObject_SetAttr(self, key, value))
33243322
return -1;
@@ -3471,12 +3469,12 @@ Array_item(CDataObject *self, int index)
34713469
}
34723470

34733471
static PyObject *
3474-
Array_slice(CDataObject *self, int ilow, int ihigh)
3472+
Array_slice(CDataObject *self, Py_ssize_t ilow, Py_ssize_t ihigh)
34753473
{
34763474
StgDictObject *stgdict, *itemdict;
34773475
PyObject *proto;
34783476
PyListObject *np;
3479-
int i, len;
3477+
Py_ssize_t i, len;
34803478

34813479
if (ilow < 0)
34823480
ilow = 0;
@@ -3587,13 +3585,13 @@ Array_length(CDataObject *self)
35873585
}
35883586

35893587
static PySequenceMethods Array_as_sequence = {
3590-
(inquiry)Array_length, /* sq_length; */
3588+
(lenfunc)Array_length, /* sq_length; */
35913589
0, /* sq_concat; */
35923590
0, /* sq_repeat; */
3593-
(intargfunc)Array_item, /* sq_item; */
3594-
(intintargfunc)Array_slice, /* sq_slice; */
3595-
(intobjargproc)Array_ass_item, /* sq_ass_item; */
3596-
(intintobjargproc)Array_ass_slice, /* sq_ass_slice; */
3591+
(ssizeargfunc)Array_item, /* sq_item; */
3592+
(ssizessizeargfunc)Array_slice, /* sq_slice; */
3593+
(ssizeobjargproc)Array_ass_item, /* sq_ass_item; */
3594+
(ssizessizeobjargproc)Array_ass_slice, /* sq_ass_slice; */
35973595
0, /* sq_contains; */
35983596

35993597
0, /* sq_inplace_concat; */
@@ -3664,7 +3662,7 @@ PyTypeObject Array_Type = {
36643662
};
36653663

36663664
PyObject *
3667-
CreateArrayType(PyObject *itemtype, int length)
3665+
CreateArrayType(PyObject *itemtype, Py_ssize_t length)
36683666
{
36693667
static PyObject *cache;
36703668
PyObject *key;
@@ -3676,7 +3674,7 @@ CreateArrayType(PyObject *itemtype, int length)
36763674
if (cache == NULL)
36773675
return NULL;
36783676
}
3679-
key = Py_BuildValue("(Oi)", itemtype, length);
3677+
key = Py_BuildValue("(On)", itemtype, length);
36803678
if (!key)
36813679
return NULL;
36823680
result = PyDict_GetItem(cache, key);
@@ -3691,11 +3689,16 @@ CreateArrayType(PyObject *itemtype, int length)
36913689
"Expected a type object");
36923690
return NULL;
36933691
}
3694-
sprintf(name, "%.200s_Array_%d",
3692+
#ifdef MS_WIN64
3693+
sprintf(name, "%.200s_Array_%Id",
36953694
((PyTypeObject *)itemtype)->tp_name, length);
3695+
#else
3696+
sprintf(name, "%.200s_Array_%ld",
3697+
((PyTypeObject *)itemtype)->tp_name, (long)length);
3698+
#endif
36963699

36973700
result = PyObject_CallFunction((PyObject *)&ArrayType_Type,
3698-
"s(O){s:i,s:O}",
3701+
"s(O){s:n,s:O}",
36993702
name,
37003703
&Array_Type,
37013704
"_length_",
@@ -3869,7 +3872,7 @@ Simple_repr(CDataObject *self)
38693872

38703873
name = PyString_FromString(self->ob_type->tp_name);
38713874
if (name == NULL) {
3872-
Py_DECREF(name);
3875+
Py_DECREF(val);
38733876
return NULL;
38743877
}
38753878

@@ -4101,12 +4104,12 @@ Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
41014104
}
41024105

41034106
static PyObject *
4104-
Pointer_slice(CDataObject *self, int ilow, int ihigh)
4107+
Pointer_slice(CDataObject *self, Py_ssize_t ilow, Py_ssize_t ihigh)
41054108
{
41064109
PyListObject *np;
41074110
StgDictObject *stgdict, *itemdict;
41084111
PyObject *proto;
4109-
int i, len;
4112+
Py_ssize_t i, len;
41104113

41114114
if (ilow < 0)
41124115
ilow = 0;
@@ -4142,9 +4145,9 @@ static PySequenceMethods Pointer_as_sequence = {
41424145
0, /* inquiry sq_length; */
41434146
0, /* binaryfunc sq_concat; */
41444147
0, /* intargfunc sq_repeat; */
4145-
(intargfunc)Pointer_item, /* intargfunc sq_item; */
4146-
(intintargfunc)Pointer_slice, /* intintargfunc sq_slice; */
4147-
(intobjargproc)Pointer_ass_item, /* intobjargproc sq_ass_item; */
4148+
(ssizeargfunc)Pointer_item, /* intargfunc sq_item; */
4149+
(ssizessizeargfunc)Pointer_slice, /* intintargfunc sq_slice; */
4150+
(ssizeobjargproc)Pointer_ass_item, /* intobjargproc sq_ass_item; */
41484151
0, /* intintobjargproc sq_ass_slice; */
41494152
0, /* objobjproc sq_contains; */
41504153
/* Added in release 2.0 */
@@ -4318,7 +4321,7 @@ create_comerror(void)
43184321
#endif
43194322

43204323
static PyObject *
4321-
string_at(const char *ptr, int size)
4324+
string_at(const char *ptr, Py_ssize_t size)
43224325
{
43234326
if (size == 0)
43244327
return PyString_FromString(ptr);
@@ -4336,7 +4339,7 @@ wstring_at(const wchar_t *ptr, int size)
43364339
}
43374340
#endif
43384341

4339-
DL_EXPORT(void)
4342+
PyMODINIT_FUNC
43404343
init_ctypes(void)
43414344
{
43424345
PyObject *m;

Modules/_ctypes/callproc.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -721,8 +721,9 @@ static PyObject *GetResult(PyObject *restype, void *result, PyObject *checker)
721721
O_get), we have to call Py_DECREF because O_get has already
722722
called Py_INCREF.
723723
*/
724-
if (dict->getfunc == getentry("O")->getfunc)
724+
if (dict->getfunc == getentry("O")->getfunc) {
725725
Py_DECREF(retval);
726+
}
726727
} else
727728
retval = CData_FromBaseObj(restype, NULL, 0, result);
728729

Modules/_ctypes/ctypes.h

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ struct tagCDataObject {
5050
char *b_ptr; /* pointer to memory block */
5151
int b_needsfree; /* need _we_ free the memory? */
5252
CDataObject *b_base; /* pointer to base object or NULL */
53-
int b_size; /* size of memory block in bytes */
54-
int b_length; /* number of references we need */
55-
int b_index; /* index of this object into base's
53+
Py_ssize_t b_size; /* size of memory block in bytes */
54+
Py_ssize_t b_length; /* number of references we need */
55+
Py_ssize_t b_index; /* index of this object into base's
5656
b_object list */
5757
PyObject *b_objects; /* list of references we need to keep */
5858
union value b_value;
@@ -64,9 +64,9 @@ typedef struct {
6464
char *b_ptr; /* pointer to memory block */
6565
int b_needsfree; /* need _we_ free the memory? */
6666
CDataObject *b_base; /* pointer to base object or NULL */
67-
int b_size; /* size of memory block in bytes */
68-
int b_length; /* number of references we need */
69-
int b_index; /* index of this object into base's
67+
Py_ssize_t b_size; /* size of memory block in bytes */
68+
Py_ssize_t b_length; /* number of references we need */
69+
Py_ssize_t b_index; /* index of this object into base's
7070
b_object list */
7171
PyObject *b_objects; /* list of references we need to keep */
7272
union value b_value;
@@ -94,8 +94,8 @@ extern PyTypeObject StgDict_Type;
9494
#define StgDict_Check(v) PyObject_TypeCheck(v, &StgDict_Type)
9595

9696
extern int StructUnionType_update_stgdict(PyObject *fields, PyObject *type, int isStruct);
97-
extern int PyType_stginfo(PyTypeObject *self, int *psize, int *palign, int *plength);
98-
extern int PyObject_stginfo(PyObject *self, int *psize, int *palign, int *plength);
97+
extern int PyType_stginfo(PyTypeObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength);
98+
extern int PyObject_stginfo(PyObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength);
9999

100100

101101

@@ -118,7 +118,7 @@ CField_FromDesc(PyObject *desc, int index,
118118
int pack, int is_big_endian);
119119

120120
extern PyObject *CData_AtAddress(PyObject *type, void *buf);
121-
extern PyObject *CData_FromBytes(PyObject *type, char *data, int length);
121+
extern PyObject *CData_FromBytes(PyObject *type, char *data, Py_ssize_t length);
122122

123123
extern PyTypeObject ArrayType_Type;
124124
extern PyTypeObject Array_Type;
@@ -137,7 +137,7 @@ extern PyTypeObject StructType_Type;
137137
#define StructTypeObject_Check(v) PyObject_TypeCheck(v, &StructType_Type)
138138

139139
extern PyObject *
140-
CreateArrayType(PyObject *itemtype, int length);
140+
CreateArrayType(PyObject *itemtype, Py_ssize_t length);
141141

142142
extern void init_callbacks_in_module(PyObject *m);
143143

@@ -164,9 +164,9 @@ struct fielddesc {
164164

165165
typedef struct {
166166
PyObject_HEAD
167-
int offset;
168-
int size;
169-
int index; /* Index into CDataObject's
167+
Py_ssize_t offset;
168+
Py_ssize_t size;
169+
Py_ssize_t index; /* Index into CDataObject's
170170
object array */
171171
PyObject *proto; /* a type or NULL */
172172
GETFUNC getfunc; /* getter function if proto is NULL */
@@ -185,9 +185,9 @@ typedef struct {
185185
too much risk to change that now, and there are other fields which doen't
186186
belong into this structure anyway. Maybe in ctypes 2.0... (ctypes 2000?)
187187
*/
188-
int size; /* number of bytes */
189-
int align; /* alignment requirements */
190-
int length; /* number of fields */
188+
Py_ssize_t size; /* number of bytes */
189+
Py_ssize_t align; /* alignment requirements */
190+
Py_ssize_t length; /* number of fields */
191191
ffi_type ffi_type;
192192
PyObject *proto; /* Only for Pointer/ArrayObject */
193193
SETFUNC setfunc; /* Only for simple objects */
@@ -298,17 +298,17 @@ extern PyCArgObject *new_CArgObject(void);
298298

299299
extern PyObject *
300300
CData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
301-
int index, int size, char *ptr);
301+
Py_ssize_t index, Py_ssize_t size, char *ptr);
302302

303303
extern int
304304
CData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
305-
int index, int size, char *ptr);
305+
Py_ssize_t index, Py_ssize_t size, char *ptr);
306306

307307
extern void Extend_Error_Info(PyObject *exc_class, char *fmt, ...);
308308

309309
struct basespec {
310310
CDataObject *base;
311-
int index;
311+
Py_ssize_t index;
312312
char *adr;
313313
};
314314

@@ -374,7 +374,7 @@ extern void *MallocClosure(void);
374374

375375
extern void _AddTraceback(char *, char *, int);
376376

377-
extern PyObject *CData_FromBaseObj(PyObject *type, PyObject *base, int index, char *adr);
377+
extern PyObject *CData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr);
378378

379379
/* XXX better name needed! */
380380
extern int IsSimpleSubType(PyObject *obj);

0 commit comments

Comments
 (0)