diff options
-rw-r--r-- | build_scripts/main.py | 22 | ||||
-rw-r--r-- | sources/shiboken6/libshiboken/pep384_issue33738.cpp | 46 | ||||
-rw-r--r-- | sources/shiboken6/libshiboken/pep384impl.cpp | 3 | ||||
-rw-r--r-- | sources/shiboken6/libshiboken/pep384impl.h | 10 | ||||
-rw-r--r-- | sources/shiboken6/shibokenmodule/CMakeLists.txt | 4 | ||||
-rw-r--r-- | sources/shiboken6/shibokenmodule/__init__.py.in | 1 | ||||
-rw-r--r-- | sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py | 7 |
7 files changed, 76 insertions, 17 deletions
diff --git a/build_scripts/main.py b/build_scripts/main.py index b4576d0e8..e25f22bd0 100644 --- a/build_scripts/main.py +++ b/build_scripts/main.py @@ -151,11 +151,12 @@ def get_make(platform_arch, build_type): return (make_path, make_generator) -def check_allowed_python_version(): - """ - Make sure that setup.py is run with an allowed python version. - """ +_allowed_versions_cache = None +def get_allowed_python_versions(): + global _allowed_versions_cache + if _allowed_versions_cache is not None: + return _allowed_versions_cache pattern = r'Programming Language :: Python :: (\d+)\.(\d+)' supported = [] @@ -165,6 +166,17 @@ def check_allowed_python_version(): major = int(found.group(1)) minor = int(found.group(2)) supported.append((major, minor)) + + _allowed_versions_cache = sorted(supported) + return _allowed_versions_cache + + +def check_allowed_python_version(): + """ + Make sure that setup.py is run with an allowed python version. + """ + + supported = get_allowed_python_versions() this_py = sys.version_info[:2] if this_py not in supported: log.error(f"Unsupported python version detected. Supported versions: {supported}") @@ -589,6 +601,8 @@ class PysideBuild(_build, DistUtilsCommandMixin, BuildInfoCollectorMixin): f"-DQt5Help_DIR={self.qtinfo.docs_dir}", f"-DCMAKE_BUILD_TYPE={self.build_type}", f"-DCMAKE_INSTALL_PREFIX={self.install_dir}", + # Record the minimum Python version for later use in Shiboken.__init__ + f"-DMINIMUM_PYTHON_VERSION={get_allowed_python_versions()[0]}", module_src_dir ] diff --git a/sources/shiboken6/libshiboken/pep384_issue33738.cpp b/sources/shiboken6/libshiboken/pep384_issue33738.cpp index c20edeefa..59713f2f5 100644 --- a/sources/shiboken6/libshiboken/pep384_issue33738.cpp +++ b/sources/shiboken6/libshiboken/pep384_issue33738.cpp @@ -47,7 +47,8 @@ // Simple solution: Create the structure and write such a function. // Long term: Submit a patch to python.org . -// Update: I did the long-term solution for python 3.7 in issue 33738. +// This structure comes from Python 3.7, but we have checked that +// it also works for Python 3.8 and 3.9. typedef struct { /* Number implementations must check *both* @@ -112,10 +113,45 @@ typedef struct _oldtypeobject { } PyOldTypeObject; -int PyIndex_Check(PyObject *obj) +static bool is_compatible_version() { - PyOldTypeObject *type = reinterpret_cast<PyOldTypeObject *>(Py_TYPE(obj)); - return type->tp_as_number != NULL && - type->tp_as_number->nb_index != NULL; + auto *sysmodule = PyImport_AddModule("sys"); + auto *dic = PyModule_GetDict(sysmodule); + auto *version = PyDict_GetItemString(dic, "version_info"); + auto *major = PyTuple_GetItem(version, 0); + auto *minor = PyTuple_GetItem(version, 1); + auto number = PyLong_AsLong(major) * 1000 + PyLong_AsLong(minor); + return number < 3010; +} + +/////////////////////////////////////////////////////////////////////// +// +// PYSIE-1797: The Solution +// ======================== +// +// Inspecting the data structures of Python 3.6, 3.7, 3.8 and 3.9 +// shows that concerning the here needed offset of nb_index, they +// are all compatible. +// That means: We can use the above definition for all these versions. +// +// From Python 3.10 on, the `PyType_GetSlot` function also works with +// non-heap types. That means this solution will always work. +// +// Note: When we have moved to Python 3.8 as the minimum version, +// this whole nonsense can be trashed. +// There is an automatic warning about this in parser.py . +// + +LIBSHIBOKEN_API int PyIndex_Check(PyObject *obj) +{ + static bool old_python_version = is_compatible_version(); + if (old_python_version) { + auto *type = reinterpret_cast<PyOldTypeObject *>(Py_TYPE(obj)); + return type->tp_as_number != nullptr && + type->tp_as_number->nb_index != nullptr; + } + // From Python 3.10 on, we can use PyType_GetSlot also with normal types! + unaryfunc nb_index = reinterpret_cast<unaryfunc>(PyType_GetSlot(Py_TYPE(obj), Py_nb_index)); + return nb_index != nullptr; } diff --git a/sources/shiboken6/libshiboken/pep384impl.cpp b/sources/shiboken6/libshiboken/pep384impl.cpp index b7a39adcb..1ddbe3ba1 100644 --- a/sources/shiboken6/libshiboken/pep384impl.cpp +++ b/sources/shiboken6/libshiboken/pep384impl.cpp @@ -191,9 +191,8 @@ check_PyTypeObject_valid() Py_DECREF(probe_tp_mro); } -#if PY_VERSION_HEX < PY_ISSUE33738_SOLVED +// PYSIDE-1797: This must be a runtime decision. #include "pep384_issue33738.cpp" -#endif #endif // Py_LIMITED_API diff --git a/sources/shiboken6/libshiboken/pep384impl.h b/sources/shiboken6/libshiboken/pep384impl.h index 62a66e37e..0198ff3f1 100644 --- a/sources/shiboken6/libshiboken/pep384impl.h +++ b/sources/shiboken6/libshiboken/pep384impl.h @@ -140,12 +140,14 @@ typedef struct _typeobject { #endif // This was a macro error in the limited API from the beginning. -// It was fixed in Python master, but did make it only in Python 3.8 . -#define PY_ISSUE33738_SOLVED 0x03080000 -#if PY_VERSION_HEX < PY_ISSUE33738_SOLVED +// It was fixed in Python master, but did make it only into Python 3.8 . + +// PYSIDE-1797: This must be a runtime decision. +// Remove that when the minimum Python version is 3.8, +// because the macro PyIndex_Check bug was fixed then. +/// FIXME: Remove PyIndex_Check and pep384_issue33738.cpp when Python 3.7 is gone. #undef PyIndex_Check LIBSHIBOKEN_API int PyIndex_Check(PyObject *obj); -#endif LIBSHIBOKEN_API PyObject *_PepType_Lookup(PyTypeObject *type, PyObject *name); diff --git a/sources/shiboken6/shibokenmodule/CMakeLists.txt b/sources/shiboken6/shibokenmodule/CMakeLists.txt index da534ba75..2d5276652 100644 --- a/sources/shiboken6/shibokenmodule/CMakeLists.txt +++ b/sources/shiboken6/shibokenmodule/CMakeLists.txt @@ -43,6 +43,10 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/_config.py.in" install(FILES "${CMAKE_CURRENT_BINARY_DIR}/_config.py" DESTINATION "${PYTHON_SITE_PACKAGES}/shiboken6") +if ("${MINIMUM_PYTHON_VERSION}" STREQUAL "") + set(MINIMUM_PYTHON_VERSION None) +endif() + # PYSIDE-1497: This `..` is the crucial trick to unify the path location of `Shiboken`. configure_file("${CMAKE_CURRENT_SOURCE_DIR}/__init__.py.in" "${CMAKE_CURRENT_BINARY_DIR}/../__init__.py" @ONLY) diff --git a/sources/shiboken6/shibokenmodule/__init__.py.in b/sources/shiboken6/shibokenmodule/__init__.py.in index 3dd59b024..ab95667da 100644 --- a/sources/shiboken6/shibokenmodule/__init__.py.in +++ b/sources/shiboken6/shibokenmodule/__init__.py.in @@ -1,5 +1,6 @@ __version__ = "@FINAL_PACKAGE_VERSION@" __version_info__ = (@shiboken_MAJOR_VERSION@, @shiboken_MINOR_VERSION@, @shiboken_MICRO_VERSION@, "@shiboken_PRE_RELEASE_VERSION_TYPE@", "@shiboken_PRE_RELEASE_VERSION@") +__minimum_python_version__ = @MINIMUM_PYTHON_VERSION@ # PYSIDE-932: Python 2 cannot import 'zipfile' for embedding while being imported, itself. # We simply pre-load all imports for the signature extension. diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py index 68d991049..86451f68f 100644 --- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py +++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py @@ -77,7 +77,7 @@ In effect, 'type_map' maps text to real Python objects. """ def _get_flag_enum_option(): - from shiboken6 import __version_info__ as ver + from shiboken6 import __version_info__ as ver, __minimum_python_version__ as pyminver # PYSIDE-1735: Use the new Enums per default if version is >= 6.4 # This decides between delivered vs. dev versions. # When 6.4 is out, the switching mode will be gone. @@ -97,10 +97,13 @@ def _get_flag_enum_option(): flag = bool(getattr(sys, sysname)) sysver = sys.version_info[:2] if flag and sysver < (3, 7): - import warnings warnings.warn(f"Enums with functional API are not supported in " f"Python {'.'.join(map(str, sysver))}") flag = False + # PYSIDE-1797: Emit a warning when we may remove pep384_issue33738.cpp + if pyminver and pyminver >= (3, 8): + warnings.warn(f"\n *** Python is at version {'.'.join(map(str, pyminver))} now. " + f"The file pep384_issue33738.cpp should be removed ASAP! ***") # modify the sys attribute to bool setattr(sys, sysname, flag) # modify the env attribute to "0" or "1" |