diff options
Diffstat (limited to 'sources/shiboken2')
3 files changed, 101 insertions, 21 deletions
diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp index 922f85906..564e5fcef 100644 --- a/sources/shiboken2/libshiboken/signature.cpp +++ b/sources/shiboken2/libshiboken/signature.cpp @@ -129,13 +129,16 @@ static PyObject * _get_class_of_cf(PyObject *ob_cf) { PyObject *selftype = PyCFunction_GET_SELF(ob_cf); - if (selftype == NULL) - selftype = PyDict_GetItem(pyside_globals->map_dict, (PyObject *)ob_cf); - if (selftype == NULL) { - if (!PyErr_Occurred()) - Py_RETURN_NONE; - return NULL; + if (selftype == nullptr) { + selftype = PyDict_GetItem(pyside_globals->map_dict, ob_cf); + if (selftype == nullptr) { + // This must be an overloaded function that we handled special. + Shiboken::AutoDecRef special(Py_BuildValue("(Os)", ob_cf, "overload")); + selftype = PyDict_GetItem(pyside_globals->map_dict, special); + } } + assert(selftype); + PyObject *typemod = (PyType_Check(selftype) || PyModule_Check(selftype)) ? selftype : (PyObject *)Py_TYPE(selftype); // do we support module functions? @@ -175,19 +178,26 @@ GetClassOfFunc(PyObject *ob) } static PyObject * -compute_name_key(PyObject *ob) +get_funcname(PyObject *ob) { - if (PyType_Check(ob)) - return GetClassKey(GetClassOfFunc(ob)); PyObject *func = ob; if (Py_TYPE(ob) == PepStaticMethod_TypePtr) func = PyObject_GetAttrString(ob, "__func__"); else Py_INCREF(func); - Shiboken::AutoDecRef func_name(PyObject_GetAttrString(func, "__name__")); + PyObject *func_name = PyObject_GetAttrString(func, "__name__"); Py_DECREF(func); - if (func_name.isNull()) + if (func_name == nullptr) Py_FatalError("unexpected name problem in compute_name_key"); + return func_name; +} + +static PyObject * +compute_name_key(PyObject *ob) +{ + if (PyType_Check(ob)) + return GetClassKey(ob); + Shiboken::AutoDecRef func_name(get_funcname(ob)); Shiboken::AutoDecRef type_key(GetClassKey(GetClassOfFunc(ob))); return Py_BuildValue("(OO)", type_key.object(), func_name.object()); } @@ -201,9 +211,11 @@ build_name_key_to_func(PyObject *obtype) if (meth == 0) return 0; + Shiboken::AutoDecRef type_key(GetClassKey(obtype)); for (; meth->ml_name != NULL; meth++) { Shiboken::AutoDecRef func(PyCFunction_NewEx(meth, obtype, NULL)); - Shiboken::AutoDecRef name_key(compute_name_key(func)); + Shiboken::AutoDecRef func_name(get_funcname(func)); + Shiboken::AutoDecRef name_key(Py_BuildValue("(OO)", type_key.object(), func_name.object())); if (func.isNull() || name_key.isNull() || PyDict_SetItem(pyside_globals->map_dict, name_key, func) < 0) return -1; @@ -224,7 +236,7 @@ name_key_to_func(PyObject *ob) Py_RETURN_NONE; PyObject *ret = PyDict_GetItem(pyside_globals->map_dict, name_key); - if (ret == NULL) { + if (ret == nullptr) { // do a lazy initialization Shiboken::AutoDecRef type_key(GetClassKey(GetClassOfFunc(ob))); PyObject *type = PyDict_GetItem(pyside_globals->map_dict, @@ -233,7 +245,7 @@ name_key_to_func(PyObject *ob) Py_RETURN_NONE; assert(PyType_Check(type)); if (build_name_key_to_func(type) < 0) - return NULL; + return nullptr; ret = PyDict_GetItem(pyside_globals->map_dict, name_key); } Py_XINCREF(ret); @@ -901,6 +913,12 @@ _build_func_to_type(PyObject *obtype) strcat(mangled_name, ".overload"); if (PyDict_SetItemString(dict, mangled_name, descr) < 0) return -1; + if (meth->ml_flags & METH_STATIC) { + // This is the special case where a static method is hidden. + Shiboken::AutoDecRef special(Py_BuildValue("(Os)", cfunc.object(), "overload")); + if (PyDict_SetItem(pyside_globals->map_dict, special, obtype) < 0) + return -1; + } if (PyDict_SetItemString(pyside_globals->map_dict, mangled_name, obtype) < 0) return -1; continue; diff --git a/sources/shiboken2/shibokenmodule/support/signature/backport_inspect.py b/sources/shiboken2/shibokenmodule/support/signature/backport_inspect.py index 6b97470e2..e890dcdcf 100644 --- a/sources/shiboken2/shibokenmodule/support/signature/backport_inspect.py +++ b/sources/shiboken2/shibokenmodule/support/signature/backport_inspect.py @@ -113,8 +113,8 @@ CO_NOFREE = 0x0040 # We use '__builtin__' and '__name__' instead. # It is further changed because we use a local copy of typing def formatannotation(annotation, base_module=None): - if getattr(annotation, '__module__', None) == 'support.signature.typing': - return repr(annotation).replace('support.signature.typing', 'typing') + if getattr(annotation, '__module__', None) == 'support.signature.typing27': + return repr(annotation).replace('support.signature.typing27', 'typing') if isinstance(annotation, type): if annotation.__module__ in ('__builtin__', base_module): return annotation.__name__ diff --git a/sources/shiboken2/shibokenmodule/support/signature/mapping.py b/sources/shiboken2/shibokenmodule/support/signature/mapping.py index 3e76cd94a..f638bc42b 100644 --- a/sources/shiboken2/shibokenmodule/support/signature/mapping.py +++ b/sources/shiboken2/shibokenmodule/support/signature/mapping.py @@ -88,6 +88,7 @@ WId = int GL_TEXTURE_2D = 0x0DE1 GL_RGBA = 0x1908 + class _NotCalled(str): """ Wrap some text with semantics @@ -104,7 +105,7 @@ class _NotCalled(str): real object is needed, the wrapper can simply be called. """ def __repr__(self): - suppress = "support.signature.typing." + suppress = "support.signature.typing27." text = self[len(suppress):] if self.startswith(suppress) else self return "{}({})".format(type(self).__name__, text) @@ -113,14 +114,20 @@ class _NotCalled(str): text = self if self.endswith(")") else self + "()" return eval(text, namespace) +USE_PEP563 = sys.version_info[:2] >= (3, 7) + + # Some types are abstract. They just show their name. class Virtual(_NotCalled): pass # Other types I simply could not find. class Missing(_NotCalled): - def __repr__(self): - return '{}("{}")'.format(type(self).__name__, self) + if not USE_PEP563: + # The string must be quoted, because the object does not exist. + def __repr__(self): + return '{}("{}")'.format(type(self).__name__, self) + class Invalid(_NotCalled): pass @@ -129,12 +136,20 @@ class Invalid(_NotCalled): class Default(_NotCalled): pass + class Instance(_NotCalled): pass class Reloader(object): - _uninitialized = ["sample"] + """ + Reloder class + + This is a singleton class which provides the update function for the + shiboken and PySide classes. + """ + ## Note: We needed to rename shiboken2 in order to avoid a name clash. + _uninitialized = "Shiboken minimal sample other smart".split() _prefixes = [""] def __init__(self): @@ -142,6 +157,14 @@ class Reloader(object): self.uninitialized = self._uninitialized def update(self, g=None): + """ + update is responsible to import all modules from shiboken and PySide + which are already in sys.modules. + The purpose is to follow all user imports without introducing new + ones. + This function is called by pyside_type_init to adapt imports + when the number of imported modules has changed. + """ if self.sys_module_count == len(sys.modules): return self.sys_module_count = len(sys.modules) @@ -160,6 +183,14 @@ class Reloader(object): self.uninitialized.remove(mod_name) proc_name = "init_" + mod_name if proc_name in g: + # Do the 'import {import_name}' first. + # 'top' is PySide2 when we do 'import PySide.QtCore' + # or Shiboken if we do 'import Shiboken'. + # Convince yourself that these two lines below have the same + # global effect as "import Shiboken" or "import PySide2.QtCore". + top = __import__(import_name) + g[top.__name__] = top + # Modules are in place, we can update the type_map. g.update(g[proc_name]()) @@ -167,8 +198,23 @@ update_mapping = Reloader().update type_map = {} +def init_Shiboken(): + type_map.update({ + "shiboken2.bool": bool, + "size_t": int, + "PyType": type, + }) + return locals() + + +def init_minimal(): + type_map.update({ + "MinBool": bool, + }) + return locals() + + def init_sample(): - import sample import datetime type_map.update({ "sample.int": int, @@ -207,4 +253,20 @@ def init_sample(): }) return locals() + +def init_other(): + import numbers + type_map.update({ + "other.Number": numbers.Number, + "other.ExtendsNoImplicitConversion": Missing("other.ExtendsNoImplicitConversion"), + }) + return locals() + + +def init_smart(): + type_map.update({ + "smart.SharedPtr": Missing("smart.SharedPtr"), # bad object "SharedPtr<Obj >" + }) + return locals() + # end of file |