Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
b5bc537c
Commit
b5bc537c
authored
Oct 27, 2006
by
Martin v. Löwis
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Patch #1549049: Rewrite type conversion in structmember.
Fixes #1545696 and #1566140. Will backport to 2.5.
parent
efb57072
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
296 additions
and
61 deletions
+296
-61
Lib/test/test_structmembers.py
Lib/test/test_structmembers.py
+80
-0
Misc/ACKS
Misc/ACKS
+1
-0
Misc/NEWS
Misc/NEWS
+3
-0
Modules/_testcapimodule.c
Modules/_testcapimodule.c
+121
-8
Python/structmember.c
Python/structmember.c
+91
-53
No files found.
Lib/test/test_structmembers.py
0 → 100644
View file @
b5bc537c
from
_testcapi
import
test_structmembersType
,
\
CHAR_MAX
,
CHAR_MIN
,
UCHAR_MAX
,
\
SHRT_MAX
,
SHRT_MIN
,
USHRT_MAX
,
\
INT_MAX
,
INT_MIN
,
UINT_MAX
,
\
LONG_MAX
,
LONG_MIN
,
ULONG_MAX
import
warnings
,
exceptions
,
unittest
,
test
.
test_warnings
from
test
import
test_support
ts
=
test_structmembersType
(
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9.99999
,
10.1010101010
)
class
ReadWriteTests
(
unittest
.
TestCase
):
def
test_types
(
self
):
ts
.
T_BYTE
=
CHAR_MAX
self
.
assertEquals
(
ts
.
T_BYTE
,
CHAR_MAX
)
ts
.
T_BYTE
=
CHAR_MIN
self
.
assertEquals
(
ts
.
T_BYTE
,
CHAR_MIN
)
ts
.
T_UBYTE
=
UCHAR_MAX
self
.
assertEquals
(
ts
.
T_UBYTE
,
UCHAR_MAX
)
ts
.
T_SHORT
=
SHRT_MAX
self
.
assertEquals
(
ts
.
T_SHORT
,
SHRT_MAX
)
ts
.
T_SHORT
=
SHRT_MIN
self
.
assertEquals
(
ts
.
T_SHORT
,
SHRT_MIN
)
ts
.
T_USHORT
=
USHRT_MAX
self
.
assertEquals
(
ts
.
T_USHORT
,
USHRT_MAX
)
ts
.
T_INT
=
INT_MAX
self
.
assertEquals
(
ts
.
T_INT
,
INT_MAX
)
ts
.
T_INT
=
INT_MIN
self
.
assertEquals
(
ts
.
T_INT
,
INT_MIN
)
ts
.
T_UINT
=
UINT_MAX
self
.
assertEquals
(
ts
.
T_UINT
,
UINT_MAX
)
ts
.
T_LONG
=
LONG_MAX
self
.
assertEquals
(
ts
.
T_LONG
,
LONG_MAX
)
ts
.
T_LONG
=
LONG_MIN
self
.
assertEquals
(
ts
.
T_LONG
,
LONG_MIN
)
ts
.
T_ULONG
=
ULONG_MAX
self
.
assertEquals
(
ts
.
T_ULONG
,
ULONG_MAX
)
class
TestWarnings
(
test
.
test_warnings
.
TestModule
):
def
has_warned
(
self
):
self
.
assertEqual
(
test
.
test_warnings
.
msg
.
category
,
exceptions
.
RuntimeWarning
.
__name__
)
def
test_byte_max
(
self
):
ts
.
T_BYTE
=
CHAR_MAX
+
1
self
.
has_warned
()
def
test_byte_min
(
self
):
ts
.
T_BYTE
=
CHAR_MIN
-
1
self
.
has_warned
()
def
test_ubyte_max
(
self
):
ts
.
T_UBYTE
=
UCHAR_MAX
+
1
self
.
has_warned
()
def
test_short_max
(
self
):
ts
.
T_SHORT
=
SHRT_MAX
+
1
self
.
has_warned
()
def
test_short_min
(
self
):
ts
.
T_SHORT
=
SHRT_MIN
-
1
self
.
has_warned
()
def
test_ushort_max
(
self
):
ts
.
T_USHORT
=
USHRT_MAX
+
1
self
.
has_warned
()
def
test_main
(
verbose
=
None
):
test_support
.
run_unittest
(
ReadWriteTests
,
TestWarnings
)
if
__name__
==
"__main__"
:
test_main
(
verbose
=
True
)
Misc/ACKS
View file @
b5bc537c
...
...
@@ -633,6 +633,7 @@ Stephen Turner
Bill Tutt
Doobee R. Tzeck
Lionel Ulmer
Roger Upole
Michael Urman
Hector Urtubia
Dmitry Vasiliev
...
...
Misc/NEWS
View file @
b5bc537c
...
...
@@ -12,6 +12,9 @@ What's New in Python 2.6 alpha 1?
Core and builtins
-----------------
- Patch #1549049: Support long values in structmember, issue warnings
if the assigned value for structmember fields gets truncated.
- Update the peephole optimizer to remove more dead code (jumps after returns)
and inline unconditional jumps to returns.
...
...
Modules/_testcapimodule.c
View file @
b5bc537c
...
...
@@ -6,6 +6,8 @@
*/
#include "Python.h"
#include <values.h>
#include "structmember.h"
#ifdef WITH_THREAD
#include "pythread.h"
...
...
@@ -35,13 +37,13 @@ raiseTestError(const char* test_name, const char* msg)
platforms have these hardcoded. Better safe than sorry.
*/
static
PyObject
*
sizeof_error
(
const
char
*
fatname
,
const
char
*
typ
e
name
,
sizeof_error
(
const
char
*
fatname
,
const
char
*
typname
,
int
expected
,
int
got
)
{
char
buf
[
1024
];
PyOS_snprintf
(
buf
,
sizeof
(
buf
),
"%.200s #define == %d but sizeof(%.200s) == %d"
,
fatname
,
expected
,
typ
e
name
,
got
);
fatname
,
expected
,
typname
,
got
);
PyErr_SetString
(
TestError
,
buf
);
return
(
PyObject
*
)
NULL
;
}
...
...
@@ -615,7 +617,7 @@ _make_call(void *callable)
{
PyObject
*
rc
;
PyGILState_STATE
s
=
PyGILState_Ensure
();
rc
=
PyObject_CallFunction
(
callable
,
""
);
rc
=
PyObject_CallFunction
(
(
PyObject
*
)
callable
,
""
);
Py_XDECREF
(
rc
);
PyGILState_Release
(
s
);
}
...
...
@@ -756,6 +758,105 @@ static PyMethodDef TestMethods[] = {
#define AddSym(d, n, f, v) {PyObject *o = f(v); PyDict_SetItemString(d, n, o); Py_DECREF(o);}
typedef
struct
{
char
byte_member
;
unsigned
char
ubyte_member
;
short
short_member
;
unsigned
short
ushort_member
;
int
int_member
;
unsigned
int
uint_member
;
long
long_member
;
unsigned
long
ulong_member
;
float
float_member
;
double
double_member
;
}
all_structmembers
;
typedef
struct
{
PyObject_HEAD
all_structmembers
structmembers
;
}
test_structmembers
;
static
struct
PyMemberDef
test_members
[]
=
{
{
"T_BYTE"
,
T_BYTE
,
offsetof
(
test_structmembers
,
structmembers
.
byte_member
),
0
,
NULL
},
{
"T_UBYTE"
,
T_UBYTE
,
offsetof
(
test_structmembers
,
structmembers
.
ubyte_member
),
0
,
NULL
},
{
"T_SHORT"
,
T_SHORT
,
offsetof
(
test_structmembers
,
structmembers
.
short_member
),
0
,
NULL
},
{
"T_USHORT"
,
T_USHORT
,
offsetof
(
test_structmembers
,
structmembers
.
ushort_member
),
0
,
NULL
},
{
"T_INT"
,
T_INT
,
offsetof
(
test_structmembers
,
structmembers
.
int_member
),
0
,
NULL
},
{
"T_UINT"
,
T_UINT
,
offsetof
(
test_structmembers
,
structmembers
.
uint_member
),
0
,
NULL
},
{
"T_LONG"
,
T_LONG
,
offsetof
(
test_structmembers
,
structmembers
.
long_member
),
0
,
NULL
},
{
"T_ULONG"
,
T_ULONG
,
offsetof
(
test_structmembers
,
structmembers
.
ulong_member
),
0
,
NULL
},
{
"T_FLOAT"
,
T_FLOAT
,
offsetof
(
test_structmembers
,
structmembers
.
float_member
),
0
,
NULL
},
{
"T_DOUBLE"
,
T_DOUBLE
,
offsetof
(
test_structmembers
,
structmembers
.
double_member
),
0
,
NULL
},
{
NULL
}
};
static
PyObject
*
test_structmembers_new
(
PyTypeObject
*
type
,
PyObject
*
args
,
PyObject
*
kwargs
){
static
char
*
keywords
[]
=
{
"T_BYTE"
,
"T_UBYTE"
,
"T_SHORT"
,
"T_USHORT"
,
"T_INT"
,
"T_UINT"
,
"T_LONG"
,
"T_ULONG"
,
"T_FLOAT"
,
"T_DOUBLE"
,
NULL
};
test_structmembers
*
ob
=
PyObject_New
(
test_structmembers
,
type
);
if
(
ob
==
NULL
)
return
NULL
;
memset
(
&
ob
->
structmembers
,
0
,
sizeof
(
all_structmembers
));
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kwargs
,
"|bBhHiIlkfd"
,
keywords
,
&
ob
->
structmembers
.
byte_member
,
&
ob
->
structmembers
.
ubyte_member
,
&
ob
->
structmembers
.
short_member
,
&
ob
->
structmembers
.
ushort_member
,
&
ob
->
structmembers
.
int_member
,
&
ob
->
structmembers
.
uint_member
,
&
ob
->
structmembers
.
long_member
,
&
ob
->
structmembers
.
ulong_member
,
&
ob
->
structmembers
.
float_member
,
&
ob
->
structmembers
.
double_member
)){
Py_DECREF
(
ob
);
return
NULL
;
}
return
(
PyObject
*
)
ob
;
}
static
void
test_structmembers_free
(
PyObject
*
ob
){
PyObject_FREE
(
ob
);
}
static
PyTypeObject
test_structmembersType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
"test_structmembersType"
,
sizeof
(
test_structmembers
),
/* tp_basicsize */
0
,
/* tp_itemsize */
test_structmembers_free
,
/* destructor tp_dealloc */
0
,
/* tp_print */
0
,
/* tp_getattr */
0
,
/* tp_setattr */
0
,
/* tp_compare */
0
,
/* tp_repr */
0
,
/* tp_as_number */
0
,
/* tp_as_sequence */
0
,
/* tp_as_mapping */
0
,
/* tp_hash */
0
,
/* tp_call */
0
,
/* tp_str */
PyObject_GenericGetAttr
,
PyObject_GenericSetAttr
,
0
,
/* tp_as_buffer */
0
,
/* tp_flags */
"Type containing all structmember types"
,
0
,
/* traverseproc tp_traverse */
0
,
/* tp_clear */
0
,
/* tp_richcompare */
0
,
/* tp_weaklistoffset */
0
,
/* tp_iter */
0
,
/* tp_iternext */
0
,
/* tp_methods */
test_members
,
/* tp_members */
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
test_structmembers_new
,
/* tp_new */
};
PyMODINIT_FUNC
init_testcapi
(
void
)
{
...
...
@@ -765,16 +866,28 @@ init_testcapi(void)
if
(
m
==
NULL
)
return
;
test_structmembersType
.
ob_type
=&
PyType_Type
;
Py_INCREF
(
&
test_structmembersType
);
PyModule_AddObject
(
m
,
"test_structmembersType"
,
(
PyObject
*
)
&
test_structmembersType
);
PyModule_AddObject
(
m
,
"CHAR_MAX"
,
PyInt_FromLong
(
CHAR_MAX
));
PyModule_AddObject
(
m
,
"CHAR_MIN"
,
PyInt_FromLong
(
CHAR_MIN
));
PyModule_AddObject
(
m
,
"UCHAR_MAX"
,
PyInt_FromLong
(
UCHAR_MAX
));
PyModule_AddObject
(
m
,
"SHRT_MAX"
,
PyInt_FromLong
(
SHRT_MAX
));
PyModule_AddObject
(
m
,
"SHRT_MIN"
,
PyInt_FromLong
(
SHRT_MIN
));
PyModule_AddObject
(
m
,
"USHRT_MAX"
,
PyInt_FromLong
(
USHRT_MAX
));
PyModule_AddObject
(
m
,
"INT_MAX"
,
PyLong_FromLong
(
INT_MAX
));
PyModule_AddObject
(
m
,
"INT_MIN"
,
PyLong_FromLong
(
INT_MIN
));
PyModule_AddObject
(
m
,
"UINT_MAX"
,
PyLong_FromUnsignedLong
(
UINT_MAX
));
PyModule_AddObject
(
m
,
"ULONG_MAX"
,
PyLong_FromUnsignedLong
(
ULONG_MAX
));
PyModule_AddObject
(
m
,
"INT_MIN"
,
PyInt_FromLong
(
INT_MIN
));
PyModule_AddObject
(
m
,
"LONG_MIN"
,
PyInt_FromLong
(
LONG_MIN
));
PyModule_AddObject
(
m
,
"PY_SSIZE_T_MIN"
,
PyInt_FromSsize_t
(
PY_SSIZE_T_MIN
));
PyModule_AddObject
(
m
,
"INT_MAX"
,
PyInt_FromLong
(
INT_MAX
));
PyModule_AddObject
(
m
,
"LONG_MAX"
,
PyInt_FromLong
(
LONG_MAX
));
PyModule_AddObject
(
m
,
"LONG_MIN"
,
PyInt_FromLong
(
LONG_MIN
));
PyModule_AddObject
(
m
,
"ULONG_MAX"
,
PyLong_FromUnsignedLong
(
ULONG_MAX
));
PyModule_AddObject
(
m
,
"FLT_MAX"
,
PyFloat_FromDouble
(
FLT_MAX
));
PyModule_AddObject
(
m
,
"FLT_MIN"
,
PyFloat_FromDouble
(
FLT_MIN
));
PyModule_AddObject
(
m
,
"DBL_MAX"
,
PyFloat_FromDouble
(
DBL_MAX
));
PyModule_AddObject
(
m
,
"DBL_MIN"
,
PyFloat_FromDouble
(
DBL_MIN
));
PyModule_AddObject
(
m
,
"PY_SSIZE_T_MAX"
,
PyInt_FromSsize_t
(
PY_SSIZE_T_MAX
));
PyModule_AddObject
(
m
,
"PY_SSIZE_T_MIN"
,
PyInt_FromSsize_t
(
PY_SSIZE_T_MIN
));
TestError
=
PyErr_NewException
(
"_testcapi.error"
,
NULL
,
NULL
);
Py_INCREF
(
TestError
);
...
...
Python/structmember.c
View file @
b5bc537c
...
...
@@ -62,29 +62,28 @@ PyMember_GetOne(const char *addr, PyMemberDef *l)
addr
+=
l
->
offset
;
switch
(
l
->
type
)
{
case
T_BYTE
:
v
=
PyInt_FromLong
(
(
long
)
(((
*
(
char
*
)
addr
&
0xff
)
^
0x80
)
-
0x80
));
v
=
PyInt_FromLong
(
*
(
char
*
)
addr
);
break
;
case
T_UBYTE
:
v
=
Py
Int_FromLong
((
long
)
*
(
char
*
)
addr
&
0xff
);
v
=
Py
Long_FromUnsignedLong
(
*
(
unsigned
char
*
)
addr
);
break
;
case
T_SHORT
:
v
=
PyInt_FromLong
(
(
long
)
*
(
short
*
)
addr
);
v
=
PyInt_FromLong
(
*
(
short
*
)
addr
);
break
;
case
T_USHORT
:
v
=
Py
Int_FromLong
((
long
)
*
(
unsigned
short
*
)
addr
);
v
=
Py
Long_FromUnsignedLong
(
*
(
unsigned
short
*
)
addr
);
break
;
case
T_INT
:
v
=
PyInt_FromLong
(
(
long
)
*
(
int
*
)
addr
);
v
=
PyInt_FromLong
(
*
(
int
*
)
addr
);
break
;
case
T_UINT
:
v
=
Py
Int_FromLong
((
long
)
*
(
unsigned
int
*
)
addr
);
v
=
Py
Long_FromUnsignedLong
(
*
(
unsigned
int
*
)
addr
);
break
;
case
T_LONG
:
v
=
PyInt_FromLong
(
*
(
long
*
)
addr
);
break
;
case
T_ULONG
:
v
=
PyLong_From
Double
((
double
)
*
(
unsigned
long
*
)
addr
);
v
=
PyLong_From
UnsignedLong
(
*
(
unsigned
long
*
)
addr
);
break
;
case
T_FLOAT
:
v
=
PyFloat_FromDouble
((
double
)
*
(
float
*
)
addr
);
...
...
@@ -175,68 +174,107 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
}
addr
+=
l
->
offset
;
switch
(
l
->
type
)
{
case
T_BYTE
:
case
T_UBYTE
:
if
(
!
PyInt_Check
(
v
))
{
PyErr_BadArgument
();
case
T_BYTE
:
{
long
long_val
;
long_val
=
PyInt_AsLong
(
v
);
if
((
long_val
==
-
1
)
&&
PyErr_Occurred
())
return
-
1
;
}
*
(
char
*
)
addr
=
(
char
)
PyInt_AsLong
(
v
);
/* XXX: For compatibility, only warn about truncations
for now. */
if
((
long_val
>
CHAR_MAX
)
||
(
long_val
<
CHAR_MIN
))
PyErr_Warn
(
PyExc_RuntimeWarning
,
"Truncation of value to char"
);
*
(
char
*
)
addr
=
(
char
)
long_val
;
break
;
case
T_SHORT
:
case
T_USHORT
:
if
(
!
PyInt_Check
(
v
))
{
PyErr_BadArgument
();
return
-
1
;
}
*
(
short
*
)
addr
=
(
short
)
PyInt_AsLong
(
v
);
case
T_UBYTE
:{
long
long_val
;
long_val
=
PyInt_AsLong
(
v
);
if
((
long_val
==
-
1
)
&&
PyErr_Occurred
())
return
-
1
;
if
((
long_val
>
UCHAR_MAX
)
||
(
long_val
<
0
))
PyErr_Warn
(
PyExc_RuntimeWarning
,
"Truncation of value to unsigned char"
);
*
(
unsigned
char
*
)
addr
=
(
unsigned
char
)
long_val
;
break
;
case
T_UINT
:
case
T_INT
:
if
(
!
PyInt_Check
(
v
))
{
PyErr_BadArgument
();
}
case
T_SHORT
:{
long
long_val
;
long_val
=
PyInt_AsLong
(
v
);
if
((
long_val
==
-
1
)
&&
PyErr_Occurred
())
return
-
1
;
if
((
long_val
>
SHRT_MAX
)
||
(
long_val
<
SHRT_MIN
))
PyErr_Warn
(
PyExc_RuntimeWarning
,
"Truncation of value to short"
);
*
(
short
*
)
addr
=
(
short
)
long_val
;
break
;
}
*
(
int
*
)
addr
=
(
int
)
PyInt_AsLong
(
v
);
case
T_USHORT
:{
long
long_val
;
long_val
=
PyInt_AsLong
(
v
);
if
((
long_val
==
-
1
)
&&
PyErr_Occurred
())
return
-
1
;
if
((
long_val
>
USHRT_MAX
)
||
(
long_val
<
0
))
PyErr_Warn
(
PyExc_RuntimeWarning
,
"Truncation of value to unsigned short"
);
*
(
unsigned
short
*
)
addr
=
(
unsigned
short
)
long_val
;
break
;
case
T_LONG
:
if
(
!
PyInt_Check
(
v
))
{
PyErr_BadArgument
();
}
case
T_INT
:{
long
long_val
;
long_val
=
PyInt_AsLong
(
v
);
if
((
long_val
==
-
1
)
&&
PyErr_Occurred
())
return
-
1
;
if
((
long_val
>
INT_MAX
)
||
(
long_val
<
INT_MIN
))
PyErr_Warn
(
PyExc_RuntimeWarning
,
"Truncation of value to int"
);
*
(
int
*
)
addr
=
(
int
)
long_val
;
break
;
}
case
T_UINT
:{
unsigned
long
ulong_val
;
ulong_val
=
PyLong_AsUnsignedLong
(
v
);
if
((
ulong_val
==
(
unsigned
int
)
-
1
)
&&
PyErr_Occurred
())
{
/* XXX: For compatibility, accept negative int values
as well. */
PyErr_Clear
();
ulong_val
=
PyLong_AsLong
(
v
);
if
((
ulong_val
==
(
unsigned
int
)
-
1
)
&&
PyErr_Occurred
())
return
-
1
;
PyErr_Warn
(
PyExc_RuntimeWarning
,
"Writing negative value into unsigned field"
);
}
*
(
long
*
)
addr
=
PyInt_AsLong
(
v
);
if
(
ulong_val
>
UINT_MAX
)
PyErr_Warn
(
PyExc_RuntimeWarning
,
"Truncation of value to unsigned int"
);
*
(
unsigned
int
*
)
addr
=
(
unsigned
int
)
ulong_val
;
break
;
case
T_ULONG
:
if
(
PyInt_Check
(
v
))
*
(
long
*
)
addr
=
PyInt_AsLong
(
v
);
else
if
(
PyLong_Check
(
v
))
*
(
long
*
)
addr
=
PyLong_AsLong
(
v
);
else
{
PyErr_BadArgument
();
}
case
T_LONG
:{
*
(
long
*
)
addr
=
PyLong_AsLong
(
v
);
if
((
*
(
long
*
)
addr
==
-
1
)
&&
PyErr_Occurred
())
return
-
1
;
break
;
}
case
T_ULONG
:{
*
(
unsigned
long
*
)
addr
=
PyLong_AsUnsignedLong
(
v
);
if
((
*
(
unsigned
long
*
)
addr
==
(
unsigned
long
)
-
1
)
&&
PyErr_Occurred
())
{
/* XXX: For compatibility, accept negative int values
as well. */
PyErr_Clear
();
*
(
unsigned
long
*
)
addr
=
PyLong_AsLong
(
v
);
if
((
*
(
unsigned
long
*
)
addr
==
(
unsigned
int
)
-
1
)
&&
PyErr_Occurred
())
return
-
1
;
PyErr_Warn
(
PyExc_RuntimeWarning
,
"Writing negative value into unsigned field"
);
}
break
;
case
T_FLOAT
:
if
(
PyInt_Check
(
v
))
*
(
float
*
)
addr
=
(
float
)
PyInt_AsLong
(
v
);
else
if
(
PyFloat_Check
(
v
))
*
(
float
*
)
addr
=
(
float
)
PyFloat_AsDouble
(
v
);
else
{
PyErr_BadArgument
();
return
-
1
;
}
case
T_FLOAT
:{
double
double_val
;
double_val
=
PyFloat_AsDouble
(
v
);
if
((
double_val
==
-
1
)
&&
PyErr_Occurred
())
return
-
1
;
*
(
float
*
)
addr
=
(
float
)
double_val
;
break
;
}
case
T_DOUBLE
:
if
(
PyInt_Check
(
v
))
*
(
double
*
)
addr
=
(
double
)
PyInt_AsLong
(
v
);
else
if
(
PyFloat_Check
(
v
))
*
(
double
*
)
addr
=
PyFloat_AsDouble
(
v
);
else
{
PyErr_BadArgument
();
*
(
double
*
)
addr
=
PyFloat_AsDouble
(
v
);
if
((
*
(
double
*
)
addr
==
-
1
)
&&
PyErr_Occurred
())
return
-
1
;
}
break
;
case
T_OBJECT
:
case
T_OBJECT_EX
:
...
...
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