From 29c5148598b5e48e505da3d620d9a30c49f1da0b Mon Sep 17 00:00:00 2001 From: Florian Apolloner Date: Wed, 24 Apr 2024 20:04:48 +0200 Subject: [PATCH] Implement Python 3.12 compatible loader. Fixes #130. (#131) --- .github/workflows/build.yaml | 2 +- README.md | 4 +-- docs/index.rst | 6 +++-- src/qrc_importer.py | 47 ++++++++++++++++++++++-------------- 4 files changed, 36 insertions(+), 23 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 2f180c8..066a5dd 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -28,7 +28,7 @@ jobs: - name: Install dependencies (macOS) if: matrix.os == 'macos-latest' run: | - brew install qt@5 python@3.8 + brew install qt@5 python@3.12 echo PATH=/usr/local/opt/qt@5/bin:$PATH >> ${GITHUB_ENV} - run: qmake - run: make diff --git a/README.md b/README.md index fdaeaf8..b92a771 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Requirements ------------ * Qt 5.1.0 or newer (Qt 6.x also supported) -* Python 3.3.0 or newer +* Python 3.8.0 or newer Building @@ -28,7 +28,7 @@ make install To build against a specific Python version, use: ``` -qmake PYTHON_CONFIG=python3.3-config # use "qmake6" for Qt 6 +qmake PYTHON_CONFIG=python3.8-config # use "qmake6" for Qt 6 make make install ``` diff --git a/docs/index.rst b/docs/index.rst index 6b901b0..06f0d43 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1169,7 +1169,7 @@ Building PyOtherSide The following build requirements have to be satisfied to build PyOtherSide: * Qt 5.1.0 or newer (Qt 6.x also supported) -* Python 3.3.0 or newer +* Python 3.8.0 or newer If you have the required build-dependencies installed, building and installing the PyOtherSide plugin should be as simple as: @@ -1185,7 +1185,7 @@ pass a suitable ``python-config`` to ``qmake`` at configure time: .. code-block:: sh - qmake PYTHON_CONFIG=python3.3-config # For Qt 6, use "qmake6" + qmake PYTHON_CONFIG=python3.8-config # For Qt 6, use "qmake6" make make install @@ -1199,6 +1199,8 @@ ChangeLog Version UNRELEASED (YYYY-MM-DD) ------------------------------- +* Dropped support for Python < 3.8 (PR#131) +* Added support for Python 3.12 (PR#131) * Support for Qt 6.5 and newer (backwards-incompatible ``Q_RETURN_ARG()`` change) (fixes #128) Version 1.6.0 (2022-08-05) diff --git a/src/qrc_importer.py b/src/qrc_importer.py index 1a4a123..af51a98 100644 --- a/src/qrc_importer.py +++ b/src/qrc_importer.py @@ -16,32 +16,43 @@ # import sys +from importlib import abc +from importlib.util import spec_from_loader + import pyotherside -from importlib import abc -class PyOtherSideQtRCImporter(abc.MetaPathFinder, abc.SourceLoader): - def find_module(self, fullname, path): - if path is None or all(x.startswith('qrc:') for x in path): - if self.get_filename(fullname): - return self +def get_filename(fullname): + basename = fullname.replace(".", "/") - def get_filename(self, fullname): - basename = fullname.replace('.', '/') + for import_path in sys.path: + if not import_path.startswith("qrc:"): + continue + + for candidate in ("{}/{}.py", "{}/{}/__init__.py"): + filename = candidate.format(import_path, basename) + if pyotherside.qrc_is_file(filename[len("qrc:") :]): + return filename - for import_path in sys.path: - if not import_path.startswith('qrc:'): - continue - for candidate in ('{}/{}.py', '{}/{}/__init__.py'): - filename = candidate.format(import_path, basename) - if pyotherside.qrc_is_file(filename[len('qrc:'):]): - return filename +class PyOtherSideQtRCLoader(abc.SourceLoader): + def __init__(self, filepath): + self.filepath = filepath def get_data(self, path): - return pyotherside.qrc_get_file_contents(path[len('qrc:'):]) + return pyotherside.qrc_get_file_contents(self.filepath[len("qrc:") :]) + + def get_filename(self, fullname): + return get_filename(fullname) + + +class PyOtherSideQtRCImporter(abc.MetaPathFinder): + def find_spec(self, fullname, path, target=None): + if path is None: + fname = get_filename(fullname) + if fname: + return spec_from_loader(fullname, PyOtherSideQtRCLoader(fname)) + return None - def module_repr(self, m): - return "".format(m.__name__, m.__file__) sys.meta_path.append(PyOtherSideQtRCImporter())