fix: remove pkg_resources for compatibility with python 3.12

pkg_resources is a package that is unavailable in python 3.12, unless
setuptools is explicitely installed. Turns out, there are replacement
functions coming from importlib_resources, which can be obtained from
the importlib-resources pypi package. This package will be installed
with tutor starting from 17.0.2.
This commit is contained in:
Régis Behmo 2024-02-06 11:41:23 +01:00
parent 02c7719c32
commit d1c67f42d9
2 changed files with 15 additions and 27 deletions

View File

@ -0,0 +1 @@
- [Bugfix] Make plugin compatible with Python 3.12 by removing dependency on `pkg_resources`. (by @regisb)

View File

@ -6,10 +6,9 @@ from glob import glob
from typing import Any, Literal, Optional, Union from typing import Any, Literal, Optional, Union
import click import click
import pkg_resources import importlib_resources
import requests # type: ignore import requests # type: ignore
from tutor import config as tutor_config from tutor import config as tutor_config
from tutor.__about__ import __version_suffix__
from tutor import exceptions from tutor import exceptions
from tutor import hooks as tutor_hooks from tutor import hooks as tutor_hooks
from tutor.__about__ import __version_suffix__ from tutor.__about__ import __version_suffix__
@ -39,22 +38,17 @@ config: dict[str, dict[str, Any]] = {
} }
# Initialization hooks # Initialization hooks
# For each service that needs to be initialized, we load the task template
# To add a custom initialization task, create a bash script template under:
# tutorxqueue/templates/xqueue/tasks/
# and then add it to the MY_INIT_TASKS list. Each task is in the format:
# ("<service>", ("<path>", "<to>", "<script>", "<template>"))
MY_INIT_TASKS: list[tuple[str, tuple[str, ...]]] = [
("mysql", ("xqueue", "tasks", "mysql", "init")),
("xqueue", ("xqueue", "tasks", "xqueue", "init")),
]
# For each task added to MY_INIT_TASKS, we load the task template
# and add it to the CLI_DO_INIT_TASKS filter, which tells Tutor to # and add it to the CLI_DO_INIT_TASKS filter, which tells Tutor to
# run it as part of the `init` job. # run it as part of the `init` job.
for service, template_path in MY_INIT_TASKS: for service in ["mysql", "xqueue"]:
full_path: str = pkg_resources.resource_filename( full_path: str = str(
"tutorxqueue", os.path.join("templates", *template_path) importlib_resources.files("tutorxqueue")
/ "templates"
/ "xqueue"
/ "tasks"
/ service
/ "init"
) )
with open(full_path, encoding="utf-8") as init_task_file: with open(full_path, encoding="utf-8") as init_task_file:
init_task: str = init_task_file.read() init_task: str = init_task_file.read()
@ -185,7 +179,7 @@ class Client:
if not self.base_url: if not self.base_url:
scheme = "https" if user_config["ENABLE_HTTPS"] else "http" scheme = "https" if user_config["ENABLE_HTTPS"] else "http"
host = user_config["XQUEUE_HOST"] host = user_config["XQUEUE_HOST"]
self.base_url = "{}://{}".format(scheme, host) self.base_url = f"{scheme}://{host}"
self.login() self.login()
@property @property
@ -208,9 +202,7 @@ class Client:
message = response.get("content") message = response.get("content")
if message != "Logged in": if message != "Logged in":
raise exceptions.TutorError( raise exceptions.TutorError(
"Could not login to xqueue server at {}. Response: '{}'".format( f"Could not login to xqueue server at {self.base_url}. Response: '{message}'"
self.base_url, message
)
) )
def show_submission(self, queue: str) -> Union[dict[str, Any], Any]: def show_submission(self, queue: str) -> Union[dict[str, Any], Any]:
@ -280,7 +272,7 @@ command.add_command(submissions)
# Add the "templates" folder as a template root # Add the "templates" folder as a template root
tutor_hooks.Filters.ENV_TEMPLATE_ROOTS.add_item( tutor_hooks.Filters.ENV_TEMPLATE_ROOTS.add_item(
pkg_resources.resource_filename("tutorxqueue", "templates") str(importlib_resources.files("tutorxqueue") / "templates")
) )
# Render the "build" and "apps" folders # Render the "build" and "apps" folders
tutor_hooks.Filters.ENV_TEMPLATE_TARGETS.add_items( tutor_hooks.Filters.ENV_TEMPLATE_TARGETS.add_items(
@ -290,12 +282,7 @@ tutor_hooks.Filters.ENV_TEMPLATE_TARGETS.add_items(
], ],
) )
# Load patches from files # Load patches from files
for path in glob( for path in glob(str(importlib_resources.files("tutorxqueue") / "patches" / "*")):
os.path.join(
pkg_resources.resource_filename("tutorxqueue", "patches"),
"*",
)
):
with open(path, encoding="utf-8") as patch_file: with open(path, encoding="utf-8") as patch_file:
tutor_hooks.Filters.ENV_PATCHES.add_item( tutor_hooks.Filters.ENV_PATCHES.add_item(
(os.path.basename(path), patch_file.read()) (os.path.basename(path), patch_file.read())