diff options
| author | Christian Tismer <tismer@stackless.com> | 2024-06-07 14:57:14 +0200 |
|---|---|---|
| committer | Christian Tismer <tismer@stackless.com> | 2024-06-12 09:41:45 +0200 |
| commit | ad18260e583a30505e42b04fd242c52ff36f735c (patch) | |
| tree | b214b18e06b9df8df41e61b9c043c8b5f8324e5b | |
| parent | 70b083842b95f3e11f315a2a0bdd5fe6b2ee705d (diff) | |
Do the transition to Python 3.13, GIL-part
* opcodes have changed numbers. That made "import *" etc. fail.
* PUSH_NULL is sometimes inserted before a call.
* enum_test needed an overhaul due to opcode changes.
Python 3.13 works fine.
Supporting --disable-gil is a different issue.
Task-number: PYSIDE-2751
Change-Id: I37b447148787e2923a58c091a5c8ac808d579bc0
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
| -rw-r--r-- | build_scripts/config.py | 1 | ||||
| -rw-r--r-- | sources/pyside6/tests/pysidetest/enum_test.py | 41 | ||||
| -rw-r--r-- | sources/shiboken6/libshiboken/sbkfeature_base.cpp | 21 | ||||
| -rw-r--r-- | sources/shiboken6/libshiboken/sbkmodule.cpp | 9 |
4 files changed, 53 insertions, 19 deletions
diff --git a/build_scripts/config.py b/build_scripts/config.py index 0a6eebf78..4b1d755a1 100644 --- a/build_scripts/config.py +++ b/build_scripts/config.py @@ -65,6 +65,7 @@ class Config(object): 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', + 'Programming Language :: Python :: 3.13', ] self.setup_script_dir = None diff --git a/sources/pyside6/tests/pysidetest/enum_test.py b/sources/pyside6/tests/pysidetest/enum_test.py index 832834530..7afc5b948 100644 --- a/sources/pyside6/tests/pysidetest/enum_test.py +++ b/sources/pyside6/tests/pysidetest/enum_test.py @@ -1,4 +1,4 @@ -# Copyright (C) 2022 The Qt Company Ltd. +# Copyright (C) 2024 The Qt Company Ltd. # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 import os @@ -50,6 +50,8 @@ class ListConnectionTest(unittest.TestCase): # PYSIDE-1735: We are testing that opcodes do what they are supposed to do. # This is needed in the PyEnum forgiveness mode where we need # to introspect the code if an Enum was called with no args. + +# flake8: noqa class InvestigateOpcodesTest(unittest.TestCase): def probe_function1(self): @@ -162,25 +164,40 @@ class InvestigateOpcodesTest(unittest.TestCase): self.assertEqual(self.read_code(self.probe_function2, adaptive=True), result_3) self.assertEqual(self.get_sizes(self.probe_function2, adaptive=True), sizes_3) - if sys.version_info[:2] >= (3, 12): + if sys.version_info[:2] == (3, 12): - result_1 = [('RESUME', 151, 0), - ('LOAD_GLOBAL', 116, 0), - ('LOAD_ATTR', 106, 2), - ('STORE_FAST', 125, 1), + result_1 = [('RESUME', 151, 0), + ('LOAD_GLOBAL', 116, 0), + ('LOAD_ATTR', 106, 2), + ('STORE_FAST', 125, 1), ('RETURN_CONST', 121, 0)] - result_2 = [('RESUME', 151, 0), - ('LOAD_GLOBAL', 116, 1), - ('LOAD_ATTR', 106, 2), - ('CALL', 171, 0), - ('STORE_FAST', 125, 1), + result_2 = [('RESUME', 151, 0), + ('LOAD_GLOBAL', 116, 1), + ('LOAD_ATTR', 106, 2), + ('CALL', 171, 0), + ('STORE_FAST', 125, 1), ('RETURN_CONST', 121, 0)] + if sys.version_info[:2] >= (3, 13): + + result_1 = [('RESUME', 149, 0), + ('LOAD_GLOBAL', 91, 0), + ('LOAD_ATTR', 82, 2), + ('STORE_FAST', 110, 1), + ('RETURN_CONST', 103, 0)] + + result_2 = [('RESUME', 149, 0), + ('LOAD_GLOBAL', 91, 0), + ('LOAD_ATTR', 82, 2), + ('PUSH_NULL', 34, None), + ('CALL', 53, 0), + ('STORE_FAST', 110, 1), + ('RETURN_CONST', 103, 0)] + self.assertEqual(self.read_code(self.probe_function1), result_1) self.assertEqual(self.read_code(self.probe_function2), result_2) if __name__ == '__main__': unittest.main() - diff --git a/sources/shiboken6/libshiboken/sbkfeature_base.cpp b/sources/shiboken6/libshiboken/sbkfeature_base.cpp index f31b8f4f7..971835c53 100644 --- a/sources/shiboken6/libshiboken/sbkfeature_base.cpp +++ b/sources/shiboken6/libshiboken/sbkfeature_base.cpp @@ -92,8 +92,12 @@ void disassembleFrame(const char *marker) PyErr_Restore(error_type, error_value, error_traceback); } -// python 3.12 -static int const CALL = 171; +// Python 3.13 +static int const LOAD_ATTR_313 = 82; +static int const CALL_313 = 53; +static int const PUSH_NULL_313 = 34; +// Python 3.12 +static int const CALL_312 = 171; // Python 3.11 static int const PRECALL = 166; // we have "big instructions" with gaps after them @@ -105,13 +109,16 @@ static int const LOAD_METHOD = 160; static int const CALL_METHOD = 161; // Python 3.6 static int const CALL_FUNCTION = 131; -static int const LOAD_ATTR = 106; +static int const LOAD_ATTR_312 = 106; // NoGil (how long will this exist in this form?) static int const LOAD_METHOD_NOGIL = 55; static int const CALL_METHOD_NOGIL = 72; static bool currentOpcode_Is_CallMethNoArgs() { + static auto number = _PepRuntimeVersion(); + static int LOAD_ATTR = number < 0x030D00 ? LOAD_ATTR_312 : LOAD_ATTR_313; + static int CALL = number < 0x030D00 ? CALL_312 : CALL_313; // PYSIDE-2221: Special case for the NoGil version: // Find out if we have such a version. // We could also ask the variable `Py_NOGIL`. @@ -148,7 +155,6 @@ static bool currentOpcode_Is_CallMethNoArgs() } uint8_t opcode2 = co_code[f_lasti + 2]; uint8_t oparg2 = co_code[f_lasti + 3]; - static auto number = _PepRuntimeVersion(); if (number < 0x030B00) return opcode1 == LOAD_METHOD && opcode2 == CALL_METHOD && oparg2 == 0; @@ -158,7 +164,7 @@ static bool currentOpcode_Is_CallMethNoArgs() // don't need to take care of them. if (opcode1 == LOAD_METHOD) f_lasti += LOAD_METHOD_GAP_311; - else if (opcode1 == LOAD_ATTR) + else if (opcode1 == LOAD_ATTR_312) f_lasti += LOAD_ATTR_GAP_311; else return false; @@ -176,6 +182,11 @@ static bool currentOpcode_Is_CallMethNoArgs() else return false; + if (number >= 0x030D00) { + int opcode3 = co_code[f_lasti + 2]; + if (opcode3 == PUSH_NULL_313) + f_lasti += 2; + } opcode2 = co_code[f_lasti + 2]; oparg2 = co_code[f_lasti + 3]; diff --git a/sources/shiboken6/libshiboken/sbkmodule.cpp b/sources/shiboken6/libshiboken/sbkmodule.cpp index f0136148b..a94fbe279 100644 --- a/sources/shiboken6/libshiboken/sbkmodule.cpp +++ b/sources/shiboken6/libshiboken/sbkmodule.cpp @@ -248,6 +248,9 @@ static PyMethodDef module_methods[] = { // Python 3.8 - 3.12 static int const LOAD_CONST_312 = 100; static int const IMPORT_NAME_312 = 108; +// Python 3.13 +static int const LOAD_CONST_313 = 83; +static int const IMPORT_NAME_313 = 75; static bool isImportStar(PyObject *module) { @@ -260,6 +263,9 @@ static bool isImportStar(PyObject *module) static PyObject *const _co_consts = Shiboken::String::createStaticString("co_consts"); static PyObject *const _co_names = Shiboken::String::createStaticString("co_names"); + static int LOAD_CONST = _PepRuntimeVersion() < 0x030D00 ? LOAD_CONST_312 : LOAD_CONST_313; + static int IMPORT_NAME = _PepRuntimeVersion() < 0x030D00 ? IMPORT_NAME_312 : IMPORT_NAME_313; + auto *obFrame = reinterpret_cast<PyObject *>(PyEval_GetFrame()); if (obFrame == nullptr) return true; // better assume worst-case. @@ -279,7 +285,7 @@ static bool isImportStar(PyObject *module) PyBytes_AsStringAndSize(dec_co_code, &co_code, &code_len); uint8_t opcode2 = co_code[f_lasti]; uint8_t opcode1 = co_code[f_lasti - 2]; - if (opcode1 == LOAD_CONST_312 && opcode2 == IMPORT_NAME_312) { + if (opcode1 == LOAD_CONST && opcode2 == IMPORT_NAME) { uint8_t oparg1 = co_code[f_lasti - 1]; uint8_t oparg2 = co_code[f_lasti + 1]; AutoDecRef dec_co_consts(PyObject_GetAttr(dec_f_code, _co_consts)); @@ -482,7 +488,6 @@ PyObject *create(const char * /* modName */, void *moduleData) Py_INCREF(origImportFunc); AutoDecRef func(PyCFunction_NewEx(lazy_methods, nullptr, nullptr)); PyDict_SetItemString(builtins, "__import__", func); - // Everything is set. lazy_init = true; } // PYSIDE-2404: Nuitka inserts some additional code in standalone mode |
