From 877ad239519f8c6e0747c1916f52d716a31aec0a Mon Sep 17 00:00:00 2001 From: Stanislav Levin Date: Thu, 7 Nov 2024 21:45:22 +0300 Subject: [PATCH] maintenance: drop support for EOL-d Python 3.8 According to Python life cycle: https://devguide.python.org/versions/ https://peps.python.org/pep-0569/ > As of 2024-10-07, 3.8 has reached the end-of-life phase of its release cycle. 3.8.20 was the final security release. The codebase for 3.8 is now frozen and no further updates will be provided nor issues of any kind will be accepted on the bug tracker. - require Python 3.9+ - cleaned up the code needed only for Python 3.8 support - run CI for Python 3.9+ Fixes: https://github.com/stanislavlevin/pyproject_installer/issues/83 Signed-off-by: Stanislav Levin --- .github/workflows/pipelines.yml | 8 ++--- backend/wheel.py | 7 ++-- pyproject.toml | 3 +- src/pyproject_installer/build_cmd/_build.py | 38 ++++++++++----------- src/pyproject_installer/lib/entry_points.py | 17 +-------- src/pyproject_installer/lib/wheel.py | 15 +++----- src/pyproject_installer/run_cmd/_run_env.py | 8 +---- tests/conftest.py | 7 ++-- tests/integration/conftest.py | 4 --- 9 files changed, 37 insertions(+), 70 deletions(-) diff --git a/.github/workflows/pipelines.yml b/.github/workflows/pipelines.yml index 91a786b..67b43cb 100644 --- a/.github/workflows/pipelines.yml +++ b/.github/workflows/pipelines.yml @@ -33,7 +33,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13'] + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v4 @@ -63,7 +63,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13'] + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v4 @@ -93,7 +93,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13'] + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v4 @@ -122,7 +122,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13'] + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 diff --git a/backend/wheel.py b/backend/wheel.py index c58a6a5..e3c76b1 100644 --- a/backend/wheel.py +++ b/backend/wheel.py @@ -170,9 +170,10 @@ def package_record(self): zinfo.compress_type = ZIP_DEFLATED self.records.append((str(dist_info_record), "", "")) - with self._zipfile.open(zinfo, "w") as f, TextIOWrapper( - f, encoding="utf-8", newline="" - ) as csvf: + with ( + self._zipfile.open(zinfo, "w") as f, + TextIOWrapper(f, encoding="utf-8", newline="") as csvf, + ): writer = csv.writer(csvf, lineterminator="\n") writer.writerows(self.records) diff --git a/pyproject.toml b/pyproject.toml index 3e88c06..4d9d23d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ name = "pyproject-installer" description = "Pyproject installer" readme = "README.md" -requires-python = ">=3.8" +requires-python = ">=3.9" license = {text = "MIT"} authors = [ {name = "Stanislav Levin", email = "slev@altlinux.org"}, @@ -15,7 +15,6 @@ classifiers = [ "Operating System :: Unix", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", diff --git a/src/pyproject_installer/build_cmd/_build.py b/src/pyproject_installer/build_cmd/_build.py index ae746c0..7356cfb 100644 --- a/src/pyproject_installer/build_cmd/_build.py +++ b/src/pyproject_installer/build_cmd/_build.py @@ -116,16 +116,18 @@ def build_metadata(srcdir, outdir, config=None, verbose=False): hook = "prepare_metadata_for_build_wheel" logger.info("Building metadata with %s", hook) - with build_out_tmpdir(srcdir, hook, config, verbose) as ( - distinfo_dir, - tmp_path, + with ( + build_out_tmpdir(srcdir, hook, config, verbose) as ( + distinfo_dir, + tmp_path, + ), ): if distinfo_dir: metadata_path_src = tmp_path / distinfo_dir / metadata_filename - # Python 3.8 syntax - with metadata_path_src.open( - mode="rb" - ) as fsrc, metadata_path_dest.open(mode="wb") as fdst: + with ( + metadata_path_src.open(mode="rb") as fsrc, + metadata_path_dest.open(mode="wb") as fdst, + ): shutil.copyfileobj(fsrc, fdst) return metadata_filename @@ -133,22 +135,18 @@ def build_metadata(srcdir, outdir, config=None, verbose=False): # fallback to build_wheel hook = "build_wheel" logger.info("Fallback to building metadata with %s", hook) - with build_out_tmpdir(srcdir, hook, config, verbose) as ( - wheel_filename, - tmp_path, + with ( + build_out_tmpdir(srcdir, hook, config, verbose) as ( + wheel_filename, + tmp_path, + ), ): wheel_path = tmp_path / wheel_filename with WheelFile(wheel_path) as whl: metadata_path_src = whl.dist_info / metadata_filename - if sys.version_info > (3, 9): - # Python3.9: zipfile.Path.open opens in text mode by default - mode = "rb" - else: - # Python3.8: zipfile.Path.open supports only binary mode - mode = "r" - # Python 3.8 syntax - with metadata_path_src.open( - mode=mode - ) as fsrc, metadata_path_dest.open(mode="wb") as fdst: + with ( + metadata_path_src.open(mode="rb") as fsrc, + metadata_path_dest.open(mode="wb") as fdst, + ): shutil.copyfileobj(fsrc, fdst) return metadata_filename diff --git a/src/pyproject_installer/lib/entry_points.py b/src/pyproject_installer/lib/entry_points.py index 3d0878f..28d2aca 100644 --- a/src/pyproject_installer/lib/entry_points.py +++ b/src/pyproject_installer/lib/entry_points.py @@ -1,7 +1,6 @@ def parse_entry_points(distr, group): """ Compat only. - - module and attr attributes of ep are available since Python 3.9 - "selectable" entry points were introduced in Python 3.10 """ distr_eps = distr.entry_points @@ -13,18 +12,4 @@ def parse_entry_points(distr, group): else: eps = distr_eps.select(group=group) - for ep in eps: - try: - # module is available since Python 3.9 - ep_module = ep.module - except AttributeError: - ep_match = ep.pattern.match(ep.value) - ep_module = ep_match.group("module") - - try: - # attr is available since Python 3.9 - ep_attr = ep.attr - except AttributeError: - ep_attr = ep_match.group("attr") - - yield (ep.name, ep.value, ep_module, ep_attr) + yield from ((ep.name, ep.value, ep.module, ep.attr) for ep in eps) diff --git a/src/pyproject_installer/lib/wheel.py b/src/pyproject_installer/lib/wheel.py index ad7acff..f58cb86 100644 --- a/src/pyproject_installer/lib/wheel.py +++ b/src/pyproject_installer/lib/wheel.py @@ -7,7 +7,6 @@ import csv import hashlib import logging -import sys from ..errors import WheelFileError from .entry_points import parse_entry_points @@ -151,16 +150,10 @@ def validate_record(self): record_path = self.dist_info / "RECORD" recorded_files = set() - if sys.version_info > (3, 9): - # since Python3.9 zipfile.Path.open opens in text mode by default - mode = "rb" - else: - # while Python3.8 zipfile.Path.open supports only binary mode - mode = "r" - - with record_path.open(mode=mode) as csvbf, TextIOWrapper( - csvbf, encoding="utf-8", newline="" - ) as csvf: + with ( + record_path.open(mode="rb") as csvbf, + TextIOWrapper(csvbf, encoding="utf-8", newline="") as csvf, + ): reader = csv.reader(csvf) for row in reader: # path, hash and size diff --git a/src/pyproject_installer/run_cmd/_run_env.py b/src/pyproject_installer/run_cmd/_run_env.py index a47ec95..f0b446e 100644 --- a/src/pyproject_installer/run_cmd/_run_env.py +++ b/src/pyproject_installer/run_cmd/_run_env.py @@ -33,19 +33,13 @@ def __init__(self, wheel): "clear": True, "upgrade": False, "with_pip": False, + "upgrade_deps": False, } - if sys.version_info > (3, 9): - # New in version 3.9: Added the upgrade_deps parameter - venv_kwargs["upgrade_deps"] = False super().__init__(**venv_kwargs) def ensure_directories(self, *args, **kwargs): # save context for reusage self.context = super().ensure_directories(*args, **kwargs) - # env_exec_cmd requires Python3.9+ (https://bugs.python.org/issue45337), - # for non-windows systems: context.env_exec_cmd = context.env_exe - if not hasattr(self.context, "env_exec_cmd"): - self.context.env_exec_cmd = self.context.env_exe return self.context def install_console_scripts(self, context): diff --git a/tests/conftest.py b/tests/conftest.py index 3477d19..de6a978 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -75,9 +75,10 @@ def update_record(self): self.record = ws.getvalue() def drop_from_record(self, file): - with StringIO(self.record, newline="") as rs, StringIO( - newline="" - ) as ws: + with ( + StringIO(self.record, newline="") as rs, + StringIO(newline="") as ws, + ): reader = csv.reader(rs) writer = csv.writer(ws, lineterminator="\n") for row in reader: diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 4371046..40e6587 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -21,10 +21,6 @@ def __init__(self, *args, **kwargs): def ensure_directories(self, *args, **kwargs): # save context for reusage self.context = super().ensure_directories(*args, **kwargs) - # env_exec_cmd requires Python3.9+ (https://bugs.python.org/issue45337), - # for non-windows systems: context.env_exec_cmd = context.env_exe - if not hasattr(self.context, "env_exec_cmd"): - self.context.env_exec_cmd = self.context.env_exe return self.context