diff options
Diffstat (limited to 'sources/shiboken2/libshiboken')
-rw-r--r-- | sources/shiboken2/libshiboken/pep384impl.cpp | 81 | ||||
-rw-r--r-- | sources/shiboken2/libshiboken/pep384impl.h | 6 | ||||
-rw-r--r-- | sources/shiboken2/libshiboken/sbkstaticstrings.h | 1 | ||||
-rw-r--r-- | sources/shiboken2/libshiboken/sbkstaticstrings_p.h | 1 |
4 files changed, 88 insertions, 1 deletions
diff --git a/sources/shiboken2/libshiboken/pep384impl.cpp b/sources/shiboken2/libshiboken/pep384impl.cpp index fa31ce43f..4df9bc21d 100644 --- a/sources/shiboken2/libshiboken/pep384impl.cpp +++ b/sources/shiboken2/libshiboken/pep384impl.cpp @@ -192,6 +192,87 @@ check_PyTypeObject_valid() /***************************************************************************** * + * Additional for object.h / class properties + * + */ +#ifdef Py_LIMITED_API +/* + * This implementation of `_PyType_Lookup` works for lookup in our classes. + * The implementation ignores all caching and versioning and is also + * less optimized. This is reduced from the Python implementation. + */ + +/* Internal API to look for a name through the MRO, bypassing the method cache. + This returns a borrowed reference, and might set an exception. + 'error' is set to: -1: error with exception; 1: error without exception; 0: ok */ +static PyObject * +find_name_in_mro(PyTypeObject *type, PyObject *name, int *error) +{ + Py_ssize_t i, n; + PyObject *mro, *res, *base, *dict; + + /* Look in tp_dict of types in MRO */ + mro = type->tp_mro; + + res = nullptr; + /* Keep a strong reference to mro because type->tp_mro can be replaced + during dict lookup, e.g. when comparing to non-string keys. */ + Py_INCREF(mro); + assert(PyTuple_Check(mro)); + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + base = PyTuple_GET_ITEM(mro, i); + assert(PyType_Check(base)); + dict = ((PyTypeObject *)base)->tp_dict; + assert(dict && PyDict_Check(dict)); + res = PyDict_GetItem(dict, name); + if (res != nullptr) + break; + if (PyErr_Occurred()) { + *error = -1; + goto done; + } + } + *error = 0; +done: + Py_DECREF(mro); + return res; +} + +/* Internal API to look for a name through the MRO. + This returns a borrowed reference, and doesn't set an exception! */ +PyObject * +_PepType_Lookup(PyTypeObject *type, PyObject *name) +{ + PyObject *res; + int error; + + /* We may end up clearing live exceptions below, so make sure it's ours. */ + assert(!PyErr_Occurred()); + + res = find_name_in_mro(type, name, &error); + /* Only put NULL results into cache if there was no error. */ + if (error) { + /* It's not ideal to clear the error condition, + but this function is documented as not setting + an exception, and I don't want to change that. + E.g., when PyType_Ready() can't proceed, it won't + set the "ready" flag, so future attempts to ready + the same type will call it again -- hopefully + in a context that propagates the exception out. + */ + if (error == -1) { + PyErr_Clear(); + } + return nullptr; + } + return res; +} + +#endif // Py_LIMITED_API + +/***************************************************************************** + * * Support for unicodeobject.h * */ diff --git a/sources/shiboken2/libshiboken/pep384impl.h b/sources/shiboken2/libshiboken/pep384impl.h index 7a6f57fcd..07f4a913f 100644 --- a/sources/shiboken2/libshiboken/pep384impl.h +++ b/sources/shiboken2/libshiboken/pep384impl.h @@ -142,6 +142,12 @@ typedef struct _typeobject { LIBSHIBOKEN_API int PyIndex_Check(PyObject *obj); #endif +LIBSHIBOKEN_API PyObject *_PepType_Lookup(PyTypeObject *type, PyObject *name); + +#else // Py_LIMITED_API + +#define _PepType_Lookup(type, name) _PyType_Lookup(type, name) + #endif // Py_LIMITED_API struct SbkObjectTypePrivate; diff --git a/sources/shiboken2/libshiboken/sbkstaticstrings.h b/sources/shiboken2/libshiboken/sbkstaticstrings.h index b72fa989b..16d36041e 100644 --- a/sources/shiboken2/libshiboken/sbkstaticstrings.h +++ b/sources/shiboken2/libshiboken/sbkstaticstrings.h @@ -69,6 +69,7 @@ LIBSHIBOKEN_API PyObject *dict(); LIBSHIBOKEN_API PyObject *doc(); LIBSHIBOKEN_API PyObject *ecf(); LIBSHIBOKEN_API PyObject *file(); +LIBSHIBOKEN_API PyObject *func(); LIBSHIBOKEN_API PyObject *get(); LIBSHIBOKEN_API PyObject *members(); LIBSHIBOKEN_API PyObject *module(); diff --git a/sources/shiboken2/libshiboken/sbkstaticstrings_p.h b/sources/shiboken2/libshiboken/sbkstaticstrings_p.h index c33fa0299..acfc71409 100644 --- a/sources/shiboken2/libshiboken/sbkstaticstrings_p.h +++ b/sources/shiboken2/libshiboken/sbkstaticstrings_p.h @@ -60,7 +60,6 @@ PyObject *bases(); PyObject *builtins(); PyObject *code(); PyObject *dictoffset(); -PyObject *func(); PyObject *func_kind(); PyObject *iter(); PyObject *module(); |