diff options
Diffstat (limited to 'sources/shiboken2')
9 files changed, 90 insertions, 23 deletions
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp index 9739dfef6..7743d50a2 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp @@ -2825,7 +2825,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream &s, const Ov if (isVarargs) --numArgs; typeChecks.prepend(QString::fromLatin1("numArgs %1 %2").arg(isVarargs ? QLatin1String(">=") : QLatin1String("==")).arg(numArgs)); - } else if (sequenceArgCount > 1) { + } else if (usePyArgs && sequenceArgCount > 0) { typeChecks.prepend(QString::fromLatin1("numArgs >= %1").arg(startArg + sequenceArgCount)); } else if (refFunc->isOperatorOverload() && !refFunc->isCallOperator()) { typeChecks.prepend(QString::fromLatin1("%1isReverse").arg(refFunc->isReverseOperator() ? QString() : QLatin1String("!"))); diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp index dca5631bc..113128f5a 100644 --- a/sources/shiboken2/libshiboken/basewrapper.cpp +++ b/sources/shiboken2/libshiboken/basewrapper.cpp @@ -677,6 +677,13 @@ void SbkObjectType_SetPropertyStrings(PyTypeObject *type, const char **strings) PepType_SOTP(reinterpret_cast<SbkObjectType *>(type))->propertyStrings = strings; } +// PYSIDE-1626: Enforcing a context switch without further action. +void SbkObjectType_UpdateFeature(PyTypeObject *type) +{ + if (SelectFeatureSet != nullptr) + type->tp_dict = SelectFeatureSet(type); +} + // ////////////////////////////////////////////////////////////////////////////// diff --git a/sources/shiboken2/libshiboken/basewrapper.h b/sources/shiboken2/libshiboken/basewrapper.h index 2f0c22e9f..a79a93096 100644 --- a/sources/shiboken2/libshiboken/basewrapper.h +++ b/sources/shiboken2/libshiboken/basewrapper.h @@ -98,11 +98,14 @@ typedef void (*SubTypeInitHook)(SbkObjectType *, PyObject *, PyObject *); typedef PyObject *(*SelectableFeatureHook)(PyTypeObject *); LIBSHIBOKEN_API SelectableFeatureHook initSelectableFeature(SelectableFeatureHook func); -// PYSIDE-1019: Get access to PySide reserved bits. +/// PYSIDE-1019: Get access to PySide reserved bits. LIBSHIBOKEN_API int SbkObjectType_GetReserved(PyTypeObject *type); LIBSHIBOKEN_API void SbkObjectType_SetReserved(PyTypeObject *type, int value); -// PYSIDE-1019: Get access to PySide property strings. +/// PYSIDE-1626: Enforcing a context switch without further action. +LIBSHIBOKEN_API void SbkObjectType_UpdateFeature(PyTypeObject *type); + +/// PYSIDE-1019: Get access to PySide property strings. LIBSHIBOKEN_API const char **SbkObjectType_GetPropertyStrings(PyTypeObject *type); LIBSHIBOKEN_API void SbkObjectType_SetPropertyStrings(PyTypeObject *type, const char **strings); diff --git a/sources/shiboken2/libshiboken/bindingmanager.cpp b/sources/shiboken2/libshiboken/bindingmanager.cpp index 065c02049..5d69e923f 100644 --- a/sources/shiboken2/libshiboken/bindingmanager.cpp +++ b/sources/shiboken2/libshiboken/bindingmanager.cpp @@ -292,6 +292,9 @@ PyObject *BindingManager::getOverride(const void *cptr, if (!wrapper || reinterpret_cast<const PyObject *>(wrapper)->ob_refcnt == 0) return nullptr; + // PYSIDE-1626: Touch the type to initiate switching early. + SbkObjectType_UpdateFeature(Py_TYPE(wrapper)); + int flag = currentSelectId(Py_TYPE(wrapper)); int propFlag = isdigit(methodName[0]) ? methodName[0] - '0' : 0; if ((flag & 0x02) != 0 && (propFlag & 3) != 0) { diff --git a/sources/shiboken2/libshiboken/embed/signature_bootstrap.py b/sources/shiboken2/libshiboken/embed/signature_bootstrap.py index dd8df2b63..902864267 100644 --- a/sources/shiboken2/libshiboken/embed/signature_bootstrap.py +++ b/sources/shiboken2/libshiboken/embed/signature_bootstrap.py @@ -77,10 +77,11 @@ def bootstrap(): recursion_trap += 1 @contextmanager - def ensure_shibokensupport(support_path): + def ensure_shibokensupport(target, support_path): # Make sure that we always have the shibokensupport containing package first. # Also remove any prior loaded module of this name, just in case. - sys.path.insert(0, support_path) + # PYSIDE-1621: support_path can also be a finder instance. + target.insert(0, support_path) sbks = "shibokensupport" if sbks in sys.modules: @@ -100,7 +101,7 @@ def bootstrap(): print(" " + p) sys.stdout.flush() sys.exit(-1) - sys.path.remove(support_path) + target.remove(support_path) try: import shiboken2 as root @@ -119,8 +120,6 @@ def bootstrap(): # Here we decide if we work embedded or not. embedding_var = "pyside_uses_embedding" use_embedding = bool(getattr(sys, embedding_var, False)) - # We keep the zip file for inspection if the sys variable has been set. - keep_zipfile = hasattr(sys, embedding_var) loader_path = os.path.join(rp, look_for) files_dir = os.path.abspath(os.path.join(loader_path, "..", "..", "..")) assert files_dir.endswith("files.dir") @@ -131,41 +130,54 @@ def bootstrap(): support_path = prepare_zipfile() if use_embedding else files_dir setattr(sys, embedding_var, use_embedding) + if use_embedding: + target, support_path = prepare_zipfile() + else: + target, support_path = sys.path, files_dir + try: - with ensure_shibokensupport(support_path): + with ensure_shibokensupport(target, support_path): from shibokensupport.signature import loader except Exception as e: print('Exception:', e) traceback.print_exc(file=sys.stdout) - finally: - if use_embedding and not keep_zipfile: - # clear the temp zipfile - try: - os.remove(support_path) - except OSError as e: - print(e) - print("Error deleting {support_path}, ignored".format(**locals())) - return loader + return loader + # New functionality: Loading from a zip archive. # There exists the zip importer, but as it is written, only real zip files are # supported. Before I will start an own implementation, it is easiest to use # a temporary zip file. +# PYSIDE-1621: make zip file access totally virtual def prepare_zipfile(): """ Write the zip file to a real file and return its name. It will be implicitly opened as such when we add the name to sys.path . + + New approach (Python 3, only): + + Use EmbeddableZipImporter and pass the zipfile structure directly. + The sys.path way does not work, instead we need to use sys.meta_path . + See https://docs.python.org/3/library/sys.html#sys.meta_path """ import base64 - import tempfile - import os + import io + import sys import zipfile # 'zipstring_sequence' comes from signature.cpp zipbytes = base64.b64decode(''.join(zipstring_sequence)) + if sys.version_info[0] >= 3: + vzip = zipfile.ZipFile(io.BytesIO(zipbytes)) + return sys.meta_path, EmbeddableZipImporter(vzip) + + # Old version for Python 2.7, only. + import os + import tempfile + fd, fname = tempfile.mkstemp(prefix='embedded.', suffix='.zip') os.write(fd, zipbytes) os.close(fd) @@ -178,6 +190,45 @@ def prepare_zipfile(): print('Broken Zip File:', e) traceback.print_exc(file=sys.stdout) finally: - return fname + return sys.path, fname + + +class EmbeddableZipImporter(object): + + def __init__(self, zip_file): + def p2m(filename): + if filename.endswith("/__init__.py"): + return filename[:-12].replace("/", ".") + if filename.endswith(".py"): + return filename[:-3].replace("/", ".") + return None + + self.zfile = zip_file + self._path2mod = {_.filename : p2m(_.filename) for _ in zip_file.filelist} + self._mod2path = {_[1] : _[0] for _ in self._path2mod.items()} + + def find_module(self, fullname, path): + return self if self._mod2path.get(fullname) else None + + def load_module(self, fullname): + import importlib + import sys + + filename = self._mod2path.get(fullname) + if filename not in self._path2mod: + raise ImportError(fullname) + module_spec = importlib.machinery.ModuleSpec(fullname, None) + new_module = importlib.util.module_from_spec(module_spec) + with self.zfile.open(filename, "r") as f: # "rb" not for zipfile + exec(f.read(), new_module.__dict__) + new_module.__file__ = filename + new_module.__loader__ = self + if filename.endswith("/__init__.py"): + new_module.__path__ = [] + new_module.__package__ = fullname + else: + new_module.__package__ = fullname.rpartition('.')[0] + sys.modules[fullname] = new_module + return new_module # eof diff --git a/sources/shiboken2/libshiboken/sbkenum.cpp b/sources/shiboken2/libshiboken/sbkenum.cpp index 0d103db6c..7dc73dfbc 100644 --- a/sources/shiboken2/libshiboken/sbkenum.cpp +++ b/sources/shiboken2/libshiboken/sbkenum.cpp @@ -750,6 +750,7 @@ newTypeWithName(const char *name, newspec.slots = newslots; Shiboken::AutoDecRef bases(PyTuple_New(1)); static auto basetype = SbkEnum_TypeF(); + Py_INCREF(basetype); PyTuple_SetItem(bases, 0, reinterpret_cast<PyObject *>(basetype)); auto *type = reinterpret_cast<PyTypeObject *>(SbkType_FromSpecWithBases(&newspec, bases)); PyErr_Print(); diff --git a/sources/shiboken2/libshiboken/signature/signature_globals.cpp b/sources/shiboken2/libshiboken/signature/signature_globals.cpp index d23ae15d0..818102804 100644 --- a/sources/shiboken2/libshiboken/signature/signature_globals.cpp +++ b/sources/shiboken2/libshiboken/signature/signature_globals.cpp @@ -110,7 +110,7 @@ static safe_globals_struc *init_phase_1(PyMethodDef *init_meth) if (compile == nullptr) goto error; AutoDecRef code_obj(PyObject_CallFunction(compile, "Oss", - bytes.object(), "(builtin)", "exec")); + bytes.object(), "signature_bootstrap.py", "exec")); #else AutoDecRef code_obj(PyObject_CallFunctionObjArgs( loads, bytes.object(), nullptr)); diff --git a/sources/shiboken2/shiboken_version.py b/sources/shiboken2/shiboken_version.py index 876a0e401..3ee73451b 100644 --- a/sources/shiboken2/shiboken_version.py +++ b/sources/shiboken2/shiboken_version.py @@ -39,7 +39,7 @@ major_version = "5" minor_version = "15" -patch_version = "5" +patch_version = "6" # For example: "a", "b", "rc" # (which means "alpha", "beta", "release candidate"). diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py index a509ecf07..022299391 100644 --- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py +++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py @@ -206,6 +206,7 @@ def move_into_pyside_package(): put_into_package(PySide2.support.signature, parser) put_into_package(PySide2.support.signature, importhandler) put_into_package(PySide2.support.signature.lib, enum_sig) + put_into_package(PySide2.support.signature.lib, tool) put_into_package(None if orig_typing else PySide2.support.signature, typing) put_into_package(PySide2.support.signature, inspect) @@ -217,6 +218,7 @@ from shibokensupport.signature import lib from shibokensupport.signature import parser from shibokensupport.signature import importhandler from shibokensupport.signature.lib import enum_sig +from shibokensupport.signature.lib import tool if "PySide2" in sys.modules: # We publish everything under "PySide2.support.signature", again. |