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
This commit is contained in:
Brad Warren
2024-12-06 12:37:17 -08:00
committed by GitHub
parent 3f9387bd15
commit 7a48c235a9
23 changed files with 66 additions and 146 deletions
+2 -6
View File
@@ -3,6 +3,7 @@
.. warning:: This module is not part of the public API. .. warning:: This module is not part of the public API.
""" """
import importlib.resources
import os import os
import sys import sys
@@ -12,16 +13,11 @@ import josepy as jose
from josepy.util import ComparableECKey from josepy.util import ComparableECKey
from OpenSSL import crypto 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): def load_vector(*names):
"""Load contents of a test vector.""" """Load contents of a test vector."""
# luckily, resource_string opens file in binary mode # 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() return vector_ref.read_bytes()
-9
View File
@@ -23,15 +23,6 @@ docs_extras = [
] ]
test_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',
'pytest-xdist', 'pytest-xdist',
'typing-extensions', 'typing-extensions',
@@ -2,10 +2,10 @@
import atexit import atexit
import binascii import binascii
import fnmatch import fnmatch
import importlib.resources
import logging import logging
import re import re
import subprocess import subprocess
import sys
from contextlib import ExitStack from contextlib import ExitStack
from typing import Dict from typing import Dict
from typing import Iterable from typing import Iterable
@@ -17,12 +17,6 @@ from certbot import errors
from certbot import util from certbot import util
from certbot.compat import os 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__) logger = logging.getLogger(__name__)
@@ -257,6 +251,6 @@ def find_ssl_apache_conf(prefix: str) -> str:
""" """
file_manager = ExitStack() file_manager = ExitStack()
atexit.register(file_manager.close) 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))) .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)))
@@ -1,14 +1,10 @@
"""Apache plugin constants.""" """Apache plugin constants."""
import atexit import atexit
import sys import importlib.resources
from contextlib import ExitStack from contextlib import ExitStack
from typing import Dict from typing import Dict
from typing import List 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" MOD_SSL_CONF_DEST = "options-ssl-apache.conf"
"""Name of the mod_ssl config file as saved """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. # Python process, and will be automatically cleaned up on exit.
file_manager = ExitStack() file_manager = ExitStack()
atexit.register(file_manager.close) atexit.register(file_manager.close)
augeas_lens_dir_ref = importlib_resources.files("certbot_apache") / "_internal" / "augeas_lens" 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))) return str(file_manager.enter_context(importlib.resources.as_file(augeas_lens_dir_ref)))
AUGEAS_LENS_DIR = _generate_augeas_lens_dir_static() AUGEAS_LENS_DIR = _generate_augeas_lens_dir_static()
"""Path to the Augeas lens directory""" """Path to the Augeas lens directory"""
@@ -1653,15 +1653,12 @@ class InstallSslOptionsConfTest(util.ApacheTest):
file has been manually edited by the user, and will refuse to update it. file has been manually edited by the user, and will refuse to update it.
This test ensures that all necessary hashes are present. This test ensures that all necessary hashes are present.
""" """
if sys.version_info >= (3, 9): # pragma: no cover import importlib.resources
import importlib.resources as importlib_resources
else: # pragma: no cover
import importlib_resources
from certbot_apache._internal.constants import ALL_SSL_OPTIONS_HASHES from certbot_apache._internal.constants import ALL_SSL_OPTIONS_HASHES
ref = importlib_resources.files("certbot_apache") / "_internal" / "tls_configs" ref = importlib.resources.files("certbot_apache") / "_internal" / "tls_configs"
with importlib_resources.as_file(ref) as tls_configs_dir: 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) all_files = [os.path.join(tls_configs_dir, name) for name in os.listdir(tls_configs_dir)
if name.endswith('options-ssl-apache.conf')] if name.endswith('options-ssl-apache.conf')]
assert len(all_files) >= 1 assert len(all_files) >= 1
-1
View File
@@ -9,7 +9,6 @@ install_requires = [
# https://github.com/certbot/certbot/issues/8761 for more info. # https://github.com/certbot/certbot/issues/8761 for more info.
f'acme>={version}', f'acme>={version}',
f'certbot>={version}', f'certbot>={version}',
'importlib_resources>=1.3.1; python_version < "3.9"',
'python-augeas', 'python-augeas',
] ]
@@ -2,15 +2,10 @@
"""General purpose nginx test configuration generator.""" """General purpose nginx test configuration generator."""
import atexit import atexit
import getpass import getpass
import sys import importlib.resources
from contextlib import ExitStack from contextlib import ExitStack
from typing import Optional 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, 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, 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: if not key_path:
file_manager = ExitStack() file_manager = ExitStack()
atexit.register(file_manager.close) 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')) .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: if not cert_path:
file_manager = ExitStack() file_manager = ExitStack()
atexit.register(file_manager.close) 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')) .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 '''\ return '''\
# This error log will be written regardless of server scope error_log # This error log will be written regardless of server scope error_log
@@ -1,6 +1,6 @@
"""Module to handle the context of RFC2136 integration tests.""" """Module to handle the context of RFC2136 integration tests."""
from contextlib import contextmanager from contextlib import contextmanager
import sys import importlib.resources
import tempfile import tempfile
from typing import Generator from typing import Generator
from typing import Iterable 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.certbot_tests import context as certbot_context
from certbot_integration_tests.utils import certbot_call 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): class IntegrationTestsContext(certbot_context.IntegrationTestsContext):
"""Integration test context for certbot-dns-rfc2136""" """Integration test context for certbot-dns-rfc2136"""
@@ -48,9 +43,9 @@ class IntegrationTestsContext(certbot_context.IntegrationTestsContext):
:yields: Path to credentials file :yields: Path to credentials file
:rtype: str :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')) .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: with open(src_file, 'r') as f:
contents = f.read().format( contents = f.read().format(
server_address=self._dns_xdist['address'], server_address=self._dns_xdist['address'],
@@ -1,5 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
"""Module to setup an RFC2136-capable DNS server""" """Module to setup an RFC2136-capable DNS server"""
import importlib.resources
import os import os
import os.path import os.path
import shutil import shutil
@@ -17,11 +18,6 @@ from typing import Type
from certbot_integration_tests.utils import constants 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_DOCKER_IMAGE = "internetsystemsconsortium/bind9:9.20"
BIND_BIND_ADDRESS = ("127.0.0.1", 45953) BIND_BIND_ADDRESS = ("127.0.0.1", 45953)
@@ -83,8 +79,8 @@ class DNSServer:
def _configure_bind(self) -> None: def _configure_bind(self) -> None:
"""Configure the BIND9 server based on the prebaked configuration""" """Configure the BIND9 server based on the prebaked configuration"""
ref = importlib_resources.files("certbot_integration_tests") / "assets" / "bind-config" ref = importlib.resources.files("certbot_integration_tests") / "assets" / "bind-config"
with importlib_resources.as_file(ref) as path: with importlib.resources.as_file(ref) as path:
for directory in ("conf", "zones"): for directory in ("conf", "zones"):
shutil.copytree( shutil.copytree(
os.path.join(path, directory), os.path.join(self.bind_root, directory) os.path.join(path, directory), os.path.join(self.bind_root, directory)
@@ -7,6 +7,7 @@ import contextlib
import errno import errno
import functools import functools
import http.server as SimpleHTTPServer import http.server as SimpleHTTPServer
import importlib.resources
import os import os
import re import re
import shutil 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_ALTERNATE_ROOTS
from certbot_integration_tests.utils.constants import PEBBLE_MANAGEMENT_URL 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' RSA_KEY_TYPE = 'rsa'
ECDSA_KEY_TYPE = 'ecdsa' ECDSA_KEY_TYPE = 'ecdsa'
@@ -124,9 +120,9 @@ def generate_test_file_hooks(config_dir: str, hook_probe: str) -> None:
""" """
file_manager = contextlib.ExitStack() file_manager = contextlib.ExitStack()
atexit.register(file_manager.close) 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')) .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): 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 # 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 :returns: the path to the loaded sample data directory
:rtype: str :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')) .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') copied = os.path.join(workspace, 'sample-config')
shutil.copytree(original, copied, symlinks=True) shutil.copytree(original, copied, symlinks=True)
@@ -1,10 +1,10 @@
# pylint: disable=missing-module-docstring # pylint: disable=missing-module-docstring
import atexit import atexit
import importlib.resources
import io import io
import json import json
import os import os
import stat import stat
import sys
import zipfile import zipfile
from contextlib import ExitStack from contextlib import ExitStack
from typing import Optional, Tuple 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 DEFAULT_HTTP_01_PORT
from certbot_integration_tests.utils.constants import MOCK_OCSP_SERVER_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' 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 # pylint: disable=missing-function-docstring
file_manager = ExitStack() file_manager = ExitStack()
atexit.register(file_manager.close) atexit.register(file_manager.close)
pebble_path_ref = importlib_resources.files('certbot_integration_tests') / 'assets' pebble_path_ref = importlib.resources.files('certbot_integration_tests') / 'assets'
assets_path = str(file_manager.enter_context(importlib_resources.as_file(pebble_path_ref))) assets_path = str(file_manager.enter_context(importlib.resources.as_file(pebble_path_ref)))
pebble_path = _fetch_asset('pebble', assets_path) pebble_path = _fetch_asset('pebble', assets_path)
challtestsrv_path = _fetch_asset('pebble-challtestsrv', assets_path) challtestsrv_path = _fetch_asset('pebble-challtestsrv', assets_path)
-1
View File
@@ -6,7 +6,6 @@ version = '0.32.0.dev0'
install_requires = [ install_requires = [
'coverage', 'coverage',
'cryptography', 'cryptography',
'importlib_resources>=1.3.1; python_version < "3.9"',
'pyopenssl', 'pyopenssl',
'pytest', 'pytest',
'pytest-cov', 'pytest-cov',
@@ -3,10 +3,10 @@
import atexit import atexit
from contextlib import ExitStack from contextlib import ExitStack
import logging import logging
import importlib.resources
import re import re
import socket import socket
import subprocess import subprocess
import sys
import tempfile import tempfile
import time import time
from typing import Any 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 obj
from certbot_nginx._internal import parser 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 NAME_RANK = 0
START_WILDCARD_RANK = 1 START_WILDCARD_RANK = 1
END_WILDCARD_RANK = 2 END_WILDCARD_RANK = 2
@@ -171,10 +166,10 @@ class NginxConfigurator(common.Configurator):
file_manager = ExitStack() file_manager = ExitStack()
atexit.register(file_manager.close) 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)) .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 @property
def mod_ssl_conf(self) -> str: def mod_ssl_conf(self) -> str:
@@ -1074,16 +1074,13 @@ class InstallSslOptionsConfTest(util.NginxTest):
file has been manually edited by the user, and will refuse to update it. file has been manually edited by the user, and will refuse to update it.
This test ensures that all necessary hashes are present. This test ensures that all necessary hashes are present.
""" """
if sys.version_info >= (3, 9): # pragma: no cover import importlib.resources
import importlib.resources as importlib_resources
else: # pragma: no cover
import importlib_resources
from certbot_nginx._internal.constants import ALL_SSL_OPTIONS_HASHES 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") "_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): for tls_config_file in os.listdir(tls_configs_dir):
file_hash = crypto_util.sha256sum(os.path.join(tls_configs_dir, tls_config_file)) file_hash = crypto_util.sha256sum(os.path.join(tls_configs_dir, tls_config_file))
assert file_hash in ALL_SSL_OPTIONS_HASHES, \ assert file_hash in ALL_SSL_OPTIONS_HASHES, \
@@ -1,5 +1,6 @@
"""Common utilities for certbot_nginx.""" """Common utilities for certbot_nginx."""
import copy import copy
import importlib.resources
import shutil import shutil
import tempfile import tempfile
import sys 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 configurator
from certbot_nginx._internal import nginxparser 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): class NginxTest(test_util.ConfigTestCase):
def setUp(self): def setUp(self):
@@ -86,8 +82,8 @@ class NginxTest(test_util.ConfigTestCase):
@contextmanager @contextmanager
def get_data_filename(filename): def get_data_filename(filename):
"""Gets the filename of a test data file.""" """Gets the filename of a test data file."""
ref = importlib_resources.files(__package__) / "testdata" / "etc_nginx"/ filename ref = importlib.resources.files(__package__) / "testdata" / "etc_nginx"/ filename
with importlib_resources.as_file(ref) as path: with importlib.resources.as_file(ref) as path:
yield path yield path
-1
View File
@@ -9,7 +9,6 @@ install_requires = [
# https://github.com/certbot/certbot/issues/8761 for more info. # https://github.com/certbot/certbot/issues/8761 for more info.
f'acme>={version}', f'acme>={version}',
f'certbot>={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 23.1.0 is a bad release: https://github.com/pyca/pyopenssl/issues/1199
'PyOpenSSL>=17.5.0,!=23.1.0', 'PyOpenSSL>=17.5.0,!=23.1.0',
'pyparsing>=2.2.1', 'pyparsing>=2.2.1',
+1
View File
@@ -15,6 +15,7 @@ Certbot adheres to [Semantic Versioning](https://semver.org/).
* Updated our Docker images to be based on Alpine Linux 3.20. * Updated our Docker images to be based on Alpine Linux 3.20.
* Our runtime dependency on setuptools has been dropped from all Certbot * Our runtime dependency on setuptools has been dropped from all Certbot
components. components.
* Certbot's packages no longer depend on library importlib_resources.
### Fixed ### Fixed
+3 -8
View File
@@ -1,7 +1,7 @@
"""Certbot constants.""" """Certbot constants."""
import atexit import atexit
import importlib.resources
import logging import logging
import sys
from contextlib import ExitStack from contextlib import ExitStack
from typing import Any from typing import Any
from typing import Dict from typing import Dict
@@ -10,11 +10,6 @@ from acme import challenges
from certbot.compat import misc from certbot.compat import misc
from certbot.compat import os 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_PLUGINS_ENTRY_POINT = "certbot.plugins"
"""Setuptools entry point group name for 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. # Python process, and will be automatically cleaned up on exit.
file_manager = ExitStack() file_manager = ExitStack()
atexit.register(file_manager.close) atexit.register(file_manager.close)
ssl_dhparams_src_ref = importlib_resources.files("certbot") / "ssl-dhparams.pem" 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))) return str(file_manager.enter_context(importlib.resources.as_file(ssl_dhparams_src_ref)))
SSL_DHPARAMS_SRC = _generate_ssl_dhparams_src_static() SSL_DHPARAMS_SRC = _generate_ssl_dhparams_src_static()
"""Path to the nginx ssl_dhparams file found in the Certbot distribution.""" """Path to the nginx ssl_dhparams file found in the Certbot distribution."""
+3 -8
View File
@@ -2,10 +2,10 @@
from abc import ABCMeta from abc import ABCMeta
from abc import abstractmethod from abc import abstractmethod
import argparse import argparse
import importlib.resources
import logging import logging
import re import re
import shutil import shutil
import sys
import tempfile import tempfile
from typing import Any from typing import Any
from typing import Callable from typing import Callable
@@ -31,11 +31,6 @@ from certbot.interfaces import Installer as AbstractInstaller
from certbot.interfaces import Plugin as AbstractPlugin from certbot.interfaces import Plugin as AbstractPlugin
from certbot.plugins.storage import PluginStorage 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__) 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(config_dir, constants.CONFIG_DIRS_MODE)
filesystem.chmod(work_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) test_dir_ref = importlib.resources.files(pkg).joinpath("testdata").joinpath(test_dir)
with importlib_resources.as_file(test_dir_ref) as path: with importlib.resources.as_file(test_dir_ref) as path:
shutil.copytree( shutil.copytree(
path, os.path.join(temp_dir, test_dir), symlinks=True) path, os.path.join(temp_dir, test_dir), symlinks=True)
+4 -8
View File
@@ -3,6 +3,7 @@ import atexit
from contextlib import ExitStack from contextlib import ExitStack
import copy import copy
from importlib import reload as reload_module from importlib import reload as reload_module
import importlib.resources
import io import io
import logging import logging
import multiprocessing import multiprocessing
@@ -38,11 +39,6 @@ from certbot.compat import os
from certbot.display import util as display_util from certbot.display import util as display_util
from certbot.plugins import common 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): class DummyInstaller(common.Installer):
"""Dummy installer plugin for test purpose.""" """Dummy installer plugin for test purpose."""
@@ -84,14 +80,14 @@ def vector_path(*names: str) -> str:
"""Path to a test vector.""" """Path to a test vector."""
_file_manager = ExitStack() _file_manager = ExitStack()
atexit.register(_file_manager.close) atexit.register(_file_manager.close)
vector_ref = importlib_resources.files(__package__).joinpath('testdata', *names) vector_ref = importlib.resources.files(__package__).joinpath('testdata', *names)
path = _file_manager.enter_context(importlib_resources.as_file(vector_ref)) path = _file_manager.enter_context(importlib.resources.as_file(vector_ref))
return str(path) return str(path)
def load_vector(*names: str) -> bytes: def load_vector(*names: str) -> bytes:
"""Load contents of a test vector.""" """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() data = vector_ref.read_bytes()
# Try at most to convert CRLF to LF when data is text # Try at most to convert CRLF to LF when data is text
try: try:
-1
View File
@@ -32,7 +32,6 @@ install_requires = [
'configobj>=5.0.6', 'configobj>=5.0.6',
'cryptography>=3.2.1', 'cryptography>=3.2.1',
'distro>=1.0.1', 'distro>=1.0.1',
'importlib_resources>=1.3.1; python_version < "3.9"',
'importlib_metadata>=4.6; python_version < "3.10"', 'importlib_metadata>=4.6; python_version < "3.10"',
# Josepy 2+ may introduce backward incompatible changes by droping usage of # Josepy 2+ may introduce backward incompatible changes by droping usage of
# deprecated PyOpenSSL APIs. # deprecated PyOpenSSL APIs.
-1
View File
@@ -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" 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" 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-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" 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" 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" isort==5.13.2 ; python_version >= "3.9" and python_version < "3.10"
+15 -16
View File
@@ -8,15 +8,15 @@
alabaster==0.7.16 ; python_version >= "3.9" and python_version < "4.0" 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" 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" 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" 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-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" 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" 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" 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" 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" boto3==1.35.74 ; python_version >= "3.9" and python_version < "4.0"
botocore==1.35.69 ; 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" 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" 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" 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" 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" 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" 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" 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-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" 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" 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" 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" 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-metadata==8.5.0 ; python_version >= "3.9" and python_version < "3.12"
importlib-resources==6.4.5 ; python_version >= "3.9" and python_version < "4.0"
iniconfig==2.0.0 ; python_version >= "3.9" and python_version < "4.0" 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" 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" 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" 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-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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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-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-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-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-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" 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" 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" 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" 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" 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" 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" 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" 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-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-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-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-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-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-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-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" 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" 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" 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" 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" 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" 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" 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" 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" 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"