From d99b2feeb30fa772dca48345c8992b4eafdeac21 Mon Sep 17 00:00:00 2001 From: Abdul-Muqadim-Arbisoft Date: Thu, 11 Jan 2024 18:20:04 +0500 Subject: [PATCH 1/3] fix: remove pkg_resources for python 3.12 compatibility pkg_resources is available in python 3.12 only if setuptools is explicitely installed, which is not always the case. We fix that by replacing all usage of pkg_resources with importlib_resources and importlib_metadata. Close #966 --- ...202_153925_danyal.faheem_remove_pkg_resources.md | 1 + requirements/base.in | 2 ++ requirements/base.txt | 8 ++++++++ requirements/dev.txt | 8 ++++++-- requirements/docs.txt | 13 ++++++++++--- tutor.spec | 6 +++--- tutor/env.py | 4 ++-- tutor/plugins/v0.py | 13 ++++++------- tutor/plugins/v1.py | 11 ++++++----- 9 files changed, 44 insertions(+), 22 deletions(-) create mode 100644 changelog.d/20240202_153925_danyal.faheem_remove_pkg_resources.md diff --git a/changelog.d/20240202_153925_danyal.faheem_remove_pkg_resources.md b/changelog.d/20240202_153925_danyal.faheem_remove_pkg_resources.md new file mode 100644 index 0000000..d7cd4d9 --- /dev/null +++ b/changelog.d/20240202_153925_danyal.faheem_remove_pkg_resources.md @@ -0,0 +1 @@ +[Depreciation] Replace pkg_resources with importlib_metadata and importlib_resources. (by @Danyal-Faheem) \ No newline at end of file diff --git a/requirements/base.in b/requirements/base.in index eb60ad6..21e5098 100644 --- a/requirements/base.in +++ b/requirements/base.in @@ -6,3 +6,5 @@ mypy pycryptodome>=3.17.0 pyyaml>=6.0 typing-extensions>=4.4.0 +importlib-metadata>=7.0.1 +importlib-resources>=6.1.1 diff --git a/requirements/base.txt b/requirements/base.txt index 1526e68..37cdb88 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -20,6 +20,10 @@ google-auth==2.23.3 # via kubernetes idna==3.4 # via requests +importlib-metadata==7.0.1 + # via -r requirements/base.in +importlib-resources==6.1.1 + # via -r requirements/base.in jinja2==3.1.3 # via -r requirements/base.in kubernetes==28.1.0 @@ -72,3 +76,7 @@ urllib3==1.26.18 # requests websocket-client==1.6.4 # via kubernetes +zipp==3.17.0 + # via + # importlib-metadata + # importlib-resources diff --git a/requirements/dev.txt b/requirements/dev.txt index 3515973..5c6aba3 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -58,14 +58,17 @@ idna==3.4 # via # -r requirements/base.txt # requests -importlib-metadata==6.8.0 +importlib-metadata==7.0.1 # via + # -r requirements/base.txt # build # keyring # pyinstaller # twine importlib-resources==6.1.1 - # via keyring + # via + # -r requirements/base.txt + # keyring isort==5.12.0 # via pylint jaraco-classes==3.3.0 @@ -232,6 +235,7 @@ wheel==0.41.2 # via pip-tools zipp==3.17.0 # via + # -r requirements/base.txt # importlib-metadata # importlib-resources diff --git a/requirements/docs.txt b/requirements/docs.txt index 8acbfb5..4ca558d 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -42,8 +42,12 @@ idna==3.4 # requests imagesize==1.4.1 # via sphinx -importlib-metadata==6.8.0 - # via sphinx +importlib-metadata==7.0.1 + # via + # -r requirements/base.txt + # sphinx +importlib-resources==6.1.1 + # via -r requirements/base.txt jinja2==3.1.3 # via # -r requirements/base.txt @@ -153,4 +157,7 @@ websocket-client==1.6.4 # -r requirements/base.txt # kubernetes zipp==3.17.0 - # via importlib-metadata + # via + # -r requirements/base.txt + # importlib-metadata + # importlib-resources diff --git a/tutor.spec b/tutor.spec index f68c7c0..1e6f591 100644 --- a/tutor.spec +++ b/tutor.spec @@ -1,7 +1,7 @@ # -*- mode: python -*- import importlib import os -import pkg_resources +from importlib_metadata block_cipher = None @@ -10,10 +10,10 @@ hidden_imports = [] # Auto-discover plugins and include patches & templates folders for entrypoint_version in ["tutor.plugin.v0", "tutor.plugin.v1"]: - for entrypoint in pkg_resources.iter_entry_points(entrypoint_version): + for entrypoint in importlib_metadata.entry_points(group=entrypoint_version): plugin_name = entrypoint.name try: - plugin = entrypoint.load() + plugin = importlib.import_module(entrypoint.value) except Exception as e: print(f"ERROR Failed to load plugin {plugin_name}: {e}") continue diff --git a/tutor/env.py b/tutor/env.py index 5e668b8..470f9dc 100644 --- a/tutor/env.py +++ b/tutor/env.py @@ -7,13 +7,13 @@ import typing as t from copy import deepcopy import jinja2 -import pkg_resources +import importlib_resources from tutor import exceptions, fmt, hooks, plugins, utils from tutor.__about__ import __app__, __version__ from tutor.types import Config, ConfigValue -TEMPLATES_ROOT = pkg_resources.resource_filename("tutor", "templates") +TEMPLATES_ROOT = str(importlib_resources.files("tutor") / "templates") VERSION_FILENAME = "version" BIN_FILE_EXTENSIONS = [ ".ico", diff --git a/tutor/plugins/v0.py b/tutor/plugins/v0.py index 16e6770..b1cf0f7 100644 --- a/tutor/plugins/v0.py +++ b/tutor/plugins/v0.py @@ -5,7 +5,7 @@ import typing as t from glob import glob import click -import pkg_resources +import importlib_metadata from tutor import env, exceptions, fmt, hooks, serialize from tutor.__about__ import __app__ @@ -246,12 +246,12 @@ class EntrypointPlugin(BasePlugin): ENTRYPOINT = "tutor.plugin.v0" - def __init__(self, entrypoint: pkg_resources.EntryPoint) -> None: - self.loader: pkg_resources.EntryPoint + def __init__(self, entrypoint: importlib_metadata.EntryPoint) -> None: + self.loader: importlib_metadata.EntryPoint = entrypoint super().__init__(entrypoint.name, entrypoint) def _load_obj(self) -> None: - self.obj = self.loader.load() + self.obj = importlib.import_module(self.loader.value) def _version(self) -> t.Optional[str]: if not self.loader.dist: @@ -260,12 +260,11 @@ class EntrypointPlugin(BasePlugin): @classmethod def discover_all(cls) -> None: - for entrypoint in pkg_resources.iter_entry_points(cls.ENTRYPOINT): + entrypoints = importlib_metadata.entry_points(group=cls.ENTRYPOINT) + for entrypoint in entrypoints: try: error: t.Optional[str] = None cls(entrypoint) - except pkg_resources.VersionConflict as e: - error = e.report() except Exception as e: # pylint: disable=broad-except error = str(e) if error: diff --git a/tutor/plugins/v1.py b/tutor/plugins/v1.py index cf24bf0..88982b6 100644 --- a/tutor/plugins/v1.py +++ b/tutor/plugins/v1.py @@ -2,7 +2,7 @@ import importlib.util import os from glob import glob -import pkg_resources +import importlib_metadata from tutor import hooks @@ -26,7 +26,7 @@ def _discover_entrypoint_plugins() -> None: """ with hooks.Contexts.PLUGINS.enter(): if "TUTOR_IGNORE_ENTRYPOINT_PLUGINS" not in os.environ: - for entrypoint in pkg_resources.iter_entry_points("tutor.plugin.v1"): + for entrypoint in importlib_metadata.entry_points(group="tutor.plugin.v1"): discover_package(entrypoint) @@ -56,7 +56,7 @@ def discover_module(path: str) -> None: spec.loader.exec_module(module) -def discover_package(entrypoint: pkg_resources.EntryPoint) -> None: +def discover_package(entrypoint: importlib_metadata.EntryPoint) -> None: """ Install a plugin from a python package. """ @@ -68,10 +68,11 @@ def discover_package(entrypoint: pkg_resources.EntryPoint) -> None: # Add plugin information if entrypoint.dist is None: raise ValueError(f"Could not read plugin version: {name}") - hooks.Filters.PLUGINS_INFO.add_item((name, entrypoint.dist.version)) + dist_version = entrypoint.dist.version if entrypoint.dist else "Unknown" + hooks.Filters.PLUGINS_INFO.add_item((name, dist_version)) # Import module on enable @hooks.Actions.PLUGIN_LOADED.add() def load(plugin_name: str) -> None: if name == plugin_name: - entrypoint.load() + importlib.import_module(entrypoint.value) From 439b7d08f0585dd765feb4e2f450ea4bea82320e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20Behmo?= Date: Fri, 9 Feb 2024 22:15:43 +0100 Subject: [PATCH 2/3] feat: upgrade to quince.2 --- changelog.d/20240209_220759_regis.md | 1 + tutor/templates/build/openedx/Dockerfile | 2 -- tutor/templates/config/defaults.yml | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) create mode 100644 changelog.d/20240209_220759_regis.md diff --git a/changelog.d/20240209_220759_regis.md b/changelog.d/20240209_220759_regis.md new file mode 100644 index 0000000..bb40ed3 --- /dev/null +++ b/changelog.d/20240209_220759_regis.md @@ -0,0 +1 @@ +- [Improvement] Upgrade base release to open-release/quince.2. (by @regisb) diff --git a/tutor/templates/build/openedx/Dockerfile b/tutor/templates/build/openedx/Dockerfile index 51e7db4..0aef8e8 100644 --- a/tutor/templates/build/openedx/Dockerfile +++ b/tutor/templates/build/openedx/Dockerfile @@ -51,8 +51,6 @@ RUN git config --global user.email "tutor@overhang.io" \ {{ patch("openedx-dockerfile-git-patches-default") }} {%- else %} # Patch edx-platform -# XBlock JWT security fix https://github.com/openedx/edx-platform/pull/34047 -RUN curl -fsSL https://github.com/openedx/edx-platform/commit/89f5f69682a5e1422f89e867491e8974dd0a8208.patch | git am {%- endif %} {# Example: RUN curl -fsSL https://github.com/openedx/edx-platform/commit/.patch | git am #} diff --git a/tutor/templates/config/defaults.yml b/tutor/templates/config/defaults.yml index 9ab1967..d0d3a31 100644 --- a/tutor/templates/config/defaults.yml +++ b/tutor/templates/config/defaults.yml @@ -59,7 +59,7 @@ OPENEDX_LMS_UWSGI_WORKERS: 2 OPENEDX_MYSQL_DATABASE: "openedx" OPENEDX_MYSQL_USERNAME: "openedx" # the common version will be automatically set to "master" in the nightly branch -OPENEDX_COMMON_VERSION: "open-release/quince.1" +OPENEDX_COMMON_VERSION: "open-release/quince.2" OPENEDX_EXTRA_PIP_REQUIREMENTS: [] MYSQL_HOST: "mysql" MYSQL_PORT: 3306 From b2b373f534ce78f8c86bc3f5a4eac970505acc0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20Behmo?= Date: Fri, 9 Feb 2024 22:24:04 +0100 Subject: [PATCH 3/3] v17.0.2 --- CHANGELOG.md | 16 ++++++++++++++++ .../20240110_101228_kyle_importnewdemocourse.md | 7 ------- ...29_144929_kshitij_fix_tutor_docker_compose.md | 2 -- .../20240130_123351_regis_fix_save_on_plugins.md | 2 -- ..._153925_danyal.faheem_remove_pkg_resources.md | 1 - changelog.d/20240209_220759_regis.md | 1 - tutor/__about__.py | 2 +- 7 files changed, 17 insertions(+), 14 deletions(-) delete mode 100644 changelog.d/20240110_101228_kyle_importnewdemocourse.md delete mode 100644 changelog.d/20240129_144929_kshitij_fix_tutor_docker_compose.md delete mode 100644 changelog.d/20240130_123351_regis_fix_save_on_plugins.md delete mode 100644 changelog.d/20240202_153925_danyal.faheem_remove_pkg_resources.md delete mode 100644 changelog.d/20240209_220759_regis.md diff --git a/CHANGELOG.md b/CHANGELOG.md index f0146df..1101120 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,22 @@ instructions, because git commits are used to generate release notes: + +## v17.0.2 (2024-02-09) + +- [Feature] Several enhancements to the Demo Course (by @kdmccormick): + - The [Open edX Demo Course](https://github.com/openedx/openedx-demo-course) has been re-built from scratch with up-to-date instruction-focused content. Its directory structure has changed. + - In order to support both the old and new structures of the Demo Course's repository, the command `tutor local do importdemocourse` will now auto-determine the course root based on the location of `course.xml`. Use the `--repo-dir` argument to override this behavior. + - The new command `tutor local do importdemolibraries` will import any content libraries defined within the Demo Course repository. At the moment, that is just the "Respiratory System Question Bank", which is an optional but helpful extension to the new Demo Course. + - To try out the new Demo Course now, run: `tutor local do importdemocourse --version master`. + - To try out the demo Respiratory System Question Bank now, run: `tutor local do importdemolibraries --version master`. + - To revert back to an older Demo Course version at any point, run: `tutor local do importdemocourse --version open-release/quince.2`, replacing `quince.2` with your preferred course version. +- [Bugfix] Remove duplicate volume declarations that cause `docker compose` v2.24.1 to fail. +- [Bugfix] Actually update the environment on `tutor plugins enable ...`. (by @regisb) +- [Feature] Introduce a `tutor.hooks.lru_cache` decorator that is automatically cleared whenever a plugin is loaded or unloaded. This is useful, in particular when a plugin implements a costly function that depends on tutor hooks. (by @regisb) +- [Bugfix] Fix compatibility with Python 3.12 by replacing pkg_resources with importlib_metadata and importlib_resources. (by @Danyal-Faheem) +- [Improvement] Upgrade base release to open-release/quince.2. (by @regisb) + ## v17.0.1 (2024-01-25) diff --git a/changelog.d/20240110_101228_kyle_importnewdemocourse.md b/changelog.d/20240110_101228_kyle_importnewdemocourse.md deleted file mode 100644 index 79a7d44..0000000 --- a/changelog.d/20240110_101228_kyle_importnewdemocourse.md +++ /dev/null @@ -1,7 +0,0 @@ -- [Feature] Several enhancements to the Demo Course (by @kdmccormick): - - The [Open edX Demo Course](https://github.com/openedx/openedx-demo-course) has been re-built from scratch with up-to-date instruction-focused content. Its directory structure has changed. - - In order to support both the old and new structures of the Demo Course's repository, the command `tutor local do importdemocourse` will now auto-determine the course root based on the location of `course.xml`. Use the `--repo-dir` argument to override this behavior. - - The new command `tutor local do importdemolibraries` will import any content libraries defined within the Demo Course repository. At the moment, that is just the "Respiratory System Question Bank", which is an optional but helpful extension to the new Demo Course. - - To try out the new Demo Course now, run: `tutor local do importdemocourse --version master`. - - To try out the demo Respiratory System Question Bank now, run: `tutor local do importdemolibraries --version master`. - - To revert back to an older Demo Course version at any point, run: `tutor local do importdemocourse --version open-release/quince.2`, replacing `quince.2` with your preferred course version. diff --git a/changelog.d/20240129_144929_kshitij_fix_tutor_docker_compose.md b/changelog.d/20240129_144929_kshitij_fix_tutor_docker_compose.md deleted file mode 100644 index 4a9625c..0000000 --- a/changelog.d/20240129_144929_kshitij_fix_tutor_docker_compose.md +++ /dev/null @@ -1,2 +0,0 @@ -- [Bugfix] Fixes duplicate volume declarations causing Tutor commands that - invoke Docker to fail. \ No newline at end of file diff --git a/changelog.d/20240130_123351_regis_fix_save_on_plugins.md b/changelog.d/20240130_123351_regis_fix_save_on_plugins.md deleted file mode 100644 index 164dd81..0000000 --- a/changelog.d/20240130_123351_regis_fix_save_on_plugins.md +++ /dev/null @@ -1,2 +0,0 @@ -- [Bugfix] Actually update the environment on `tutor plugins enable ...`. (by @regisb) -- [Feature] Introduce a `tutor.hooks.lru_cache` decorator that is automatically cleared whenever a plugin is loaded or unloaded. This is useful, in particular when a plugin implements a costly function that depends on tutor hooks. (by @regisb) diff --git a/changelog.d/20240202_153925_danyal.faheem_remove_pkg_resources.md b/changelog.d/20240202_153925_danyal.faheem_remove_pkg_resources.md deleted file mode 100644 index d7cd4d9..0000000 --- a/changelog.d/20240202_153925_danyal.faheem_remove_pkg_resources.md +++ /dev/null @@ -1 +0,0 @@ -[Depreciation] Replace pkg_resources with importlib_metadata and importlib_resources. (by @Danyal-Faheem) \ No newline at end of file diff --git a/changelog.d/20240209_220759_regis.md b/changelog.d/20240209_220759_regis.md deleted file mode 100644 index bb40ed3..0000000 --- a/changelog.d/20240209_220759_regis.md +++ /dev/null @@ -1 +0,0 @@ -- [Improvement] Upgrade base release to open-release/quince.2. (by @regisb) diff --git a/tutor/__about__.py b/tutor/__about__.py index 3b0f631..c49850a 100644 --- a/tutor/__about__.py +++ b/tutor/__about__.py @@ -2,7 +2,7 @@ import os # Increment this version number to trigger a new release. See # docs/tutor.html#versioning for information on the versioning scheme. -__version__ = "17.0.1" +__version__ = "17.0.2" # The version suffix will be appended to the actual version, separated by a # dash. Use this suffix to differentiate between the actual released version and