From 7a48c235a90669fe7c003d7502f9245daebeac86 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Fri, 6 Dec 2024 12:37:17 -0800 Subject: [PATCH] remove importlib_resources (#10076) this is part of my work on https://github.com/certbot/certbot/issues/10035 based on erica's comment at https://github.com/certbot/certbot/issues/10035#issuecomment-2452212686 --- acme/acme/_internal/tests/test_util.py | 8 ++--- acme/setup.py | 9 ------ .../certbot_apache/_internal/apache_util.py | 12 ++----- .../certbot_apache/_internal/constants.py | 10 ++---- .../_internal/tests/configurator_test.py | 9 ++---- certbot-apache/setup.py | 1 - .../nginx_tests/nginx_config.py | 15 +++------ .../rfc2136_tests/context.py | 11 ++----- .../utils/dns_server.py | 10 ++---- .../certbot_integration_tests/utils/misc.py | 14 +++------ .../utils/pebble_artifacts.py | 11 ++----- certbot-ci/setup.py | 1 - .../certbot_nginx/_internal/configurator.py | 11 ++----- .../_internal/tests/configurator_test.py | 11 +++---- .../_internal/tests/test_util.py | 10 ++---- certbot-nginx/setup.py | 1 - certbot/CHANGELOG.md | 1 + certbot/certbot/_internal/constants.py | 11 ++----- certbot/certbot/plugins/common.py | 11 ++----- certbot/certbot/tests/util.py | 12 +++---- certbot/setup.py | 1 - tools/oldest_constraints.txt | 1 - tools/requirements.txt | 31 +++++++++---------- 23 files changed, 66 insertions(+), 146 deletions(-) diff --git a/acme/acme/_internal/tests/test_util.py b/acme/acme/_internal/tests/test_util.py index 2ba00d345..7a2789ba6 100644 --- a/acme/acme/_internal/tests/test_util.py +++ b/acme/acme/_internal/tests/test_util.py @@ -3,6 +3,7 @@ .. warning:: This module is not part of the public API. """ +import importlib.resources import os import sys @@ -12,16 +13,11 @@ import josepy as jose from josepy.util import ComparableECKey from OpenSSL import crypto -if sys.version_info >= (3, 9): # pragma: no cover - import importlib.resources as importlib_resources -else: # pragma: no cover - import importlib_resources - def load_vector(*names): """Load contents of a test vector.""" # luckily, resource_string opens file in binary mode - vector_ref = importlib_resources.files(__package__).joinpath('testdata', *names) + vector_ref = importlib.resources.files(__package__).joinpath('testdata', *names) return vector_ref.read_bytes() diff --git a/acme/setup.py b/acme/setup.py index c060b6e98..73cb5edd8 100644 --- a/acme/setup.py +++ b/acme/setup.py @@ -23,15 +23,6 @@ docs_extras = [ ] test_extras = [ - # In theory we could scope importlib_resources to env marker 'python_version<"3.9"'. But this - # makes the pinning mechanism emit warnings when running `poetry lock` because in the corner - # case of an extra dependency with env marker coming from a setup.py file, it generate the - # invalid requirement 'importlib_resource>=1.3.1;python<=3.9;extra=="test"'. - # To fix the issue, we do not pass the env marker. This is fine because: - # - importlib_resources can be applied to any Python version, - # - this is a "test" extra dependency for limited audience, - # - it does not change anything at the end for the generated requirement files. - 'importlib_resources>=1.3.1', 'pytest', 'pytest-xdist', 'typing-extensions', diff --git a/certbot-apache/certbot_apache/_internal/apache_util.py b/certbot-apache/certbot_apache/_internal/apache_util.py index 3303f452b..fded3add4 100644 --- a/certbot-apache/certbot_apache/_internal/apache_util.py +++ b/certbot-apache/certbot_apache/_internal/apache_util.py @@ -2,10 +2,10 @@ import atexit import binascii import fnmatch +import importlib.resources import logging import re import subprocess -import sys from contextlib import ExitStack from typing import Dict from typing import Iterable @@ -17,12 +17,6 @@ from certbot import errors from certbot import util from certbot.compat import os -if sys.version_info >= (3, 9): # pragma: no cover - import importlib.resources as importlib_resources -else: # pragma: no cover - import importlib_resources - - logger = logging.getLogger(__name__) @@ -257,6 +251,6 @@ def find_ssl_apache_conf(prefix: str) -> str: """ file_manager = ExitStack() atexit.register(file_manager.close) - ref = (importlib_resources.files("certbot_apache").joinpath("_internal") + ref = (importlib.resources.files("certbot_apache").joinpath("_internal") .joinpath("tls_configs").joinpath("{0}-options-ssl-apache.conf".format(prefix))) - return str(file_manager.enter_context(importlib_resources.as_file(ref))) + return str(file_manager.enter_context(importlib.resources.as_file(ref))) diff --git a/certbot-apache/certbot_apache/_internal/constants.py b/certbot-apache/certbot_apache/_internal/constants.py index 8e2aa3769..2057e4159 100644 --- a/certbot-apache/certbot_apache/_internal/constants.py +++ b/certbot-apache/certbot_apache/_internal/constants.py @@ -1,14 +1,10 @@ """Apache plugin constants.""" import atexit -import sys +import importlib.resources from contextlib import ExitStack from typing import Dict from typing import List -if sys.version_info >= (3, 9): # pragma: no cover - import importlib.resources as importlib_resources -else: # pragma: no cover - import importlib_resources MOD_SSL_CONF_DEST = "options-ssl-apache.conf" """Name of the mod_ssl config file as saved @@ -46,8 +42,8 @@ def _generate_augeas_lens_dir_static() -> str: # Python process, and will be automatically cleaned up on exit. file_manager = ExitStack() atexit.register(file_manager.close) - augeas_lens_dir_ref = importlib_resources.files("certbot_apache") / "_internal" / "augeas_lens" - return str(file_manager.enter_context(importlib_resources.as_file(augeas_lens_dir_ref))) + augeas_lens_dir_ref = importlib.resources.files("certbot_apache") / "_internal" / "augeas_lens" + return str(file_manager.enter_context(importlib.resources.as_file(augeas_lens_dir_ref))) AUGEAS_LENS_DIR = _generate_augeas_lens_dir_static() """Path to the Augeas lens directory""" diff --git a/certbot-apache/certbot_apache/_internal/tests/configurator_test.py b/certbot-apache/certbot_apache/_internal/tests/configurator_test.py index e17d93135..858bb63a2 100644 --- a/certbot-apache/certbot_apache/_internal/tests/configurator_test.py +++ b/certbot-apache/certbot_apache/_internal/tests/configurator_test.py @@ -1653,15 +1653,12 @@ class InstallSslOptionsConfTest(util.ApacheTest): file has been manually edited by the user, and will refuse to update it. This test ensures that all necessary hashes are present. """ - if sys.version_info >= (3, 9): # pragma: no cover - import importlib.resources as importlib_resources - else: # pragma: no cover - import importlib_resources + import importlib.resources from certbot_apache._internal.constants import ALL_SSL_OPTIONS_HASHES - ref = importlib_resources.files("certbot_apache") / "_internal" / "tls_configs" - with importlib_resources.as_file(ref) as tls_configs_dir: + ref = importlib.resources.files("certbot_apache") / "_internal" / "tls_configs" + with importlib.resources.as_file(ref) as tls_configs_dir: all_files = [os.path.join(tls_configs_dir, name) for name in os.listdir(tls_configs_dir) if name.endswith('options-ssl-apache.conf')] assert len(all_files) >= 1 diff --git a/certbot-apache/setup.py b/certbot-apache/setup.py index a40b8bdf6..6b4cac87b 100644 --- a/certbot-apache/setup.py +++ b/certbot-apache/setup.py @@ -9,7 +9,6 @@ install_requires = [ # https://github.com/certbot/certbot/issues/8761 for more info. f'acme>={version}', f'certbot>={version}', - 'importlib_resources>=1.3.1; python_version < "3.9"', 'python-augeas', ] diff --git a/certbot-ci/certbot_integration_tests/nginx_tests/nginx_config.py b/certbot-ci/certbot_integration_tests/nginx_tests/nginx_config.py index c5d733eef..d8b195f81 100644 --- a/certbot-ci/certbot_integration_tests/nginx_tests/nginx_config.py +++ b/certbot-ci/certbot_integration_tests/nginx_tests/nginx_config.py @@ -2,15 +2,10 @@ """General purpose nginx test configuration generator.""" import atexit import getpass -import sys +import importlib.resources from contextlib import ExitStack from typing import Optional -if sys.version_info >= (3, 9): # pragma: no cover - import importlib.resources as importlib_resources -else: # pragma: no cover - import importlib_resources - def construct_nginx_config(nginx_root: str, nginx_webroot: str, http_port: int, https_port: int, other_port: int, default_server: bool, key_path: Optional[str] = None, @@ -32,16 +27,16 @@ def construct_nginx_config(nginx_root: str, nginx_webroot: str, http_port: int, if not key_path: file_manager = ExitStack() atexit.register(file_manager.close) - ref = (importlib_resources.files('certbot_integration_tests').joinpath('assets') + ref = (importlib.resources.files('certbot_integration_tests').joinpath('assets') .joinpath('key.pem')) - key_path = str(file_manager.enter_context(importlib_resources.as_file(ref))) + key_path = str(file_manager.enter_context(importlib.resources.as_file(ref))) if not cert_path: file_manager = ExitStack() atexit.register(file_manager.close) - ref = (importlib_resources.files('certbot_integration_tests').joinpath('assets') + ref = (importlib.resources.files('certbot_integration_tests').joinpath('assets') .joinpath('cert.pem')) - cert_path = str(file_manager.enter_context(importlib_resources.as_file(ref))) + cert_path = str(file_manager.enter_context(importlib.resources.as_file(ref))) return '''\ # This error log will be written regardless of server scope error_log diff --git a/certbot-ci/certbot_integration_tests/rfc2136_tests/context.py b/certbot-ci/certbot_integration_tests/rfc2136_tests/context.py index a17587f44..a36321bc9 100644 --- a/certbot-ci/certbot_integration_tests/rfc2136_tests/context.py +++ b/certbot-ci/certbot_integration_tests/rfc2136_tests/context.py @@ -1,6 +1,6 @@ """Module to handle the context of RFC2136 integration tests.""" from contextlib import contextmanager -import sys +import importlib.resources import tempfile from typing import Generator from typing import Iterable @@ -11,11 +11,6 @@ import pytest from certbot_integration_tests.certbot_tests import context as certbot_context from certbot_integration_tests.utils import certbot_call -if sys.version_info >= (3, 9): # pragma: no cover - import importlib.resources as importlib_resources -else: # pragma: no cover - import importlib_resources - class IntegrationTestsContext(certbot_context.IntegrationTestsContext): """Integration test context for certbot-dns-rfc2136""" @@ -48,9 +43,9 @@ class IntegrationTestsContext(certbot_context.IntegrationTestsContext): :yields: Path to credentials file :rtype: str """ - src_ref_file = (importlib_resources.files('certbot_integration_tests').joinpath('assets') + src_ref_file = (importlib.resources.files('certbot_integration_tests').joinpath('assets') .joinpath('bind-config').joinpath(f'rfc2136-credentials-{label}.ini.tpl')) - with importlib_resources.as_file(src_ref_file) as src_file: + with importlib.resources.as_file(src_ref_file) as src_file: with open(src_file, 'r') as f: contents = f.read().format( server_address=self._dns_xdist['address'], diff --git a/certbot-ci/certbot_integration_tests/utils/dns_server.py b/certbot-ci/certbot_integration_tests/utils/dns_server.py index 6a6da1d8e..314e215bf 100644 --- a/certbot-ci/certbot_integration_tests/utils/dns_server.py +++ b/certbot-ci/certbot_integration_tests/utils/dns_server.py @@ -1,5 +1,6 @@ #!/usr/bin/env python """Module to setup an RFC2136-capable DNS server""" +import importlib.resources import os import os.path import shutil @@ -17,11 +18,6 @@ from typing import Type from certbot_integration_tests.utils import constants -if sys.version_info >= (3, 9): # pragma: no cover - import importlib.resources as importlib_resources -else: # pragma: no cover - import importlib_resources - BIND_DOCKER_IMAGE = "internetsystemsconsortium/bind9:9.20" BIND_BIND_ADDRESS = ("127.0.0.1", 45953) @@ -83,8 +79,8 @@ class DNSServer: def _configure_bind(self) -> None: """Configure the BIND9 server based on the prebaked configuration""" - ref = importlib_resources.files("certbot_integration_tests") / "assets" / "bind-config" - with importlib_resources.as_file(ref) as path: + ref = importlib.resources.files("certbot_integration_tests") / "assets" / "bind-config" + with importlib.resources.as_file(ref) as path: for directory in ("conf", "zones"): shutil.copytree( os.path.join(path, directory), os.path.join(self.bind_root, directory) diff --git a/certbot-ci/certbot_integration_tests/utils/misc.py b/certbot-ci/certbot_integration_tests/utils/misc.py index cdce4f855..3c4890a66 100644 --- a/certbot-ci/certbot_integration_tests/utils/misc.py +++ b/certbot-ci/certbot_integration_tests/utils/misc.py @@ -7,6 +7,7 @@ import contextlib import errno import functools import http.server as SimpleHTTPServer +import importlib.resources import os import re import shutil @@ -36,11 +37,6 @@ import requests from certbot_integration_tests.utils.constants import PEBBLE_ALTERNATE_ROOTS from certbot_integration_tests.utils.constants import PEBBLE_MANAGEMENT_URL -if sys.version_info >= (3, 9): # pragma: no cover - import importlib.resources as importlib_resources -else: # pragma: no cover - import importlib_resources - RSA_KEY_TYPE = 'rsa' ECDSA_KEY_TYPE = 'ecdsa' @@ -124,9 +120,9 @@ def generate_test_file_hooks(config_dir: str, hook_probe: str) -> None: """ file_manager = contextlib.ExitStack() atexit.register(file_manager.close) - hook_path_ref = (importlib_resources.files('certbot_integration_tests').joinpath('assets') + hook_path_ref = (importlib.resources.files('certbot_integration_tests').joinpath('assets') .joinpath('hook.py')) - hook_path = str(file_manager.enter_context(importlib_resources.as_file(hook_path_ref))) + hook_path = str(file_manager.enter_context(importlib.resources.as_file(hook_path_ref))) for hook_dir in list_renewal_hooks_dirs(config_dir): # We want an equivalent of bash `chmod -p $HOOK_DIR, that does not fail if one folder of @@ -261,9 +257,9 @@ def load_sample_data_path(workspace: str) -> str: :returns: the path to the loaded sample data directory :rtype: str """ - original_ref = (importlib_resources.files('certbot_integration_tests').joinpath('assets') + original_ref = (importlib.resources.files('certbot_integration_tests').joinpath('assets') .joinpath('sample-config')) - with importlib_resources.as_file(original_ref) as original: + with importlib.resources.as_file(original_ref) as original: copied = os.path.join(workspace, 'sample-config') shutil.copytree(original, copied, symlinks=True) diff --git a/certbot-ci/certbot_integration_tests/utils/pebble_artifacts.py b/certbot-ci/certbot_integration_tests/utils/pebble_artifacts.py index ecefcb586..ebd5bd1c7 100644 --- a/certbot-ci/certbot_integration_tests/utils/pebble_artifacts.py +++ b/certbot-ci/certbot_integration_tests/utils/pebble_artifacts.py @@ -1,10 +1,10 @@ # pylint: disable=missing-module-docstring import atexit +import importlib.resources import io import json import os import stat -import sys import zipfile from contextlib import ExitStack from typing import Optional, Tuple @@ -14,11 +14,6 @@ import requests from certbot_integration_tests.utils.constants import DEFAULT_HTTP_01_PORT from certbot_integration_tests.utils.constants import MOCK_OCSP_SERVER_PORT -if sys.version_info >= (3, 9): # pragma: no cover - import importlib.resources as importlib_resources -else: # pragma: no cover - import importlib_resources - PEBBLE_VERSION = 'v2.5.1' @@ -26,8 +21,8 @@ def fetch(workspace: str, http_01_port: int = DEFAULT_HTTP_01_PORT) -> Tuple[str # pylint: disable=missing-function-docstring file_manager = ExitStack() atexit.register(file_manager.close) - pebble_path_ref = importlib_resources.files('certbot_integration_tests') / 'assets' - assets_path = str(file_manager.enter_context(importlib_resources.as_file(pebble_path_ref))) + pebble_path_ref = importlib.resources.files('certbot_integration_tests') / 'assets' + assets_path = str(file_manager.enter_context(importlib.resources.as_file(pebble_path_ref))) pebble_path = _fetch_asset('pebble', assets_path) challtestsrv_path = _fetch_asset('pebble-challtestsrv', assets_path) diff --git a/certbot-ci/setup.py b/certbot-ci/setup.py index c76e636c2..accb71477 100644 --- a/certbot-ci/setup.py +++ b/certbot-ci/setup.py @@ -6,7 +6,6 @@ version = '0.32.0.dev0' install_requires = [ 'coverage', 'cryptography', - 'importlib_resources>=1.3.1; python_version < "3.9"', 'pyopenssl', 'pytest', 'pytest-cov', diff --git a/certbot-nginx/certbot_nginx/_internal/configurator.py b/certbot-nginx/certbot_nginx/_internal/configurator.py index cbf78f669..dcdf3bf80 100644 --- a/certbot-nginx/certbot_nginx/_internal/configurator.py +++ b/certbot-nginx/certbot_nginx/_internal/configurator.py @@ -3,10 +3,10 @@ import atexit from contextlib import ExitStack import logging +import importlib.resources import re import socket import subprocess -import sys import tempfile import time from typing import Any @@ -40,11 +40,6 @@ from certbot_nginx._internal import nginxparser from certbot_nginx._internal import obj from certbot_nginx._internal import parser -if sys.version_info >= (3, 9): # pragma: no cover - import importlib.resources as importlib_resources -else: # pragma: no cover - import importlib_resources - NAME_RANK = 0 START_WILDCARD_RANK = 1 END_WILDCARD_RANK = 2 @@ -171,10 +166,10 @@ class NginxConfigurator(common.Configurator): file_manager = ExitStack() atexit.register(file_manager.close) - ref = (importlib_resources.files("certbot_nginx").joinpath("_internal") + ref = (importlib.resources.files("certbot_nginx").joinpath("_internal") .joinpath("tls_configs").joinpath(config_filename)) - return str(file_manager.enter_context(importlib_resources.as_file(ref))) + return str(file_manager.enter_context(importlib.resources.as_file(ref))) @property def mod_ssl_conf(self) -> str: diff --git a/certbot-nginx/certbot_nginx/_internal/tests/configurator_test.py b/certbot-nginx/certbot_nginx/_internal/tests/configurator_test.py index 24b21edca..e28523bc5 100644 --- a/certbot-nginx/certbot_nginx/_internal/tests/configurator_test.py +++ b/certbot-nginx/certbot_nginx/_internal/tests/configurator_test.py @@ -1074,16 +1074,13 @@ class InstallSslOptionsConfTest(util.NginxTest): file has been manually edited by the user, and will refuse to update it. This test ensures that all necessary hashes are present. """ - if sys.version_info >= (3, 9): # pragma: no cover - import importlib.resources as importlib_resources - else: # pragma: no cover - import importlib_resources - + import importlib.resources + from certbot_nginx._internal.constants import ALL_SSL_OPTIONS_HASHES - tls_configs_ref = importlib_resources.files("certbot_nginx").joinpath( + tls_configs_ref = importlib.resources.files("certbot_nginx").joinpath( "_internal", "tls_configs") - with importlib_resources.as_file(tls_configs_ref) as tls_configs_dir: + with importlib.resources.as_file(tls_configs_ref) as tls_configs_dir: for tls_config_file in os.listdir(tls_configs_dir): file_hash = crypto_util.sha256sum(os.path.join(tls_configs_dir, tls_config_file)) assert file_hash in ALL_SSL_OPTIONS_HASHES, \ diff --git a/certbot-nginx/certbot_nginx/_internal/tests/test_util.py b/certbot-nginx/certbot_nginx/_internal/tests/test_util.py index 4f95fe7b2..b849c6e16 100644 --- a/certbot-nginx/certbot_nginx/_internal/tests/test_util.py +++ b/certbot-nginx/certbot_nginx/_internal/tests/test_util.py @@ -1,5 +1,6 @@ """Common utilities for certbot_nginx.""" import copy +import importlib.resources import shutil import tempfile import sys @@ -15,11 +16,6 @@ from certbot.tests import util as test_util from certbot_nginx._internal import configurator from certbot_nginx._internal import nginxparser -if sys.version_info >= (3, 9): # pragma: no cover - import importlib.resources as importlib_resources -else: # pragma: no cover - import importlib_resources - class NginxTest(test_util.ConfigTestCase): def setUp(self): @@ -86,8 +82,8 @@ class NginxTest(test_util.ConfigTestCase): @contextmanager def get_data_filename(filename): """Gets the filename of a test data file.""" - ref = importlib_resources.files(__package__) / "testdata" / "etc_nginx"/ filename - with importlib_resources.as_file(ref) as path: + ref = importlib.resources.files(__package__) / "testdata" / "etc_nginx"/ filename + with importlib.resources.as_file(ref) as path: yield path diff --git a/certbot-nginx/setup.py b/certbot-nginx/setup.py index fb3e075f0..8e496bfd5 100644 --- a/certbot-nginx/setup.py +++ b/certbot-nginx/setup.py @@ -9,7 +9,6 @@ install_requires = [ # https://github.com/certbot/certbot/issues/8761 for more info. f'acme>={version}', f'certbot>={version}', - 'importlib_resources>=1.3.1; python_version < "3.9"', # pyOpenSSL 23.1.0 is a bad release: https://github.com/pyca/pyopenssl/issues/1199 'PyOpenSSL>=17.5.0,!=23.1.0', 'pyparsing>=2.2.1', diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md index b903a4d92..c89c81453 100644 --- a/certbot/CHANGELOG.md +++ b/certbot/CHANGELOG.md @@ -15,6 +15,7 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). * Updated our Docker images to be based on Alpine Linux 3.20. * Our runtime dependency on setuptools has been dropped from all Certbot components. +* Certbot's packages no longer depend on library importlib_resources. ### Fixed diff --git a/certbot/certbot/_internal/constants.py b/certbot/certbot/_internal/constants.py index a7b726b53..fbdc041e7 100644 --- a/certbot/certbot/_internal/constants.py +++ b/certbot/certbot/_internal/constants.py @@ -1,7 +1,7 @@ """Certbot constants.""" import atexit +import importlib.resources import logging -import sys from contextlib import ExitStack from typing import Any from typing import Dict @@ -10,11 +10,6 @@ from acme import challenges from certbot.compat import misc from certbot.compat import os -if sys.version_info >= (3, 9): # pragma: no cover - import importlib.resources as importlib_resources -else: # pragma: no cover - import importlib_resources - SETUPTOOLS_PLUGINS_ENTRY_POINT = "certbot.plugins" """Setuptools entry point group name for plugins.""" @@ -228,8 +223,8 @@ def _generate_ssl_dhparams_src_static() -> str: # Python process, and will be automatically cleaned up on exit. file_manager = ExitStack() atexit.register(file_manager.close) - ssl_dhparams_src_ref = importlib_resources.files("certbot") / "ssl-dhparams.pem" - return str(file_manager.enter_context(importlib_resources.as_file(ssl_dhparams_src_ref))) + ssl_dhparams_src_ref = importlib.resources.files("certbot") / "ssl-dhparams.pem" + return str(file_manager.enter_context(importlib.resources.as_file(ssl_dhparams_src_ref))) SSL_DHPARAMS_SRC = _generate_ssl_dhparams_src_static() """Path to the nginx ssl_dhparams file found in the Certbot distribution.""" diff --git a/certbot/certbot/plugins/common.py b/certbot/certbot/plugins/common.py index f1e790da9..b38f4fc21 100644 --- a/certbot/certbot/plugins/common.py +++ b/certbot/certbot/plugins/common.py @@ -2,10 +2,10 @@ from abc import ABCMeta from abc import abstractmethod import argparse +import importlib.resources import logging import re import shutil -import sys import tempfile from typing import Any from typing import Callable @@ -31,11 +31,6 @@ from certbot.interfaces import Installer as AbstractInstaller from certbot.interfaces import Plugin as AbstractPlugin from certbot.plugins.storage import PluginStorage -if sys.version_info >= (3, 9): # pragma: no cover - import importlib.resources as importlib_resources -else: # pragma: no cover - import importlib_resources - logger = logging.getLogger(__name__) @@ -465,8 +460,8 @@ def dir_setup(test_dir: str, pkg: str) -> Tuple[str, str, str]: # pragma: no co filesystem.chmod(config_dir, constants.CONFIG_DIRS_MODE) filesystem.chmod(work_dir, constants.CONFIG_DIRS_MODE) - test_dir_ref = importlib_resources.files(pkg).joinpath("testdata").joinpath(test_dir) - with importlib_resources.as_file(test_dir_ref) as path: + test_dir_ref = importlib.resources.files(pkg).joinpath("testdata").joinpath(test_dir) + with importlib.resources.as_file(test_dir_ref) as path: shutil.copytree( path, os.path.join(temp_dir, test_dir), symlinks=True) diff --git a/certbot/certbot/tests/util.py b/certbot/certbot/tests/util.py index 5d078cfbd..f8ba2e1e5 100644 --- a/certbot/certbot/tests/util.py +++ b/certbot/certbot/tests/util.py @@ -3,6 +3,7 @@ import atexit from contextlib import ExitStack import copy from importlib import reload as reload_module +import importlib.resources import io import logging import multiprocessing @@ -38,11 +39,6 @@ from certbot.compat import os from certbot.display import util as display_util from certbot.plugins import common -if sys.version_info >= (3, 9): # pragma: no cover - import importlib.resources as importlib_resources -else: # pragma: no cover - import importlib_resources - class DummyInstaller(common.Installer): """Dummy installer plugin for test purpose.""" @@ -84,14 +80,14 @@ def vector_path(*names: str) -> str: """Path to a test vector.""" _file_manager = ExitStack() atexit.register(_file_manager.close) - vector_ref = importlib_resources.files(__package__).joinpath('testdata', *names) - path = _file_manager.enter_context(importlib_resources.as_file(vector_ref)) + vector_ref = importlib.resources.files(__package__).joinpath('testdata', *names) + path = _file_manager.enter_context(importlib.resources.as_file(vector_ref)) return str(path) def load_vector(*names: str) -> bytes: """Load contents of a test vector.""" - vector_ref = importlib_resources.files(__package__).joinpath('testdata', *names) + vector_ref = importlib.resources.files(__package__).joinpath('testdata', *names) data = vector_ref.read_bytes() # Try at most to convert CRLF to LF when data is text try: diff --git a/certbot/setup.py b/certbot/setup.py index aed96120f..f8c478a01 100644 --- a/certbot/setup.py +++ b/certbot/setup.py @@ -32,7 +32,6 @@ install_requires = [ 'configobj>=5.0.6', 'cryptography>=3.2.1', 'distro>=1.0.1', - 'importlib_resources>=1.3.1; python_version < "3.9"', 'importlib_metadata>=4.6; python_version < "3.10"', # Josepy 2+ may introduce backward incompatible changes by droping usage of # deprecated PyOpenSSL APIs. diff --git a/tools/oldest_constraints.txt b/tools/oldest_constraints.txt index 92189b9ce..7d10771e9 100644 --- a/tools/oldest_constraints.txt +++ b/tools/oldest_constraints.txt @@ -32,7 +32,6 @@ google-auth==2.16.0 ; python_version >= "3.9" and python_version < "3.10" httplib2==0.9.2 ; python_version >= "3.9" and python_version < "3.10" idna==2.6 ; python_version >= "3.9" and python_version < "3.10" importlib-metadata==4.6.4 ; python_version >= "3.9" and python_version < "3.10" -importlib-resources==6.4.5 ; python_version >= "3.9" and python_version < "3.10" iniconfig==2.0.0 ; python_version >= "3.9" and python_version < "3.10" ipaddress==1.0.16 ; python_version >= "3.9" and python_version < "3.10" isort==5.13.2 ; python_version >= "3.9" and python_version < "3.10" diff --git a/tools/requirements.txt b/tools/requirements.txt index de89b212e..d2961f989 100644 --- a/tools/requirements.txt +++ b/tools/requirements.txt @@ -8,15 +8,15 @@ alabaster==0.7.16 ; python_version >= "3.9" and python_version < "4.0" apacheconfig==0.3.2 ; python_version >= "3.9" and python_version < "4.0" astroid==3.0.3 ; python_version >= "3.9" and python_version < "4.0" -asttokens==2.4.1 ; python_version >= "3.9" and python_version < "4.0" +asttokens==3.0.0 ; python_version >= "3.9" and python_version < "4.0" attrs==24.2.0 ; python_version >= "3.9" and python_version < "4.0" azure-core==1.32.0 ; python_version >= "3.9" and python_version < "4.0" azure-devops==7.1.0b4 ; python_version >= "3.9" and python_version < "4.0" babel==2.16.0 ; python_version >= "3.9" and python_version < "4.0" bcrypt==4.2.1 ; python_version >= "3.9" and python_version < "4.0" beautifulsoup4==4.12.3 ; python_version >= "3.9" and python_version < "4.0" -boto3==1.35.69 ; python_version >= "3.9" and python_version < "4.0" -botocore==1.35.69 ; python_version >= "3.9" and python_version < "4.0" +boto3==1.35.74 ; python_version >= "3.9" and python_version < "4.0" +botocore==1.35.74 ; python_version >= "3.9" and python_version < "4.0" build==1.2.2.post1 ; python_version >= "3.9" and python_version < "4.0" cachecontrol==0.14.1 ; python_version >= "3.9" and python_version < "4.0" cachetools==5.5.0 ; python_version >= "3.9" and python_version < "4.0" @@ -46,7 +46,7 @@ exceptiongroup==1.2.2 ; python_version >= "3.9" and python_version < "3.11" execnet==2.1.1 ; python_version >= "3.9" and python_version < "4.0" executing==2.1.0 ; python_version >= "3.9" and python_version < "4.0" fabric==3.2.2 ; python_version >= "3.9" and python_version < "4.0" -fastjsonschema==2.20.0 ; python_version >= "3.9" and python_version < "4.0" +fastjsonschema==2.21.1 ; python_version >= "3.9" and python_version < "4.0" filelock==3.16.1 ; python_version >= "3.9" and python_version < "4.0" google-api-core==2.23.0 ; python_version >= "3.9" and python_version < "4.0" google-api-python-client==2.154.0 ; python_version >= "3.9" and python_version < "4.0" @@ -56,8 +56,7 @@ googleapis-common-protos==1.66.0 ; python_version >= "3.9" and python_version < httplib2==0.22.0 ; python_version >= "3.9" and python_version < "4.0" idna==3.10 ; python_version >= "3.9" and python_version < "4.0" imagesize==1.4.1 ; python_version >= "3.9" and python_version < "4.0" -importlib-metadata==8.5.0 ; python_version >= "3.9" and python_version < "4.0" -importlib-resources==6.4.5 ; python_version >= "3.9" and python_version < "4.0" +importlib-metadata==8.5.0 ; python_version >= "3.9" and python_version < "3.12" iniconfig==2.0.0 ; python_version >= "3.9" and python_version < "4.0" installer==0.7.0 ; python_version >= "3.9" and python_version < "4.0" invoke==2.2.0 ; python_version >= "3.9" and python_version < "4.0" @@ -84,7 +83,7 @@ msgpack==1.1.0 ; python_version >= "3.9" and python_version < "4.0" msrest==0.7.1 ; python_version >= "3.9" and python_version < "4.0" mypy-extensions==1.0.0 ; python_version >= "3.9" and python_version < "4.0" mypy==1.9.0 ; python_version >= "3.9" and python_version < "4.0" -nh3==0.2.18 ; python_version >= "3.9" and python_version < "4.0" +nh3==0.2.19 ; python_version >= "3.9" and python_version < "4.0" oauthlib==3.2.2 ; python_version >= "3.9" and python_version < "4.0" packaging==24.2 ; python_version >= "3.9" and python_version < "4.0" paramiko==3.5.0 ; python_version >= "3.9" and python_version < "4.0" @@ -92,7 +91,7 @@ parsedatetime==2.6 ; python_version >= "3.9" and python_version < "4.0" parso==0.8.4 ; python_version >= "3.9" and python_version < "4.0" pexpect==4.9.0 ; python_version >= "3.9" and python_version < "4.0" pip==24.3.1 ; python_version >= "3.9" and python_version < "4.0" -pkginfo==1.10.0 ; python_version >= "3.9" and python_version < "4.0" +pkginfo==1.12.0 ; python_version >= "3.9" and python_version < "4.0" platformdirs==4.3.6 ; python_version >= "3.9" and python_version < "4.0" pluggy==1.5.0 ; python_version >= "3.9" and python_version < "4.0" ply==3.11 ; python_version >= "3.9" and python_version < "4.0" @@ -101,7 +100,7 @@ poetry-plugin-export==1.8.0 ; python_version >= "3.9" and python_version < "4.0" poetry==1.8.4 ; python_version >= "3.9" and python_version < "4.0" prompt-toolkit==3.0.48 ; python_version >= "3.9" and python_version < "4.0" proto-plus==1.25.0 ; python_version >= "3.9" and python_version < "4.0" -protobuf==5.28.3 ; python_version >= "3.9" and python_version < "4.0" +protobuf==5.29.0 ; python_version >= "3.9" and python_version < "4.0" ptyprocess==0.7.0 ; python_version >= "3.9" and python_version < "4.0" pure-eval==0.2.3 ; python_version >= "3.9" and python_version < "4.0" pyasn1-modules==0.4.1 ; python_version >= "3.9" and python_version < "4.0" @@ -119,7 +118,7 @@ pyproject-hooks==1.2.0 ; python_version >= "3.9" and python_version < "4.0" pyrfc3339==2.0.1 ; python_version >= "3.9" and python_version < "4.0" pytest-cov==6.0.0 ; python_version >= "3.9" and python_version < "4.0" pytest-xdist==3.6.1 ; python_version >= "3.9" and python_version < "4.0" -pytest==8.3.3 ; python_version >= "3.9" and python_version < "4.0" +pytest==8.3.4 ; python_version >= "3.9" and python_version < "4.0" python-augeas==1.1.0 ; python_version >= "3.9" and python_version < "4.0" python-dateutil==2.9.0.post0 ; python_version >= "3.9" and python_version < "4.0" python-digitalocean==1.17.0 ; python_version >= "3.9" and python_version < "4.0" @@ -157,29 +156,29 @@ sphinxcontrib-qthelp==2.0.0 ; python_version >= "3.9" and python_version < "4.0" sphinxcontrib-serializinghtml==2.0.0 ; python_version >= "3.9" and python_version < "4.0" stack-data==0.6.3 ; python_version >= "3.9" and python_version < "4.0" tldextract==5.1.3 ; python_version >= "3.9" and python_version < "4.0" -tomli==2.1.0 ; python_version >= "3.9" and python_full_version <= "3.11.0a6" +tomli==2.2.1 ; python_version >= "3.9" and python_full_version <= "3.11.0a6" tomlkit==0.13.2 ; python_version >= "3.9" and python_version < "4.0" tox==4.23.2 ; python_version >= "3.9" and python_version < "4.0" traitlets==5.14.3 ; python_version >= "3.9" and python_version < "4.0" trove-classifiers==2024.10.21.16 ; python_version >= "3.9" and python_version < "4.0" -twine==5.1.1 ; python_version >= "3.9" and python_version < "4.0" +twine==6.0.1 ; python_version >= "3.9" and python_version < "4.0" types-cffi==1.16.0.20240331 ; python_version >= "3.9" and python_version < "4.0" types-httplib2==0.22.0.20240310 ; python_version >= "3.9" and python_version < "4.0" types-pyopenssl==24.1.0.20240722 ; python_version >= "3.9" and python_version < "4.0" types-pyrfc3339==2.0.1.20241107 ; python_version >= "3.9" and python_version < "4.0" types-python-dateutil==2.9.0.20241003 ; python_version >= "3.9" and python_version < "4.0" types-pytz==2024.2.0.20241003 ; python_version >= "3.9" and python_version < "4.0" -types-pywin32==308.0.0.20241121 ; python_version >= "3.9" and python_version < "4.0" +types-pywin32==308.0.0.20241128 ; python_version >= "3.9" and python_version < "4.0" types-requests==2.31.0.6 ; python_version >= "3.9" and python_version < "4.0" -types-setuptools==75.5.0.20241122 ; python_version >= "3.9" and python_version < "4.0" +types-setuptools==75.6.0.20241126 ; python_version >= "3.9" and python_version < "4.0" types-urllib3==1.26.25.14 ; python_version >= "3.9" and python_version < "4.0" typing-extensions==4.12.2 ; python_version >= "3.9" and python_version < "4.0" uritemplate==4.1.1 ; python_version >= "3.9" and python_version < "4.0" urllib3==1.26.20 ; python_version >= "3.9" and python_version < "4.0" -virtualenv==20.27.1 ; python_version >= "3.9" and python_version < "4.0" +virtualenv==20.28.0 ; python_version >= "3.9" and python_version < "4.0" wcwidth==0.2.13 ; python_version >= "3.9" and python_version < "4.0" wheel==0.45.1 ; python_version >= "3.9" and python_version < "4.0" wrapt==1.17.0 ; python_version >= "3.9" and python_version < "4.0" xattr==1.1.0 ; python_version >= "3.9" and python_version < "4.0" and sys_platform == "darwin" yarg==0.1.10 ; python_version >= "3.9" and python_version < "4.0" -zipp==3.21.0 ; python_version >= "3.9" and python_version < "4.0" +zipp==3.21.0 ; python_version >= "3.9" and python_version < "3.12"