mirror of
https://github.com/python/cpython.git
synced 2026-01-06 15:32:22 +00:00
bpo-32787: Better error handling in ctypes. (#3727)
* bpo-31572: Get rid of PyObject_HasAttrString() in ctypes. * Fix error handling for _pack_. * Don't silence errors when look up in a dict. * Use _PyObject_LookupAttrId(). * More changes.
This commit is contained in:
parent
476b113ed8
commit
398bd27967
5 changed files with 247 additions and 112 deletions
|
|
@ -236,7 +236,7 @@ PyObject *
|
|||
PyDict_GetItemProxy(PyObject *dict, PyObject *key)
|
||||
{
|
||||
PyObject *result;
|
||||
PyObject *item = PyDict_GetItem(dict, key);
|
||||
PyObject *item = PyDict_GetItemWithError(dict, key);
|
||||
|
||||
if (item == NULL)
|
||||
return NULL;
|
||||
|
|
@ -426,6 +426,8 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt
|
|||
PyTypeObject *result;
|
||||
PyObject *fields;
|
||||
StgDictObject *dict;
|
||||
_Py_IDENTIFIER(_abstract_);
|
||||
_Py_IDENTIFIER(_fields_);
|
||||
|
||||
/* create the new instance (which is a class,
|
||||
since we are a metatype!) */
|
||||
|
|
@ -434,8 +436,12 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt
|
|||
return NULL;
|
||||
|
||||
/* keep this for bw compatibility */
|
||||
if (PyDict_GetItemString(result->tp_dict, "_abstract_"))
|
||||
if (_PyDict_GetItemIdWithError(result->tp_dict, &PyId__abstract_))
|
||||
return (PyObject *)result;
|
||||
if (PyErr_Occurred()) {
|
||||
Py_DECREF(result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dict = (StgDictObject *)_PyObject_CallNoArg((PyObject *)&PyCStgDict_Type);
|
||||
if (!dict) {
|
||||
|
|
@ -458,8 +464,19 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt
|
|||
|
||||
dict->paramfunc = StructUnionType_paramfunc;
|
||||
|
||||
fields = PyDict_GetItemString((PyObject *)dict, "_fields_");
|
||||
if (!fields) {
|
||||
fields = _PyDict_GetItemIdWithError((PyObject *)dict, &PyId__fields_);
|
||||
if (fields) {
|
||||
if (_PyObject_SetAttrId((PyObject *)result, &PyId__fields_, fields) < 0) {
|
||||
Py_DECREF(result);
|
||||
return NULL;
|
||||
}
|
||||
return (PyObject *)result;
|
||||
}
|
||||
else if (PyErr_Occurred()) {
|
||||
Py_DECREF(result);
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base);
|
||||
|
||||
if (basedict == NULL)
|
||||
|
|
@ -473,12 +490,6 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt
|
|||
basedict->flags |= DICTFLAG_FINAL; /* set the 'final' flag in the baseclass dict */
|
||||
return (PyObject *)result;
|
||||
}
|
||||
|
||||
if (-1 == PyObject_SetAttrString((PyObject *)result, "_fields_", fields)) {
|
||||
Py_DECREF(result);
|
||||
return NULL;
|
||||
}
|
||||
return (PyObject *)result;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
|
|
@ -693,6 +704,7 @@ static const char from_param_doc[] =
|
|||
static PyObject *
|
||||
CDataType_from_param(PyObject *type, PyObject *value)
|
||||
{
|
||||
_Py_IDENTIFIER(_as_parameter_);
|
||||
PyObject *as_parameter;
|
||||
int res = PyObject_IsInstance(value, type);
|
||||
if (res == -1)
|
||||
|
|
@ -726,7 +738,9 @@ CDataType_from_param(PyObject *type, PyObject *value)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
|
||||
if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (as_parameter) {
|
||||
value = CDataType_from_param(type, as_parameter);
|
||||
Py_DECREF(as_parameter);
|
||||
|
|
@ -961,6 +975,7 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||
StgDictObject *stgdict;
|
||||
PyObject *proto;
|
||||
PyObject *typedict;
|
||||
_Py_IDENTIFIER(_type_);
|
||||
|
||||
typedict = PyTuple_GetItem(args, 2);
|
||||
if (!typedict)
|
||||
|
|
@ -980,15 +995,15 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||
stgdict->paramfunc = PyCPointerType_paramfunc;
|
||||
stgdict->flags |= TYPEFLAG_ISPOINTER;
|
||||
|
||||
proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
|
||||
if (proto && -1 == PyCPointerType_SetProto(stgdict, proto)) {
|
||||
Py_DECREF((PyObject *)stgdict);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
proto = _PyDict_GetItemIdWithError(typedict, &PyId__type_); /* Borrowed ref */
|
||||
if (proto) {
|
||||
StgDictObject *itemdict = PyType_stgdict(proto);
|
||||
StgDictObject *itemdict;
|
||||
const char *current_format;
|
||||
if (-1 == PyCPointerType_SetProto(stgdict, proto)) {
|
||||
Py_DECREF((PyObject *)stgdict);
|
||||
return NULL;
|
||||
}
|
||||
itemdict = PyType_stgdict(proto);
|
||||
/* PyCPointerType_SetProto has verified proto has a stgdict. */
|
||||
assert(itemdict);
|
||||
/* If itemdict->format is NULL, then this is a pointer to an
|
||||
|
|
@ -1009,6 +1024,10 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
else if (PyErr_Occurred()) {
|
||||
Py_DECREF((PyObject *)stgdict);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* create the new instance (which is a class,
|
||||
since we are a metatype!) */
|
||||
|
|
@ -1034,6 +1053,7 @@ static PyObject *
|
|||
PyCPointerType_set_type(PyTypeObject *self, PyObject *type)
|
||||
{
|
||||
StgDictObject *dict;
|
||||
_Py_IDENTIFIER(_type_);
|
||||
|
||||
dict = PyType_stgdict((PyObject *)self);
|
||||
if (!dict) {
|
||||
|
|
@ -1045,7 +1065,7 @@ PyCPointerType_set_type(PyTypeObject *self, PyObject *type)
|
|||
if (-1 == PyCPointerType_SetProto(dict, type))
|
||||
return NULL;
|
||||
|
||||
if (-1 == PyDict_SetItemString((PyObject *)dict, "_type_", type))
|
||||
if (-1 == _PyDict_SetItemId((PyObject *)dict, &PyId__type_, type))
|
||||
return NULL;
|
||||
|
||||
Py_RETURN_NONE;
|
||||
|
|
@ -1386,6 +1406,8 @@ PyCArrayType_paramfunc(CDataObject *self)
|
|||
static PyObject *
|
||||
PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
_Py_IDENTIFIER(_length_);
|
||||
_Py_IDENTIFIER(_type_);
|
||||
PyTypeObject *result;
|
||||
StgDictObject *stgdict;
|
||||
StgDictObject *itemdict;
|
||||
|
|
@ -1404,12 +1426,12 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||
stgdict = NULL;
|
||||
type_attr = NULL;
|
||||
|
||||
length_attr = PyObject_GetAttrString((PyObject *)result, "_length_");
|
||||
if (_PyObject_LookupAttrId((PyObject *)result, &PyId__length_, &length_attr) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (!length_attr) {
|
||||
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
"class must define a '_length_' attribute");
|
||||
}
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
"class must define a '_length_' attribute");
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
|
@ -1437,7 +1459,9 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||
goto error;
|
||||
}
|
||||
|
||||
type_attr = PyObject_GetAttrString((PyObject *)result, "_type_");
|
||||
if (_PyObject_LookupAttrId((PyObject *)result, &PyId__type_, &type_attr) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (!type_attr) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
"class must define a '_type_' attribute");
|
||||
|
|
@ -1580,6 +1604,7 @@ static const char SIMPLE_TYPE_CHARS[] = "cbBhHiIlLdfuzZqQPXOv?g";
|
|||
static PyObject *
|
||||
c_wchar_p_from_param(PyObject *type, PyObject *value)
|
||||
{
|
||||
_Py_IDENTIFIER(_as_parameter_);
|
||||
PyObject *as_parameter;
|
||||
int res;
|
||||
if (value == Py_None) {
|
||||
|
|
@ -1629,7 +1654,9 @@ c_wchar_p_from_param(PyObject *type, PyObject *value)
|
|||
}
|
||||
}
|
||||
|
||||
as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
|
||||
if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (as_parameter) {
|
||||
value = c_wchar_p_from_param(type, as_parameter);
|
||||
Py_DECREF(as_parameter);
|
||||
|
|
@ -1644,6 +1671,7 @@ c_wchar_p_from_param(PyObject *type, PyObject *value)
|
|||
static PyObject *
|
||||
c_char_p_from_param(PyObject *type, PyObject *value)
|
||||
{
|
||||
_Py_IDENTIFIER(_as_parameter_);
|
||||
PyObject *as_parameter;
|
||||
int res;
|
||||
if (value == Py_None) {
|
||||
|
|
@ -1693,7 +1721,9 @@ c_char_p_from_param(PyObject *type, PyObject *value)
|
|||
}
|
||||
}
|
||||
|
||||
as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
|
||||
if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (as_parameter) {
|
||||
value = c_char_p_from_param(type, as_parameter);
|
||||
Py_DECREF(as_parameter);
|
||||
|
|
@ -1708,6 +1738,7 @@ c_char_p_from_param(PyObject *type, PyObject *value)
|
|||
static PyObject *
|
||||
c_void_p_from_param(PyObject *type, PyObject *value)
|
||||
{
|
||||
_Py_IDENTIFIER(_as_parameter_);
|
||||
StgDictObject *stgd;
|
||||
PyObject *as_parameter;
|
||||
int res;
|
||||
|
|
@ -1829,7 +1860,9 @@ c_void_p_from_param(PyObject *type, PyObject *value)
|
|||
}
|
||||
}
|
||||
|
||||
as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
|
||||
if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (as_parameter) {
|
||||
value = c_void_p_from_param(type, as_parameter);
|
||||
Py_DECREF(as_parameter);
|
||||
|
|
@ -1946,6 +1979,7 @@ PyCSimpleType_paramfunc(CDataObject *self)
|
|||
static PyObject *
|
||||
PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
_Py_IDENTIFIER(_type_);
|
||||
PyTypeObject *result;
|
||||
StgDictObject *stgdict;
|
||||
PyObject *proto;
|
||||
|
|
@ -1960,13 +1994,15 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||
if (result == NULL)
|
||||
return NULL;
|
||||
|
||||
proto = PyObject_GetAttrString((PyObject *)result, "_type_"); /* new ref */
|
||||
if (_PyObject_LookupAttrId((PyObject *)result, &PyId__type_, &proto) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (!proto) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
"class must define a '_type_' attribute");
|
||||
error:
|
||||
Py_XDECREF(proto);
|
||||
Py_XDECREF(result);
|
||||
Py_DECREF(result);
|
||||
return NULL;
|
||||
}
|
||||
if (PyUnicode_Check(proto)) {
|
||||
|
|
@ -2128,6 +2164,7 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||
static PyObject *
|
||||
PyCSimpleType_from_param(PyObject *type, PyObject *value)
|
||||
{
|
||||
_Py_IDENTIFIER(_as_parameter_);
|
||||
StgDictObject *dict;
|
||||
const char *fmt;
|
||||
PyCArgObject *parg;
|
||||
|
|
@ -2171,7 +2208,9 @@ PyCSimpleType_from_param(PyObject *type, PyObject *value)
|
|||
PyErr_Clear();
|
||||
Py_DECREF(parg);
|
||||
|
||||
as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
|
||||
if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (as_parameter) {
|
||||
if (Py_EnterRecursiveCall("while processing _as_parameter_")) {
|
||||
Py_DECREF(as_parameter);
|
||||
|
|
@ -2246,6 +2285,7 @@ PyTypeObject PyCSimpleType_Type = {
|
|||
static PyObject *
|
||||
converters_from_argtypes(PyObject *ob)
|
||||
{
|
||||
_Py_IDENTIFIER(from_param);
|
||||
PyObject *converters;
|
||||
Py_ssize_t i;
|
||||
Py_ssize_t nArgs;
|
||||
|
|
@ -2270,22 +2310,22 @@ converters_from_argtypes(PyObject *ob)
|
|||
*/
|
||||
|
||||
for (i = 0; i < nArgs; ++i) {
|
||||
PyObject *cnv;
|
||||
PyObject *tp = PyTuple_GET_ITEM(ob, i);
|
||||
PyObject *cnv = PyObject_GetAttrString(tp, "from_param");
|
||||
if (!cnv)
|
||||
goto argtypes_error_1;
|
||||
if (_PyObject_LookupAttrId(tp, &PyId_from_param, &cnv) <= 0) {
|
||||
Py_DECREF(converters);
|
||||
Py_DECREF(ob);
|
||||
if (!PyErr_Occurred()) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"item %zd in _argtypes_ has no from_param method",
|
||||
i+1);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
PyTuple_SET_ITEM(converters, i, cnv);
|
||||
}
|
||||
Py_DECREF(ob);
|
||||
return converters;
|
||||
|
||||
argtypes_error_1:
|
||||
Py_XDECREF(converters);
|
||||
Py_DECREF(ob);
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"item %zd in _argtypes_ has no from_param method",
|
||||
i+1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -2293,6 +2333,10 @@ make_funcptrtype_dict(StgDictObject *stgdict)
|
|||
{
|
||||
PyObject *ob;
|
||||
PyObject *converters = NULL;
|
||||
_Py_IDENTIFIER(_flags_);
|
||||
_Py_IDENTIFIER(_argtypes_);
|
||||
_Py_IDENTIFIER(_restype_);
|
||||
_Py_IDENTIFIER(_check_retval_);
|
||||
|
||||
stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
|
||||
stgdict->length = 1;
|
||||
|
|
@ -2301,26 +2345,31 @@ make_funcptrtype_dict(StgDictObject *stgdict)
|
|||
stgdict->getfunc = NULL;
|
||||
stgdict->ffi_type_pointer = ffi_type_pointer;
|
||||
|
||||
ob = PyDict_GetItemString((PyObject *)stgdict, "_flags_");
|
||||
ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__flags_);
|
||||
if (!ob || !PyLong_Check(ob)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"class must define _flags_ which must be an integer");
|
||||
if (!PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"class must define _flags_ which must be an integer");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
stgdict->flags = PyLong_AS_LONG(ob) | TYPEFLAG_ISPOINTER;
|
||||
stgdict->flags = PyLong_AsUnsignedLongMask(ob) | TYPEFLAG_ISPOINTER;
|
||||
|
||||
/* _argtypes_ is optional... */
|
||||
ob = PyDict_GetItemString((PyObject *)stgdict, "_argtypes_");
|
||||
ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__argtypes_);
|
||||
if (ob) {
|
||||
converters = converters_from_argtypes(ob);
|
||||
if (!converters)
|
||||
goto error;
|
||||
return -1;
|
||||
Py_INCREF(ob);
|
||||
stgdict->argtypes = ob;
|
||||
stgdict->converters = converters;
|
||||
}
|
||||
else if (PyErr_Occurred()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ob = PyDict_GetItemString((PyObject *)stgdict, "_restype_");
|
||||
ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__restype_);
|
||||
if (ob) {
|
||||
if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
|
|
@ -2329,12 +2378,17 @@ make_funcptrtype_dict(StgDictObject *stgdict)
|
|||
}
|
||||
Py_INCREF(ob);
|
||||
stgdict->restype = ob;
|
||||
stgdict->checker = PyObject_GetAttrString(ob, "_check_retval_");
|
||||
if (stgdict->checker == NULL)
|
||||
PyErr_Clear();
|
||||
if (_PyObject_LookupAttrId(ob, &PyId__check_retval_,
|
||||
&stgdict->checker) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (PyErr_Occurred()) {
|
||||
return -1;
|
||||
}
|
||||
/* XXX later, maybe.
|
||||
ob = PyDict_GetItemString((PyObject *)stgdict, "_errcheck_");
|
||||
ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__errcheck_);
|
||||
if (ob) {
|
||||
if (!PyCallable_Check(ob)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
|
|
@ -2344,13 +2398,11 @@ make_funcptrtype_dict(StgDictObject *stgdict)
|
|||
Py_INCREF(ob);
|
||||
stgdict->errcheck = ob;
|
||||
}
|
||||
else if (PyErr_Occurred()) {
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
return 0;
|
||||
|
||||
error:
|
||||
Py_XDECREF(converters);
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
static PyCArgObject *
|
||||
|
|
@ -3085,9 +3137,13 @@ PyCFuncPtr_get_errcheck(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
|
|||
static int
|
||||
PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
|
||||
{
|
||||
_Py_IDENTIFIER(_check_retval_);
|
||||
PyObject *checker, *oldchecker;
|
||||
if (ob == NULL) {
|
||||
oldchecker = self->checker;
|
||||
self->checker = NULL;
|
||||
Py_CLEAR(self->restype);
|
||||
Py_CLEAR(self->checker);
|
||||
Py_XDECREF(oldchecker);
|
||||
return 0;
|
||||
}
|
||||
if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
|
||||
|
|
@ -3095,11 +3151,14 @@ PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ign
|
|||
"restype must be a type, a callable, or None");
|
||||
return -1;
|
||||
}
|
||||
if (_PyObject_LookupAttrId(ob, &PyId__check_retval_, &checker) < 0) {
|
||||
return -1;
|
||||
}
|
||||
oldchecker = self->checker;
|
||||
self->checker = checker;
|
||||
Py_INCREF(ob);
|
||||
Py_XSETREF(self->restype, ob);
|
||||
Py_XSETREF(self->checker, PyObject_GetAttrString(ob, "_check_retval_"));
|
||||
if (self->checker == NULL)
|
||||
PyErr_Clear();
|
||||
Py_XDECREF(oldchecker);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -3526,9 +3585,12 @@ PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||
like that.
|
||||
*/
|
||||
/*
|
||||
if (kwds && PyDict_GetItemString(kwds, "options")) {
|
||||
if (kwds && _PyDict_GetItemIdWithError(kwds, &PyId_options)) {
|
||||
...
|
||||
}
|
||||
else if (PyErr_Occurred()) {
|
||||
return NULL;
|
||||
}
|
||||
*/
|
||||
|
||||
dict = PyType_stgdict((PyObject *)type);
|
||||
|
|
@ -3605,10 +3667,16 @@ _get_arg(int *pindex, PyObject *name, PyObject *defval, PyObject *inargs, PyObje
|
|||
Py_INCREF(v);
|
||||
return v;
|
||||
}
|
||||
if (kwds && name && (v = PyDict_GetItem(kwds, name))) {
|
||||
++*pindex;
|
||||
Py_INCREF(v);
|
||||
return v;
|
||||
if (kwds && name) {
|
||||
v = PyDict_GetItemWithError(kwds, name);
|
||||
if (v) {
|
||||
++*pindex;
|
||||
Py_INCREF(v);
|
||||
return v;
|
||||
}
|
||||
else if (PyErr_Occurred()) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (defval) {
|
||||
Py_INCREF(defval);
|
||||
|
|
@ -3685,7 +3753,7 @@ _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes,
|
|||
for (i = 0; i < len; ++i) {
|
||||
PyObject *item = PyTuple_GET_ITEM(paramflags, i);
|
||||
PyObject *ob;
|
||||
int flag;
|
||||
unsigned int flag;
|
||||
PyObject *name = NULL;
|
||||
PyObject *defval = NULL;
|
||||
|
||||
|
|
@ -3693,7 +3761,7 @@ _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes,
|
|||
calls below. */
|
||||
/* We HAVE already checked that the tuple can be parsed with "i|ZO", so... */
|
||||
Py_ssize_t tsize = PyTuple_GET_SIZE(item);
|
||||
flag = PyLong_AS_LONG(PyTuple_GET_ITEM(item, 0));
|
||||
flag = PyLong_AsUnsignedLongMask(PyTuple_GET_ITEM(item, 0));
|
||||
name = tsize > 1 ? PyTuple_GET_ITEM(item, 1) : NULL;
|
||||
defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL;
|
||||
|
||||
|
|
@ -3773,7 +3841,7 @@ _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes,
|
|||
break;
|
||||
default:
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"paramflag %d not yet implemented", flag);
|
||||
"paramflag %u not yet implemented", flag);
|
||||
goto error;
|
||||
break;
|
||||
}
|
||||
|
|
@ -4136,6 +4204,7 @@ _init_pos_args(PyObject *self, PyTypeObject *type,
|
|||
StgDictObject *dict;
|
||||
PyObject *fields;
|
||||
Py_ssize_t i;
|
||||
_Py_IDENTIFIER(_fields_);
|
||||
|
||||
if (PyType_stgdict((PyObject *)type->tp_base)) {
|
||||
index = _init_pos_args(self, type->tp_base,
|
||||
|
|
@ -4146,9 +4215,13 @@ _init_pos_args(PyObject *self, PyTypeObject *type,
|
|||
}
|
||||
|
||||
dict = PyType_stgdict((PyObject *)type);
|
||||
fields = PyDict_GetItemString((PyObject *)dict, "_fields_");
|
||||
if (fields == NULL)
|
||||
fields = _PyDict_GetItemIdWithError((PyObject *)dict, &PyId__fields_);
|
||||
if (fields == NULL) {
|
||||
if (PyErr_Occurred()) {
|
||||
return -1;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
for (i = 0;
|
||||
i < dict->length && (i+index) < PyTuple_GET_SIZE(args);
|
||||
|
|
@ -4164,13 +4237,20 @@ _init_pos_args(PyObject *self, PyTypeObject *type,
|
|||
return -1;
|
||||
}
|
||||
val = PyTuple_GET_ITEM(args, i + index);
|
||||
if (kwds && PyDict_GetItem(kwds, name)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"duplicate values for field %R",
|
||||
name);
|
||||
Py_DECREF(pair);
|
||||
Py_DECREF(name);
|
||||
return -1;
|
||||
if (kwds) {
|
||||
if (PyDict_GetItemWithError(kwds, name)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"duplicate values for field %R",
|
||||
name);
|
||||
Py_DECREF(pair);
|
||||
Py_DECREF(name);
|
||||
return -1;
|
||||
}
|
||||
else if (PyErr_Occurred()) {
|
||||
Py_DECREF(pair);
|
||||
Py_DECREF(name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
res = PyObject_SetAttr(self, name, val);
|
||||
|
|
@ -4641,6 +4721,10 @@ PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length)
|
|||
Py_DECREF(key);
|
||||
return result;
|
||||
}
|
||||
else if (PyErr_Occurred()) {
|
||||
Py_DECREF(key);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyType_Check(itemtype)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
|
|
|
|||
|
|
@ -107,9 +107,14 @@ static void
|
|||
TryAddRef(StgDictObject *dict, CDataObject *obj)
|
||||
{
|
||||
IUnknown *punk;
|
||||
_Py_IDENTIFIER(_needs_com_addref_);
|
||||
|
||||
if (NULL == PyDict_GetItemString((PyObject *)dict, "_needs_com_addref_"))
|
||||
if (!_PyDict_GetItemIdWithError((PyObject *)dict, &PyId__needs_com_addref_)) {
|
||||
if (PyErr_Occurred()) {
|
||||
PrintError("getting _needs_com_addref_");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
punk = *(IUnknown **)obj->b_ptr;
|
||||
if (punk)
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ _ctypes_get_errobj(int **pspace)
|
|||
if (error_object_name == NULL)
|
||||
return NULL;
|
||||
}
|
||||
errobj = PyDict_GetItem(dict, error_object_name);
|
||||
errobj = PyDict_GetItemWithError(dict, error_object_name);
|
||||
if (errobj) {
|
||||
if (!PyCapsule_IsValid(errobj, CTYPES_CAPSULE_NAME_PYMEM)) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
|
|
@ -155,7 +155,7 @@ _ctypes_get_errobj(int **pspace)
|
|||
}
|
||||
Py_INCREF(errobj);
|
||||
}
|
||||
else {
|
||||
else if (!PyErr_Occurred()) {
|
||||
void *space = PyMem_Malloc(sizeof(int) * 2);
|
||||
if (space == NULL)
|
||||
return NULL;
|
||||
|
|
@ -171,6 +171,9 @@ _ctypes_get_errobj(int **pspace)
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
*pspace = (int *)PyCapsule_GetPointer(errobj, CTYPES_CAPSULE_NAME_PYMEM);
|
||||
return errobj;
|
||||
}
|
||||
|
|
@ -685,8 +688,11 @@ static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa)
|
|||
#endif
|
||||
|
||||
{
|
||||
_Py_IDENTIFIER(_as_parameter_);
|
||||
PyObject *arg;
|
||||
arg = PyObject_GetAttrString(obj, "_as_parameter_");
|
||||
if (_PyObject_LookupAttrId(obj, &PyId__as_parameter_, &arg) < 0) {
|
||||
return -1;
|
||||
}
|
||||
/* Which types should we exactly allow here?
|
||||
integers are required for using Python classes
|
||||
as parameters (they have to expose the '_as_parameter_'
|
||||
|
|
@ -1685,11 +1691,14 @@ POINTER(PyObject *self, PyObject *cls)
|
|||
PyObject *key;
|
||||
char *buf;
|
||||
|
||||
result = PyDict_GetItem(_ctypes_ptrtype_cache, cls);
|
||||
result = PyDict_GetItemWithError(_ctypes_ptrtype_cache, cls);
|
||||
if (result) {
|
||||
Py_INCREF(result);
|
||||
return result;
|
||||
}
|
||||
else if (PyErr_Occurred()) {
|
||||
return NULL;
|
||||
}
|
||||
if (PyUnicode_CheckExact(cls)) {
|
||||
const char *name = PyUnicode_AsUTF8(cls);
|
||||
if (name == NULL)
|
||||
|
|
@ -1745,12 +1754,16 @@ pointer(PyObject *self, PyObject *arg)
|
|||
PyObject *result;
|
||||
PyObject *typ;
|
||||
|
||||
typ = PyDict_GetItem(_ctypes_ptrtype_cache, (PyObject *)Py_TYPE(arg));
|
||||
if (typ)
|
||||
typ = PyDict_GetItemWithError(_ctypes_ptrtype_cache, (PyObject *)Py_TYPE(arg));
|
||||
if (typ) {
|
||||
return PyObject_CallFunctionObjArgs(typ, arg, NULL);
|
||||
}
|
||||
else if (PyErr_Occurred()) {
|
||||
return NULL;
|
||||
}
|
||||
typ = POINTER(NULL, (PyObject *)Py_TYPE(arg));
|
||||
if (typ == NULL)
|
||||
return NULL;
|
||||
return NULL;
|
||||
result = PyObject_CallFunctionObjArgs(typ, arg, NULL);
|
||||
Py_DECREF(typ);
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -1147,7 +1147,7 @@ c_set(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
}
|
||||
if (PyLong_Check(value))
|
||||
{
|
||||
long longval = PyLong_AS_LONG(value);
|
||||
long longval = PyLong_AsLong(value);
|
||||
if (longval < 0 || longval >= 256)
|
||||
goto error;
|
||||
*(char *)ptr = (char)longval;
|
||||
|
|
|
|||
|
|
@ -281,13 +281,15 @@ MakeFields(PyObject *type, CFieldObject *descr,
|
|||
static int
|
||||
MakeAnonFields(PyObject *type)
|
||||
{
|
||||
_Py_IDENTIFIER(_anonymous_);
|
||||
PyObject *anon;
|
||||
PyObject *anon_names;
|
||||
Py_ssize_t i;
|
||||
|
||||
anon = PyObject_GetAttrString(type, "_anonymous_");
|
||||
if (_PyObject_LookupAttrId(type, &PyId__anonymous_, &anon) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (anon == NULL) {
|
||||
PyErr_Clear();
|
||||
return 0;
|
||||
}
|
||||
anon_names = PySequence_Fast(anon, "_anonymous_ must be a sequence");
|
||||
|
|
@ -335,13 +337,17 @@ MakeAnonFields(PyObject *type)
|
|||
int
|
||||
PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
|
||||
{
|
||||
_Py_IDENTIFIER(_swappedbytes_);
|
||||
_Py_IDENTIFIER(_use_broken_old_ctypes_structure_semantics_);
|
||||
_Py_IDENTIFIER(_pack_);
|
||||
StgDictObject *stgdict, *basedict;
|
||||
Py_ssize_t len, offset, size, align, i;
|
||||
Py_ssize_t union_size, total_align;
|
||||
Py_ssize_t field_size = 0;
|
||||
int bitofs;
|
||||
PyObject *isPacked;
|
||||
int pack = 0;
|
||||
PyObject *tmp;
|
||||
int isPacked;
|
||||
int pack;
|
||||
Py_ssize_t ffi_ofs;
|
||||
int big_endian;
|
||||
|
||||
|
|
@ -356,32 +362,59 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct
|
|||
if (fields == NULL)
|
||||
return 0;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
big_endian = PyObject_HasAttrString(type, "_swappedbytes_") ? 0 : 1;
|
||||
#else
|
||||
big_endian = PyObject_HasAttrString(type, "_swappedbytes_") ? 1 : 0;
|
||||
#endif
|
||||
if (_PyObject_LookupAttrId(type, &PyId__swappedbytes_, &tmp) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (tmp) {
|
||||
Py_DECREF(tmp);
|
||||
big_endian = !PY_BIG_ENDIAN;
|
||||
}
|
||||
else {
|
||||
big_endian = PY_BIG_ENDIAN;
|
||||
}
|
||||
|
||||
use_broken_old_ctypes_semantics = \
|
||||
PyObject_HasAttrString(type, "_use_broken_old_ctypes_structure_semantics_");
|
||||
if (_PyObject_LookupAttrId(type,
|
||||
&PyId__use_broken_old_ctypes_structure_semantics_, &tmp) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (tmp) {
|
||||
Py_DECREF(tmp);
|
||||
use_broken_old_ctypes_semantics = 1;
|
||||
}
|
||||
else {
|
||||
use_broken_old_ctypes_semantics = 0;
|
||||
}
|
||||
|
||||
isPacked = PyObject_GetAttrString(type, "_pack_");
|
||||
if (isPacked) {
|
||||
pack = _PyLong_AsInt(isPacked);
|
||||
if (pack < 0 || PyErr_Occurred()) {
|
||||
Py_XDECREF(isPacked);
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"_pack_ must be a non-negative integer");
|
||||
if (_PyObject_LookupAttrId(type, &PyId__pack_, &tmp) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (tmp) {
|
||||
isPacked = 1;
|
||||
pack = _PyLong_AsInt(tmp);
|
||||
Py_DECREF(tmp);
|
||||
if (pack < 0) {
|
||||
if (!PyErr_Occurred() ||
|
||||
PyErr_ExceptionMatches(PyExc_TypeError) ||
|
||||
PyErr_ExceptionMatches(PyExc_OverflowError))
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"_pack_ must be a non-negative integer");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
Py_DECREF(isPacked);
|
||||
} else
|
||||
PyErr_Clear();
|
||||
}
|
||||
else {
|
||||
isPacked = 0;
|
||||
pack = 0;
|
||||
}
|
||||
|
||||
len = PySequence_Length(fields);
|
||||
len = PySequence_Size(fields);
|
||||
if (len == -1) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"'_fields_' must be a sequence of pairs");
|
||||
if (PyErr_ExceptionMatches(PyExc_TypeError)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"'_fields_' must be a sequence of pairs");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue