Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
2e75c450
Kaydet (Commit)
2e75c450
authored
Haz 05, 2008
tarafından
Thomas Heller
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Backport from py3k: Implement the new buffer interface from pep3118
for ctypes instances. Closes issue #2404.
üst
259a566a
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
290 additions
and
0 deletions
+290
-0
test_pep3118.py
Lib/ctypes/test/test_pep3118.py
+191
-0
_ctypes.c
Modules/_ctypes/_ctypes.c
+0
-0
callproc.c
Modules/_ctypes/callproc.c
+27
-0
ctypes.h
Modules/_ctypes/ctypes.h
+9
-0
stgdict.c
Modules/_ctypes/stgdict.c
+63
-0
No files found.
Lib/ctypes/test/test_pep3118.py
0 → 100644
Dosyayı görüntüle @
2e75c450
import
unittest
from
ctypes
import
*
import
re
,
struct
,
sys
if
sys
.
byteorder
==
"little"
:
THIS_ENDIAN
=
"<"
OTHER_ENDIAN
=
">"
else
:
THIS_ENDIAN
=
">"
OTHER_ENDIAN
=
"<"
class
memoryview
(
object
):
# This class creates a memoryview - like object from data returned
# by the private _ctypes._buffer_info() function, just enough for
# these tests.
#
# It can be removed when the py3k memoryview object is backported.
def
__init__
(
self
,
ob
):
from
_ctypes
import
_buffer_info
self
.
format
,
self
.
ndim
,
self
.
shape
=
_buffer_info
(
ob
)
if
self
.
shape
==
():
self
.
shape
=
None
self
.
itemsize
=
sizeof
(
ob
)
else
:
size
=
sizeof
(
ob
)
for
dim
in
self
.
shape
:
size
/=
dim
self
.
itemsize
=
size
self
.
strides
=
None
self
.
readonly
=
False
self
.
size
=
sizeof
(
ob
)
def
normalize
(
format
):
# Remove current endian specifier and white space from a format
# string
format
=
format
.
replace
(
OTHER_ENDIAN
,
THIS_ENDIAN
)
return
re
.
sub
(
r"\s"
,
""
,
format
)
class
Test
(
unittest
.
TestCase
):
def
test_native_types
(
self
):
for
tp
,
fmt
,
shape
,
itemtp
in
native_types
:
ob
=
tp
()
v
=
memoryview
(
ob
)
try
:
self
.
failUnlessEqual
(
normalize
(
v
.
format
),
normalize
(
fmt
))
self
.
failUnlessEqual
(
v
.
size
,
sizeof
(
ob
))
self
.
failUnlessEqual
(
v
.
itemsize
,
sizeof
(
itemtp
))
self
.
failUnlessEqual
(
v
.
shape
,
shape
)
# ctypes object always have a non-strided memory block
self
.
failUnlessEqual
(
v
.
strides
,
None
)
# they are always read/write
self
.
failIf
(
v
.
readonly
)
if
v
.
shape
:
n
=
1
for
dim
in
v
.
shape
:
n
=
n
*
dim
self
.
failUnlessEqual
(
v
.
itemsize
*
n
,
v
.
size
)
except
:
# so that we can see the failing type
print
(
tp
)
raise
def
test_endian_types
(
self
):
for
tp
,
fmt
,
shape
,
itemtp
in
endian_types
:
ob
=
tp
()
v
=
memoryview
(
ob
)
try
:
self
.
failUnlessEqual
(
v
.
format
,
fmt
)
self
.
failUnlessEqual
(
v
.
size
,
sizeof
(
ob
))
self
.
failUnlessEqual
(
v
.
itemsize
,
sizeof
(
itemtp
))
self
.
failUnlessEqual
(
v
.
shape
,
shape
)
# ctypes object always have a non-strided memory block
self
.
failUnlessEqual
(
v
.
strides
,
None
)
# they are always read/write
self
.
failIf
(
v
.
readonly
)
if
v
.
shape
:
n
=
1
for
dim
in
v
.
shape
:
n
=
n
*
dim
self
.
failUnlessEqual
(
v
.
itemsize
*
n
,
v
.
size
)
except
:
# so that we can see the failing type
print
(
tp
)
raise
# define some structure classes
class
Point
(
Structure
):
_fields_
=
[(
"x"
,
c_long
),
(
"y"
,
c_long
)]
class
PackedPoint
(
Structure
):
_pack_
=
2
_fields_
=
[(
"x"
,
c_long
),
(
"y"
,
c_long
)]
class
Point2
(
Structure
):
pass
Point2
.
_fields_
=
[(
"x"
,
c_long
),
(
"y"
,
c_long
)]
class
EmptyStruct
(
Structure
):
_fields_
=
[]
class
aUnion
(
Union
):
_fields_
=
[(
"a"
,
c_int
)]
################################################################
#
# This table contains format strings as they look on little endian
# machines. The test replaces '<' with '>' on big endian machines.
#
native_types
=
[
# type format shape calc itemsize
## simple types
(
c_char
,
"<c"
,
None
,
c_char
),
(
c_byte
,
"<b"
,
None
,
c_byte
),
(
c_ubyte
,
"<B"
,
None
,
c_ubyte
),
(
c_short
,
"<h"
,
None
,
c_short
),
(
c_ushort
,
"<H"
,
None
,
c_ushort
),
# c_int and c_uint may be aliases to c_long
#(c_int, "<i", None, c_int),
#(c_uint, "<I", None, c_uint),
(
c_long
,
"<l"
,
None
,
c_long
),
(
c_ulong
,
"<L"
,
None
,
c_ulong
),
# c_longlong and c_ulonglong are aliases on 64-bit platforms
#(c_longlong, "<q", None, c_longlong),
#(c_ulonglong, "<Q", None, c_ulonglong),
(
c_float
,
"<f"
,
None
,
c_float
),
(
c_double
,
"<d"
,
None
,
c_double
),
# c_longdouble may be an alias to c_double
(
c_bool
,
"<?"
,
None
,
c_bool
),
(
py_object
,
"<O"
,
None
,
py_object
),
## pointers
(
POINTER
(
c_byte
),
"&<b"
,
None
,
POINTER
(
c_byte
)),
(
POINTER
(
POINTER
(
c_long
)),
"&&<l"
,
None
,
POINTER
(
POINTER
(
c_long
))),
## arrays and pointers
(
c_double
*
4
,
"(4)<d"
,
(
4
,),
c_double
),
(
c_float
*
4
*
3
*
2
,
"(2,3,4)<f"
,
(
2
,
3
,
4
),
c_float
),
(
POINTER
(
c_short
)
*
2
,
"(2)&<h"
,
(
2
,),
POINTER
(
c_short
)),
(
POINTER
(
c_short
)
*
2
*
3
,
"(3,2)&<h"
,
(
3
,
2
,),
POINTER
(
c_short
)),
(
POINTER
(
c_short
*
2
),
"&(2)<h"
,
None
,
POINTER
(
c_short
)),
## structures and unions
(
Point
,
"T{<l:x:<l:y:}"
,
None
,
Point
),
# packed structures do not implement the pep
(
PackedPoint
,
"B"
,
None
,
PackedPoint
),
(
Point2
,
"T{<l:x:<l:y:}"
,
None
,
Point2
),
(
EmptyStruct
,
"T{}"
,
None
,
EmptyStruct
),
# the pep does't support unions
(
aUnion
,
"B"
,
None
,
aUnion
),
## other
# function signatures are not implemented
(
CFUNCTYPE
(
None
),
"X{}"
,
None
,
CFUNCTYPE
(
None
)),
]
class
BEPoint
(
BigEndianStructure
):
_fields_
=
[(
"x"
,
c_long
),
(
"y"
,
c_long
)]
class
LEPoint
(
LittleEndianStructure
):
_fields_
=
[(
"x"
,
c_long
),
(
"y"
,
c_long
)]
################################################################
#
# This table contains format strings as they really look, on both big
# and little endian machines.
#
endian_types
=
[
(
BEPoint
,
"T{>l:x:>l:y:}"
,
None
,
BEPoint
),
(
LEPoint
,
"T{<l:x:<l:y:}"
,
None
,
LEPoint
),
(
POINTER
(
BEPoint
),
"&T{>l:x:>l:y:}"
,
None
,
POINTER
(
BEPoint
)),
(
POINTER
(
LEPoint
),
"&T{<l:x:<l:y:}"
,
None
,
POINTER
(
LEPoint
)),
]
if
__name__
==
"__main__"
:
unittest
.
main
()
Modules/_ctypes/_ctypes.c
Dosyayı görüntüle @
2e75c450
This diff is collapsed.
Click to expand it.
Modules/_ctypes/callproc.c
Dosyayı görüntüle @
2e75c450
...
@@ -1666,10 +1666,37 @@ pointer(PyObject *self, PyObject *arg)
...
@@ -1666,10 +1666,37 @@ pointer(PyObject *self, PyObject *arg)
return
result
;
return
result
;
}
}
static
PyObject
*
buffer_info
(
PyObject
*
self
,
PyObject
*
arg
)
{
StgDictObject
*
dict
=
PyType_stgdict
(
arg
);
PyObject
*
shape
;
Py_ssize_t
i
;
if
(
dict
==
NULL
)
dict
=
PyObject_stgdict
(
arg
);
if
(
dict
==
NULL
)
{
PyErr_SetString
(
PyExc_TypeError
,
"not a ctypes type or object"
);
return
NULL
;
}
shape
=
PyTuple_New
(
dict
->
ndim
);
for
(
i
=
0
;
i
<
(
int
)
dict
->
ndim
;
++
i
)
PyTuple_SET_ITEM
(
shape
,
i
,
PyLong_FromSsize_t
(
dict
->
shape
[
i
]));
if
(
PyErr_Occurred
())
{
Py_DECREF
(
shape
);
return
NULL
;
}
return
Py_BuildValue
(
"siN"
,
dict
->
format
,
dict
->
ndim
,
shape
);
}
PyMethodDef
module_methods
[]
=
{
PyMethodDef
module_methods
[]
=
{
{
"POINTER"
,
POINTER
,
METH_O
},
{
"POINTER"
,
POINTER
,
METH_O
},
{
"pointer"
,
pointer
,
METH_O
},
{
"pointer"
,
pointer
,
METH_O
},
{
"_unpickle"
,
unpickle
,
METH_VARARGS
},
{
"_unpickle"
,
unpickle
,
METH_VARARGS
},
{
"_buffer_info"
,
buffer_info
,
METH_O
,
"Return buffer interface information (for testing only)"
},
{
"resize"
,
resize
,
METH_VARARGS
,
"Resize the memory buffer of a ctypes instance"
},
{
"resize"
,
resize
,
METH_VARARGS
,
"Resize the memory buffer of a ctypes instance"
},
#ifdef CTYPES_UNICODE
#ifdef CTYPES_UNICODE
{
"set_conversion_mode"
,
set_conversion_mode
,
METH_VARARGS
,
set_conversion_mode_doc
},
{
"set_conversion_mode"
,
set_conversion_mode
,
METH_VARARGS
,
set_conversion_mode_doc
},
...
...
Modules/_ctypes/ctypes.h
Dosyayı görüntüle @
2e75c450
...
@@ -235,6 +235,14 @@ typedef struct {
...
@@ -235,6 +235,14 @@ typedef struct {
PyObject
*
restype
;
/* CDataObject or NULL */
PyObject
*
restype
;
/* CDataObject or NULL */
PyObject
*
checker
;
PyObject
*
checker
;
int
flags
;
/* calling convention and such */
int
flags
;
/* calling convention and such */
/* pep3118 fields, pointers neeed PyMem_Free */
char
*
format
;
int
ndim
;
Py_ssize_t
*
shape
;
/* Py_ssize_t *strides; */
/* unused in ctypes */
/* Py_ssize_t *suboffsets; */
/* unused in ctypes */
}
StgDictObject
;
}
StgDictObject
;
/****************************************************************
/****************************************************************
...
@@ -415,6 +423,7 @@ extern void *MallocClosure(void);
...
@@ -415,6 +423,7 @@ extern void *MallocClosure(void);
extern
void
_AddTraceback
(
char
*
,
char
*
,
int
);
extern
void
_AddTraceback
(
char
*
,
char
*
,
int
);
extern
PyObject
*
CData_FromBaseObj
(
PyObject
*
type
,
PyObject
*
base
,
Py_ssize_t
index
,
char
*
adr
);
extern
PyObject
*
CData_FromBaseObj
(
PyObject
*
type
,
PyObject
*
base
,
Py_ssize_t
index
,
char
*
adr
);
extern
char
*
alloc_format_string
(
const
char
*
prefix
,
const
char
*
suffix
);
/* XXX better name needed! */
/* XXX better name needed! */
extern
int
IsSimpleSubType
(
PyObject
*
obj
);
extern
int
IsSimpleSubType
(
PyObject
*
obj
);
...
...
Modules/_ctypes/stgdict.c
Dosyayı görüntüle @
2e75c450
...
@@ -6,6 +6,7 @@
...
@@ -6,6 +6,7 @@
#include <ffi.h>
#include <ffi.h>
#ifdef MS_WIN32
#ifdef MS_WIN32
#include <windows.h>
#include <windows.h>
#include <malloc.h>
#endif
#endif
#include "ctypes.h"
#include "ctypes.h"
...
@@ -24,6 +25,9 @@ StgDict_init(StgDictObject *self, PyObject *args, PyObject *kwds)
...
@@ -24,6 +25,9 @@ StgDict_init(StgDictObject *self, PyObject *args, PyObject *kwds)
{
{
if
(
PyDict_Type
.
tp_init
((
PyObject
*
)
self
,
args
,
kwds
)
<
0
)
if
(
PyDict_Type
.
tp_init
((
PyObject
*
)
self
,
args
,
kwds
)
<
0
)
return
-
1
;
return
-
1
;
self
->
format
=
NULL
;
self
->
ndim
=
0
;
self
->
shape
=
NULL
;
return
0
;
return
0
;
}
}
...
@@ -42,6 +46,8 @@ static void
...
@@ -42,6 +46,8 @@ static void
StgDict_dealloc
(
StgDictObject
*
self
)
StgDict_dealloc
(
StgDictObject
*
self
)
{
{
StgDict_clear
(
self
);
StgDict_clear
(
self
);
PyMem_Free
(
self
->
format
);
PyMem_Free
(
self
->
shape
);
PyMem_Free
(
self
->
ffi_type_pointer
.
elements
);
PyMem_Free
(
self
->
ffi_type_pointer
.
elements
);
PyDict_Type
.
tp_dealloc
((
PyObject
*
)
self
);
PyDict_Type
.
tp_dealloc
((
PyObject
*
)
self
);
}
}
...
@@ -54,6 +60,10 @@ StgDict_clone(StgDictObject *dst, StgDictObject *src)
...
@@ -54,6 +60,10 @@ StgDict_clone(StgDictObject *dst, StgDictObject *src)
StgDict_clear
(
dst
);
StgDict_clear
(
dst
);
PyMem_Free
(
dst
->
ffi_type_pointer
.
elements
);
PyMem_Free
(
dst
->
ffi_type_pointer
.
elements
);
PyMem_Free
(
dst
->
format
);
dst
->
format
=
NULL
;
PyMem_Free
(
dst
->
shape
);
dst
->
shape
=
NULL
;
dst
->
ffi_type_pointer
.
elements
=
NULL
;
dst
->
ffi_type_pointer
.
elements
=
NULL
;
d
=
(
char
*
)
dst
;
d
=
(
char
*
)
dst
;
...
@@ -68,6 +78,20 @@ StgDict_clone(StgDictObject *dst, StgDictObject *src)
...
@@ -68,6 +78,20 @@ StgDict_clone(StgDictObject *dst, StgDictObject *src)
Py_XINCREF
(
dst
->
restype
);
Py_XINCREF
(
dst
->
restype
);
Py_XINCREF
(
dst
->
checker
);
Py_XINCREF
(
dst
->
checker
);
if
(
src
->
format
)
{
dst
->
format
=
PyMem_Malloc
(
strlen
(
src
->
format
)
+
1
);
if
(
dst
->
format
==
NULL
)
return
-
1
;
strcpy
(
dst
->
format
,
src
->
format
);
}
if
(
src
->
shape
)
{
dst
->
shape
=
PyMem_Malloc
(
sizeof
(
Py_ssize_t
)
*
src
->
ndim
);
if
(
dst
->
shape
==
NULL
)
return
-
1
;
memcpy
(
dst
->
shape
,
src
->
shape
,
sizeof
(
Py_ssize_t
)
*
src
->
ndim
);
}
if
(
src
->
ffi_type_pointer
.
elements
==
NULL
)
if
(
src
->
ffi_type_pointer
.
elements
==
NULL
)
return
0
;
return
0
;
size
=
sizeof
(
ffi_type
*
)
*
(
src
->
length
+
1
);
size
=
sizeof
(
ffi_type
*
)
*
(
src
->
length
+
1
);
...
@@ -349,6 +373,11 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
...
@@ -349,6 +373,11 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
return
-
1
;
return
-
1
;
}
}
if
(
stgdict
->
format
)
{
PyMem_Free
(
stgdict
->
format
);
stgdict
->
format
=
NULL
;
}
if
(
stgdict
->
ffi_type_pointer
.
elements
)
if
(
stgdict
->
ffi_type_pointer
.
elements
)
PyMem_Free
(
stgdict
->
ffi_type_pointer
.
elements
);
PyMem_Free
(
stgdict
->
ffi_type_pointer
.
elements
);
...
@@ -387,6 +416,15 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
...
@@ -387,6 +416,15 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
ffi_ofs
=
0
;
ffi_ofs
=
0
;
}
}
if
(
isStruct
&&
!
isPacked
)
{
stgdict
->
format
=
alloc_format_string
(
NULL
,
"T{"
);
}
else
{
/* PEP3118 doesn't support union, or packed structures (well,
only standard packing, but we dont support the pep for
that). Use 'B' for bytes. */
stgdict
->
format
=
alloc_format_string
(
NULL
,
"B"
);
}
#define realdict ((PyObject *)&stgdict->dict)
#define realdict ((PyObject *)&stgdict->dict)
for
(
i
=
0
;
i
<
len
;
++
i
)
{
for
(
i
=
0
;
i
<
len
;
++
i
)
{
PyObject
*
name
=
NULL
,
*
desc
=
NULL
;
PyObject
*
name
=
NULL
,
*
desc
=
NULL
;
...
@@ -451,6 +489,24 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
...
@@ -451,6 +489,24 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
}
}
}
else
}
else
bitsize
=
0
;
bitsize
=
0
;
if
(
isStruct
&&
!
isPacked
)
{
char
*
fieldfmt
=
dict
->
format
?
dict
->
format
:
"B"
;
char
*
fieldname
=
PyString_AsString
(
name
);
char
*
ptr
;
Py_ssize_t
len
=
strlen
(
fieldname
)
+
strlen
(
fieldfmt
);
char
*
buf
=
alloca
(
len
+
2
+
1
);
sprintf
(
buf
,
"%s:%s:"
,
fieldfmt
,
fieldname
);
ptr
=
stgdict
->
format
;
stgdict
->
format
=
alloc_format_string
(
stgdict
->
format
,
buf
);
PyMem_Free
(
ptr
);
if
(
stgdict
->
format
==
NULL
)
{
Py_DECREF
(
pair
);
return
-
1
;
}
}
if
(
isStruct
)
{
if
(
isStruct
)
{
prop
=
CField_FromDesc
(
desc
,
i
,
prop
=
CField_FromDesc
(
desc
,
i
,
&
field_size
,
bitsize
,
&
bitofs
,
&
field_size
,
bitsize
,
&
bitofs
,
...
@@ -481,6 +537,13 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
...
@@ -481,6 +537,13 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
Py_DECREF
(
prop
);
Py_DECREF
(
prop
);
}
}
#undef realdict
#undef realdict
if
(
isStruct
&&
!
isPacked
)
{
stgdict
->
format
=
alloc_format_string
(
stgdict
->
format
,
"}"
);
if
(
stgdict
->
format
==
NULL
)
return
-
1
;
}
if
(
!
isStruct
)
if
(
!
isStruct
)
size
=
union_size
;
size
=
union_size
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment