diff --git a/acme/src/acme/__init__.py b/acme/src/acme/__init__.py index 9a0f5d6e0..bd48fbfcd 100644 --- a/acme/src/acme/__init__.py +++ b/acme/src/acme/__init__.py @@ -13,7 +13,7 @@ import warnings # # It is based on # https://github.com/requests/requests/blob/1278ecdf71a312dc2268f3bfc0aabfab3c006dcf/requests/packages.py -import josepy as jose +import josepy as jose # noqa: F401 for mod in list(sys.modules): # This traversal is apparently necessary such that the identities are diff --git a/acme/src/acme/_internal/tests/client_test.py b/acme/src/acme/_internal/tests/client_test.py index 7d8f44f9c..ad7cd0c3e 100644 --- a/acme/src/acme/_internal/tests/client_test.py +++ b/acme/src/acme/_internal/tests/client_test.py @@ -293,7 +293,7 @@ class ClientV2Test(unittest.TestCase): updated_order_valid = self.order.update( certificate='https://www.letsencrypt-demo.org/acme/cert/', status=messages.STATUS_VALID) - updated_orderr = self.orderr.update(body=updated_order_valid, fullchain_pem=CERT_SAN_PEM) + self.orderr.update(body=updated_order_valid, fullchain_pem=CERT_SAN_PEM) self.response.text = CERT_SAN_PEM @@ -489,14 +489,14 @@ class ClientV2Test(unittest.TestCase): not_after=datetime.datetime(2025, 3, 20, 00, 00, 00), ) t, _ = self.client.renewal_time(cert_pem) - assert t == None + assert t is None cert_pem = make_cert_for_renewal( not_before=datetime.datetime(2025, 3, 12, 00, 00, 00), not_after=datetime.datetime(2025, 3, 30, 00, 00, 00), ) t, _ = self.client.renewal_time(cert_pem) - assert t == None + assert t is None @mock.patch('acme.client.datetime') def test_renewal_time_with_renewal_info(self, dt_mock): diff --git a/acme/src/acme/_internal/tests/crypto_util_test.py b/acme/src/acme/_internal/tests/crypto_util_test.py index d149cdb87..91438fdec 100644 --- a/acme/src/acme/_internal/tests/crypto_util_test.py +++ b/acme/src/acme/_internal/tests/crypto_util_test.py @@ -123,7 +123,7 @@ class GenMakeSelfSignedCertTest(unittest.TestCase): def test_no_ips(self): from acme.crypto_util import make_self_signed_cert - cert = make_self_signed_cert(self.privkey, ['dummy']) + make_self_signed_cert(self.privkey, ['dummy']) @mock.patch("acme.crypto_util._now") def test_expiry_times(self, mock_now): diff --git a/acme/src/acme/_internal/tests/jose_test.py b/acme/src/acme/_internal/tests/jose_test.py index 83787db15..3da1ece0a 100644 --- a/acme/src/acme/_internal/tests/jose_test.py +++ b/acme/src/acme/_internal/tests/jose_test.py @@ -20,9 +20,9 @@ def _test_it(submodule, attribute): # We use the imports below with eval, but pylint doesn't # understand that. - import josepy # pylint: disable=unused-import + import josepy # pylint: disable=unused-import # noqa: F401 - import acme # pylint: disable=unused-import + import acme # pylint: disable=unused-import # noqa: F401 acme_jose_mod = eval(acme_jose_path) # pylint: disable=eval-used josepy_mod = eval(josepy_path) # pylint: disable=eval-used assert acme_jose_mod is josepy_mod diff --git a/acme/src/acme/client.py b/acme/src/acme/client.py index 64c90e06e..4ce42b1ff 100644 --- a/acme/src/acme/client.py +++ b/acme/src/acme/client.py @@ -419,8 +419,8 @@ class ClientV2: if 'Link' not in response.headers: return [] links = parse_header_links(response.headers['Link']) - return [l['url'] for l in links - if 'rel' in l and 'url' in l and l['rel'] == relation_type] + return [link['url'] for link in links + if 'rel' in link and 'url' in link and link['rel'] == relation_type] @classmethod def get_directory(cls, url: str, net: 'ClientNetwork') -> messages.Directory: diff --git a/certbot-apache/src/certbot_apache/_internal/tests/configurator_test.py b/certbot-apache/src/certbot_apache/_internal/tests/configurator_test.py index 6a5595d31..1ec50e4da 100644 --- a/certbot-apache/src/certbot_apache/_internal/tests/configurator_test.py +++ b/certbot-apache/src/certbot_apache/_internal/tests/configurator_test.py @@ -1245,7 +1245,7 @@ class MultipleVhostsTest(util.ApacheTest): def test_deploy_cert_no_mod_ssl(self): # Create - ssl_vhost = self.config.make_vhost_ssl(self.vh_truth[0]) + self.config.make_vhost_ssl(self.vh_truth[0]) self.config.parser.modules["socache_shmcb_module"] = None self.config.prepare_server_https = mock.Mock() diff --git a/certbot-apache/src/certbot_apache/_internal/tests/parsernode_configurator_test.py b/certbot-apache/src/certbot_apache/_internal/tests/parsernode_configurator_test.py index 596b424f7..f6eaccd38 100644 --- a/certbot-apache/src/certbot_apache/_internal/tests/parsernode_configurator_test.py +++ b/certbot-apache/src/certbot_apache/_internal/tests/parsernode_configurator_test.py @@ -1,4 +1,5 @@ """Tests for ApacheConfigurator for AugeasParserNode classes""" +import importlib import sys import unittest from unittest import mock @@ -7,10 +8,10 @@ import pytest from certbot_apache._internal.tests import util -try: - import apacheconfig + +if importlib.util.find_spec('apacheconfig'): HAS_APACHECONFIG = True -except ImportError: # pragma: no cover +else: # pragma: no cover HAS_APACHECONFIG = False diff --git a/certbot-apache/src/certbot_apache/_internal/tests/parsernode_test.py b/certbot-apache/src/certbot_apache/_internal/tests/parsernode_test.py index d85e8c753..d9e20ee64 100644 --- a/certbot-apache/src/certbot_apache/_internal/tests/parsernode_test.py +++ b/certbot-apache/src/certbot_apache/_internal/tests/parsernode_test.py @@ -112,12 +112,12 @@ def test_dummy(): dirty=False, filepath="/some/random/path" ) - dummydirective = DummyDirectiveNode( + dummydirective = DummyDirectiveNode( # noqa: F841 name="Name", ancestor=None, filepath="/another/path" ) - dummycomment = DummyCommentNode( + dummycomment = DummyCommentNode( # noqa: F841 comment="Comment", ancestor=dummyblock, filepath="/some/file" diff --git a/certbot-ci/src/certbot_integration_tests/utils/acme_server.py b/certbot-ci/src/certbot_integration_tests/utils/acme_server.py index 130c398c7..b196fa8c6 100755 --- a/certbot-ci/src/certbot_integration_tests/utils/acme_server.py +++ b/certbot-ci/src/certbot_integration_tests/utils/acme_server.py @@ -24,7 +24,12 @@ from certbot_integration_tests.utils import misc from certbot_integration_tests.utils import pebble_artifacts from certbot_integration_tests.utils import pebble_ocsp_server from certbot_integration_tests.utils import proxy -from certbot_integration_tests.utils.constants import * +from certbot_integration_tests.utils.constants import DEFAULT_HTTP_01_PORT +from certbot_integration_tests.utils.constants import CHALLTESTSRV_PORT +from certbot_integration_tests.utils.constants import PEBBLE_DIRECTORY_URL +from certbot_integration_tests.utils.constants import PEBBLE_CHALLTESTSRV_URL +from certbot_integration_tests.utils.constants import PEBBLE_ALTERNATE_ROOTS +from certbot_integration_tests.utils.constants import MAX_SUBPROCESS_WAIT class ACMEServer: diff --git a/certbot-ci/src/certbot_integration_tests/utils/certbot_call.py b/certbot-ci/src/certbot_integration_tests/utils/certbot_call.py index 07b6d4182..2fc6021a7 100755 --- a/certbot-ci/src/certbot_integration_tests/utils/certbot_call.py +++ b/certbot-ci/src/certbot_integration_tests/utils/certbot_call.py @@ -10,8 +10,9 @@ from typing import Optional from typing import Tuple import certbot_integration_tests -# pylint: disable=wildcard-import,unused-wildcard-import -from certbot_integration_tests.utils.constants import * +from certbot_integration_tests.utils.constants import DEFAULT_HTTP_01_PORT +from certbot_integration_tests.utils.constants import HTTPS_PORT +from certbot_integration_tests.utils.constants import PEBBLE_DIRECTORY_URL def certbot_test(certbot_args: List[str], directory_url: Optional[str], http_01_port: int, diff --git a/certbot-dns-route53/src/certbot_dns_route53/_internal/tests/dns_route53_test.py b/certbot-dns-route53/src/certbot_dns_route53/_internal/tests/dns_route53_test.py index 95a90434f..e6df0c93e 100644 --- a/certbot-dns-route53/src/certbot_dns_route53/_internal/tests/dns_route53_test.py +++ b/certbot-dns-route53/src/certbot_dns_route53/_internal/tests/dns_route53_test.py @@ -17,7 +17,6 @@ from certbot.plugins.dns_test_common import DOMAIN from certbot.tests import acme_util from certbot.tests import util as test_util -DOMAIN = 'example.com' KEY = jose.jwk.JWKRSA.load(test_util.load_vector("rsa512_key.pem")) diff --git a/certbot/setup.py b/certbot/setup.py index 170626363..587266717 100644 --- a/certbot/setup.py +++ b/certbot/setup.py @@ -71,6 +71,7 @@ test_extras = [ 'pytest', 'pytest-cov', 'pytest-xdist', + 'ruff', 'setuptools', 'tox', 'types-httplib2', diff --git a/certbot/src/certbot/_internal/cli/__init__.py b/certbot/src/certbot/_internal/cli/__init__.py index 63f951150..31964153f 100644 --- a/certbot/src/certbot/_internal/cli/__init__.py +++ b/certbot/src/certbot/_internal/cli/__init__.py @@ -1,5 +1,6 @@ """Certbot command line argument & config processing.""" # pylint: disable=too-many-lines +# ruff: noqa: F401 import argparse import logging import logging.handlers diff --git a/certbot/src/certbot/_internal/tests/auth_handler_test.py b/certbot/src/certbot/_internal/tests/auth_handler_test.py index 0a61c8e8e..6c8a2d808 100644 --- a/certbot/src/certbot/_internal/tests/auth_handler_test.py +++ b/certbot/src/certbot/_internal/tests/auth_handler_test.py @@ -51,7 +51,7 @@ class ChallengeFactoryTest(unittest.TestCase): [messages.STATUS_PENDING]) achalls = self.handler._challenge_factory(authzr, [0]) - assert type(achalls[0]) == achallenges.Other + assert type(achalls[0]) is achallenges.Other class HandleAuthorizationsTest(unittest.TestCase): diff --git a/certbot/src/certbot/_internal/tests/cert_manager_test.py b/certbot/src/certbot/_internal/tests/cert_manager_test.py index fae9de8d8..a079141c0 100644 --- a/certbot/src/certbot/_internal/tests/cert_manager_test.py +++ b/certbot/src/certbot/_internal/tests/cert_manager_test.py @@ -226,7 +226,8 @@ class CertificatesTest(BaseCertManagerTest): # pylint: disable=protected-access # pylint: disable=protected-access - get_report = lambda: cert_manager._report_human_readable(mock_config, parsed_certs) + def get_report(): + return cert_manager._report_human_readable(mock_config, parsed_certs) out = get_report() assert "INVALID: EXPIRED" in out diff --git a/certbot/src/certbot/_internal/tests/cli_test.py b/certbot/src/certbot/_internal/tests/cli_test.py index 5602734f3..f55ae65be 100644 --- a/certbot/src/certbot/_internal/tests/cli_test.py +++ b/certbot/src/certbot/_internal/tests/cli_test.py @@ -117,11 +117,10 @@ class ParseTest(unittest.TestCase): with tempfile.NamedTemporaryFile() as tmp_config: tmp_config.close() # close now because of compatibility issues on Windows # use a shim to get ConfigArgParse to pick up tmp_config - shim = ( - lambda v: copy.deepcopy(constants.CLI_DEFAULTS[v]) - if v != "config_files" - else [tmp_config.name] - ) + def shim(v): + return (copy.deepcopy(constants.CLI_DEFAULTS[v]) + if v != "config_files" + else [tmp_config.name]) mock_flag_default.side_effect = shim namespace = self.parse(["certonly"]) diff --git a/certbot/src/certbot/_internal/tests/client_test.py b/certbot/src/certbot/_internal/tests/client_test.py index 3c4197234..9b92c0c43 100644 --- a/certbot/src/certbot/_internal/tests/client_test.py +++ b/certbot/src/certbot/_internal/tests/client_test.py @@ -1061,7 +1061,7 @@ class EnhanceConfigTest(ClientTestCommon): def _test_error(self, enhance_error=False, restart_error=False): self.config.redirect = True with mock.patch('certbot._internal.client.logger') as mock_logger, \ - test_util.patch_display_util() as mock_gu: + test_util.patch_display_util(): with pytest.raises(errors.PluginError): self._test_with_all_supported() diff --git a/certbot/src/certbot/_internal/tests/compat/filesystem_test.py b/certbot/src/certbot/_internal/tests/compat/filesystem_test.py index 2f5d4e7e5..565f17087 100644 --- a/certbot/src/certbot/_internal/tests/compat/filesystem_test.py +++ b/certbot/src/certbot/_internal/tests/compat/filesystem_test.py @@ -565,7 +565,7 @@ class RealpathTest(test_util.TempDirTestCase): os.symlink(link2_path, link3_path) os.symlink(link3_path, link1_path) - with pytest.raises(RuntimeError, match='link1 is a loop!') as error: + with pytest.raises(RuntimeError, match='link1 is a loop!'): filesystem.realpath(link1_path) diff --git a/certbot/src/certbot/_internal/tests/lock_test.py b/certbot/src/certbot/_internal/tests/lock_test.py index f8ff8b59a..9a56e31a1 100644 --- a/certbot/src/certbot/_internal/tests/lock_test.py +++ b/certbot/src/certbot/_internal/tests/lock_test.py @@ -1,5 +1,6 @@ """Tests for certbot._internal.lock.""" import functools +import importlib import multiprocessing import sys from unittest import mock @@ -10,13 +11,10 @@ from certbot import errors from certbot.compat import os from certbot.tests import util as test_util -try: - import fcntl # pylint: disable=import-error,unused-import -except ImportError: - POSIX_MODE = False -else: +if importlib.util.find_spec('fcntl'): POSIX_MODE = True - +else: + POSIX_MODE = False diff --git a/certbot/src/certbot/_internal/tests/renewal_test.py b/certbot/src/certbot/_internal/tests/renewal_test.py index a0f2facd1..a6b1449c4 100644 --- a/certbot/src/certbot/_internal/tests/renewal_test.py +++ b/certbot/src/certbot/_internal/tests/renewal_test.py @@ -198,7 +198,7 @@ class RenewalTest(test_util.ConfigTestCase): from certbot._internal import renewal lineage_config = copy.deepcopy(self.config) - renewal_candidate = renewal.reconstitute(lineage_config, rc_path) + renewal.reconstitute(lineage_config, rc_path) # This means that manual_public_ip_logging_ok was not modified in the config based on its # value in the renewal conf file assert isinstance(lineage_config.manual_public_ip_logging_ok, mock.MagicMock) @@ -233,7 +233,7 @@ class RenewalTest(test_util.ConfigTestCase): test_util.make_lineage(self.config.config_dir, 'sample-renewal.conf', ec=False) config = configuration.NamespaceConfig(self.config) - with mock.patch('time.sleep') as sleep: + with mock.patch('time.sleep'): renewal.handle_renewal_request(config) mock_renew_cert.assert_called_once() @@ -254,7 +254,7 @@ class RenewalTest(test_util.ConfigTestCase): test_util.make_lineage(self.config.config_dir, 'sample-renewal.conf', ec=False) - with mock.patch('time.sleep') as sleep: + with mock.patch('time.sleep'): renewal.handle_renewal_request(self.config) assert mock_client_network_get.call_count == 0 @@ -265,7 +265,7 @@ class RenewalTest(test_util.ConfigTestCase): self.config.dry_run = True ari_client_pool = mock.MagicMock() ari_client_pool.get.return_value = mock_acme - with mock.patch('time.sleep') as sleep: + with mock.patch('time.sleep'): renewal.should_renew(self.config, mock.Mock(), ari_client_pool) assert mock_acme.renewal_time.call_count == 0 diff --git a/certbot/src/certbot/compat/_path.py b/certbot/src/certbot/compat/_path.py index c36421b7e..bc37833af 100644 --- a/certbot/src/certbot/compat/_path.py +++ b/certbot/src/certbot/compat/_path.py @@ -13,7 +13,7 @@ from __future__ import absolute_import # First round of wrapping: we import statically all public attributes exposed by the os.path # module. This allows in particular to have pylint, mypy, IDEs be aware that most of os.path # members are available in certbot.compat.path. -from os.path import * # pylint: disable=wildcard-import,unused-wildcard-import,os-module-forbidden +from os.path import * # pylint: disable=wildcard-import,unused-wildcard-import,os-module-forbidden # noqa: F403 # Second round of wrapping: we import dynamically all attributes from the os.path module that have # not yet been imported by the first round (static star import). diff --git a/certbot/src/certbot/compat/os.py b/certbot/src/certbot/compat/os.py index 3aa9a527f..82f570459 100644 --- a/certbot/src/certbot/compat/os.py +++ b/certbot/src/certbot/compat/os.py @@ -21,7 +21,7 @@ from __future__ import absolute_import # First round of wrapping: we import statically all public attributes exposed by the os module # This allows in particular to have pylint, mypy, IDEs be aware that most of os members are # available in certbot.compat.os. -from os import * # pylint: disable=wildcard-import,unused-wildcard-import,redefined-builtin,os-module-forbidden +from os import * # pylint: disable=wildcard-import,unused-wildcard-import,redefined-builtin,os-module-forbidden # noqa: F403 # Second round of wrapping: we import dynamically all attributes from the os module that have not # yet been imported by the first round (static import). This covers in particular the case of @@ -43,7 +43,7 @@ if not std_os.environ.get("CERTBOT_DOCS") == "1": # Import our internal path module, then allow certbot.compat.os.path # to behave as a module (similarly to os.path). -from certbot.compat import _path as path # type: ignore # pylint: disable=wrong-import-position +from certbot.compat import _path as path # type: ignore # pylint: disable=wrong-import-position # noqa: E402 std_sys.modules[__name__ + '.path'] = path # Clean all remaining importables that are not from the core os module. diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 000000000..5fb3b891f --- /dev/null +++ b/ruff.toml @@ -0,0 +1,8 @@ +line-length = 100 + +extend-exclude = ['tools', 'letstest'] + +[lint] +# Skip bare `except` rules (`E722`). +# Skip ambiguous variable name (`E741`). +ignore = ["E722", "E741",] diff --git a/tools/oldest_constraints.txt b/tools/oldest_constraints.txt index 12066cbe3..3d7c84716 100644 --- a/tools/oldest_constraints.txt +++ b/tools/oldest_constraints.txt @@ -2,28 +2,28 @@ # that script. apacheconfig==0.3.2 ; python_full_version >= "3.9.2" and python_version < "3.10" asn1crypto==0.24.0 ; python_full_version >= "3.9.2" and python_version < "3.10" -astroid==3.3.9 ; python_full_version >= "3.9.2" and python_version < "3.10" +astroid==3.3.11 ; python_full_version >= "3.9.2" and python_version < "3.10" attrs==25.3.0 ; python_full_version >= "3.9.2" and python_version < "3.10" beautifulsoup4==4.13.4 ; python_full_version >= "3.9.2" and python_version < "3.10" boto3==1.15.15 ; python_full_version >= "3.9.2" and python_version < "3.10" botocore==1.18.15 ; python_full_version >= "3.9.2" and python_version < "3.10" cachetools==5.5.2 ; python_full_version >= "3.9.2" and python_version < "3.10" -certifi==2025.4.26 ; python_full_version >= "3.9.2" and python_version < "3.10" +certifi==2025.8.3 ; python_full_version >= "3.9.2" and python_version < "3.10" cffi==1.12.3 ; python_full_version >= "3.9.2" and python_version < "3.10" chardet==3.0.4 ; python_full_version >= "3.9.2" and python_version < "3.10" cloudflare==2.19.0 ; python_full_version >= "3.9.2" and python_version < "3.10" colorama==0.4.6 ; python_full_version >= "3.9.2" and python_version < "3.10" and sys_platform == "win32" configargparse==1.5.3 ; python_full_version >= "3.9.2" and python_version < "3.10" configobj==5.0.6 ; python_full_version >= "3.9.2" and python_version < "3.10" -coverage==7.8.0 ; python_full_version >= "3.9.2" and python_version < "3.10" +coverage==7.10.2 ; python_full_version >= "3.9.2" and python_version < "3.10" cryptography==43.0.0 ; python_full_version >= "3.9.2" and python_version < "3.10" cython==0.29.37 ; python_full_version >= "3.9.2" and python_version < "3.10" dill==0.4.0 ; python_full_version >= "3.9.2" and python_version < "3.10" -distlib==0.3.9 ; python_full_version >= "3.9.2" and python_version < "3.10" +distlib==0.4.0 ; python_full_version >= "3.9.2" and python_version < "3.10" distro==1.0.1 ; python_full_version >= "3.9.2" and python_version < "3.10" dns-lexicon==3.15.1 ; python_full_version >= "3.9.2" and python_version < "3.10" dnspython==2.6.1 ; python_full_version >= "3.9.2" and python_version < "3.10" -exceptiongroup==1.2.2 ; python_full_version >= "3.9.2" and python_version < "3.10" +exceptiongroup==1.3.0 ; python_full_version >= "3.9.2" and python_version < "3.10" execnet==2.1.1 ; python_full_version >= "3.9.2" and python_version < "3.10" filelock==3.18.0 ; python_full_version >= "3.9.2" and python_version < "3.10" funcsigs==0.4 ; python_full_version >= "3.9.2" and python_version < "3.10" @@ -37,58 +37,62 @@ iniconfig==2.1.0 ; python_full_version >= "3.9.2" and python_version < "3.10" ipaddress==1.0.16 ; python_full_version >= "3.9.2" and python_version < "3.10" isort==6.0.1 ; python_full_version >= "3.9.2" and python_version < "3.10" jmespath==0.10.0 ; python_full_version >= "3.9.2" and python_version < "3.10" -josepy==2.0.0 ; python_full_version >= "3.9.2" and python_version < "3.10" +josepy==2.1.0 ; python_full_version >= "3.9.2" and python_version < "3.10" jsonlines==4.0.0 ; python_full_version >= "3.9.2" and python_version < "3.10" mccabe==0.7.0 ; python_full_version >= "3.9.2" and python_version < "3.10" mypy-extensions==1.1.0 ; python_full_version >= "3.9.2" and python_version < "3.10" -mypy==1.15.0 ; python_full_version >= "3.9.2" and python_version < "3.10" +mypy==1.17.1 ; python_full_version >= "3.9.2" and python_version < "3.10" ndg-httpsclient==0.3.2 ; python_full_version >= "3.9.2" and python_version < "3.10" oauth2client==4.1.3 ; python_full_version >= "3.9.2" and python_version < "3.10" packaging==25.0 ; python_full_version >= "3.9.2" and python_version < "3.10" parsedatetime==2.4 ; python_full_version >= "3.9.2" and python_version < "3.10" +pathspec==0.12.1 ; python_full_version >= "3.9.2" and python_version < "3.10" pbr==1.8.0 ; python_full_version >= "3.9.2" and python_version < "3.10" -pip==25.1 ; python_full_version >= "3.9.2" and python_version < "3.10" -platformdirs==4.3.7 ; python_full_version >= "3.9.2" and python_version < "3.10" -pluggy==1.5.0 ; python_full_version >= "3.9.2" and python_version < "3.10" +pip==25.2 ; python_full_version >= "3.9.2" and python_version < "3.10" +platformdirs==4.3.8 ; python_full_version >= "3.9.2" and python_version < "3.10" +pluggy==1.6.0 ; python_full_version >= "3.9.2" and python_version < "3.10" ply==3.4 ; python_full_version >= "3.9.2" and python_version < "3.10" py==1.11.0 ; python_full_version >= "3.9.2" and python_version < "3.10" pyasn1-modules==0.4.1 ; python_full_version >= "3.9.2" and python_version < "3.10" pyasn1==0.4.8 ; python_full_version >= "3.9.2" and python_version < "3.10" pycparser==2.14 ; python_full_version >= "3.9.2" and python_version < "3.10" -pylint==3.3.6 ; python_full_version >= "3.9.2" and python_version < "3.10" +pygments==2.19.2 ; python_full_version >= "3.9.2" and python_version < "3.10" +pylint==3.3.7 ; python_full_version >= "3.9.2" and python_version < "3.10" pyopenssl==25.0.0 ; python_full_version >= "3.9.2" and python_version < "3.10" pyotp==2.9.0 ; python_full_version >= "3.9.2" and python_version < "3.10" pyparsing==2.4.7 ; python_full_version >= "3.9.2" and python_version < "3.10" pyrfc3339==1.0 ; python_full_version >= "3.9.2" and python_version < "3.10" -pytest-cov==6.1.1 ; python_full_version >= "3.9.2" and python_version < "3.10" -pytest-xdist==3.6.1 ; python_full_version >= "3.9.2" and python_version < "3.10" -pytest==8.3.5 ; python_full_version >= "3.9.2" and python_version < "3.10" +pytest-cov==6.2.1 ; python_full_version >= "3.9.2" and python_version < "3.10" +pytest-xdist==3.8.0 ; python_full_version >= "3.9.2" and python_version < "3.10" +pytest==8.4.1 ; python_full_version >= "3.9.2" and python_version < "3.10" python-augeas==0.5.0 ; python_full_version >= "3.9.2" and python_version < "3.10" python-dateutil==2.9.0.post0 ; python_full_version >= "3.9.2" and python_version < "3.10" python-digitalocean==1.11 ; python_full_version >= "3.9.2" and python_version < "3.10" -pywin32==310 ; python_full_version >= "3.9.2" and python_version < "3.10" and sys_platform == "win32" +pytz==2025.2 ; python_full_version >= "3.9.2" and python_version < "3.10" +pywin32==311 ; python_full_version >= "3.9.2" and python_version < "3.10" and sys_platform == "win32" pyyaml==6.0.2 ; python_full_version >= "3.9.2" and python_version < "3.10" requests-file==2.1.0 ; python_full_version >= "3.9.2" and python_version < "3.10" requests==2.20.0 ; python_full_version >= "3.9.2" and python_version < "3.10" rsa==4.9.1 ; python_full_version >= "3.9.2" and python_version < "3.10" +ruff==0.12.8 ; python_full_version >= "3.9.2" and python_version < "3.10" s3transfer==0.3.7 ; python_full_version >= "3.9.2" and python_version < "3.10" -setuptools==80.0.1 ; python_full_version >= "3.9.2" and python_version < "3.10" +setuptools==80.9.0 ; python_full_version >= "3.9.2" and python_version < "3.10" six==1.11.0 ; python_full_version >= "3.9.2" and python_version < "3.10" soupsieve==2.7 ; python_full_version >= "3.9.2" and python_version < "3.10" tldextract==5.3.0 ; python_full_version >= "3.9.2" and python_version < "3.10" tomli==2.2.1 ; python_full_version >= "3.9.2" and python_version < "3.10" -tomlkit==0.13.2 ; python_full_version >= "3.9.2" and python_version < "3.10" +tomlkit==0.13.3 ; python_full_version >= "3.9.2" and python_version < "3.10" tox==1.9.2 ; python_full_version >= "3.9.2" and python_version < "3.10" -types-httplib2==0.22.0.20250401 ; python_full_version >= "3.9.2" and python_version < "3.10" +types-httplib2==0.22.0.20250622 ; python_full_version >= "3.9.2" and python_version < "3.10" types-pyrfc3339==2.0.1.20241107 ; python_full_version >= "3.9.2" and python_version < "3.10" -types-python-dateutil==2.9.0.20241206 ; python_full_version >= "3.9.2" and python_version < "3.10" -types-pywin32==310.0.0.20250429 ; python_full_version >= "3.9.2" and python_version < "3.10" +types-python-dateutil==2.9.0.20250708 ; python_full_version >= "3.9.2" and python_version < "3.10" +types-pywin32==311.0.0.20250801 ; python_full_version >= "3.9.2" and python_version < "3.10" types-requests==2.31.0.6 ; python_full_version >= "3.9.2" and python_version < "3.10" -types-setuptools==80.0.0.20250429 ; python_full_version >= "3.9.2" and python_version < "3.10" +types-setuptools==80.9.0.20250801 ; python_full_version >= "3.9.2" and python_version < "3.10" types-urllib3==1.26.25.14 ; python_full_version >= "3.9.2" and python_version < "3.10" -typing-extensions==4.13.2 ; python_full_version >= "3.9.2" and python_version < "3.10" +typing-extensions==4.14.1 ; python_full_version >= "3.9.2" and python_version < "3.10" uritemplate==3.0.1 ; python_full_version >= "3.9.2" and python_version < "3.10" urllib3==1.24.2 ; python_full_version >= "3.9.2" and python_version < "3.10" -virtualenv==20.30.0 ; python_full_version >= "3.9.2" and python_version < "3.10" +virtualenv==20.33.1 ; python_full_version >= "3.9.2" and python_version < "3.10" wheel==0.45.1 ; python_full_version >= "3.9.2" and python_version < "3.10" -zipp==3.21.0 ; python_full_version >= "3.9.2" and python_version < "3.10" +zipp==3.23.0 ; python_full_version >= "3.9.2" and python_version < "3.10" diff --git a/tools/requirements.txt b/tools/requirements.txt index e2b7b6153..fbce7ddf8 100644 --- a/tools/requirements.txt +++ b/tools/requirements.txt @@ -7,7 +7,7 @@ # for more info. alabaster==0.7.16 ; python_full_version >= "3.9.2" and python_version < "3.10" alabaster==1.0.0 ; python_version >= "3.10" and python_version < "4.0" -anyio==4.9.0 ; python_full_version >= "3.9.2" and python_version < "4.0" +anyio==4.10.0 ; python_full_version >= "3.9.2" and python_version < "4.0" apacheconfig==0.3.2 ; python_full_version >= "3.9.2" and python_version < "4.0" astroid==3.3.11 ; python_full_version >= "3.9.2" and python_version < "4.0" asttokens==3.0.0 ; python_full_version >= "3.9.2" and python_version < "4.0" @@ -18,12 +18,12 @@ babel==2.17.0 ; python_full_version >= "3.9.2" and python_version < "4.0" backports-tarfile==1.2.0 ; python_full_version >= "3.9.2" and python_version < "3.12" bcrypt==4.3.0 ; python_full_version >= "3.9.2" and python_version < "4.0" beautifulsoup4==4.13.4 ; python_full_version >= "3.9.2" and python_version < "4.0" -boto3==1.39.16 ; python_full_version >= "3.9.2" and python_version < "4.0" -botocore==1.39.16 ; python_full_version >= "3.9.2" and python_version < "4.0" -build==1.2.2.post1 ; python_full_version >= "3.9.2" and python_version < "4.0" +boto3==1.40.5 ; python_full_version >= "3.9.2" and python_version < "4.0" +botocore==1.40.5 ; python_full_version >= "3.9.2" and python_version < "4.0" +build==1.3.0 ; python_full_version >= "3.9.2" and python_version < "4.0" cachecontrol==0.14.3 ; python_full_version >= "3.9.2" and python_version < "4.0" cachetools==5.5.2 ; python_full_version >= "3.9.2" and python_version < "4.0" -certifi==2025.7.14 ; python_full_version >= "3.9.2" and python_version < "4.0" +certifi==2025.8.3 ; python_full_version >= "3.9.2" and python_version < "4.0" cffi==1.17.1 ; python_full_version >= "3.9.2" and python_version < "4.0" chardet==5.2.0 ; python_full_version >= "3.9.2" and python_version < "4.0" charset-normalizer==3.4.2 ; python_full_version >= "3.9.2" and python_version < "4.0" @@ -34,9 +34,9 @@ cloudflare==2.19.4 ; python_full_version >= "3.9.2" and python_version < "4.0" colorama==0.4.6 ; python_full_version >= "3.9.2" and python_version < "4.0" configargparse==1.7.1 ; python_full_version >= "3.9.2" and python_version < "4.0" configobj==5.0.9 ; python_full_version >= "3.9.2" and python_version < "4.0" -coverage==7.10.1 ; python_full_version >= "3.9.2" and python_version < "4.0" +coverage==7.10.2 ; python_full_version >= "3.9.2" and python_version < "4.0" crashtest==0.4.1 ; python_full_version >= "3.9.2" and python_version < "4.0" -cryptography==45.0.5 ; python_full_version >= "3.9.2" and python_version < "4.0" +cryptography==45.0.6 ; python_full_version >= "3.9.2" and python_version < "4.0" cython==0.29.37 ; python_full_version >= "3.9.2" and python_version < "4.0" decorator==5.2.1 ; python_full_version >= "3.9.2" and python_version < "4.0" deprecated==1.2.18 ; python_full_version >= "3.9.2" and python_version < "4.0" @@ -55,7 +55,7 @@ fastjsonschema==2.21.1 ; python_full_version >= "3.9.2" and python_version < "4. filelock==3.18.0 ; python_full_version >= "3.9.2" and python_version < "4.0" findpython==0.6.3 ; python_full_version >= "3.9.2" and python_version < "4.0" google-api-core==2.25.1 ; python_full_version >= "3.9.2" and python_version < "4.0" -google-api-python-client==2.177.0 ; python_full_version >= "3.9.2" and python_version < "4.0" +google-api-python-client==2.178.0 ; python_full_version >= "3.9.2" and python_version < "4.0" google-auth-httplib2==0.2.0 ; python_full_version >= "3.9.2" and python_version < "4.0" google-auth==2.40.3 ; python_full_version >= "3.9.2" and python_version < "4.0" googleapis-common-protos==1.70.0 ; python_full_version >= "3.9.2" and python_version < "4.0" @@ -103,19 +103,19 @@ mypy==1.9.0 ; python_full_version >= "3.9.2" and python_version < "4.0" nh3==0.3.0 ; python_full_version >= "3.9.2" and python_version < "4.0" oauthlib==3.3.1 ; python_full_version >= "3.9.2" and python_version < "4.0" packaging==25.0 ; python_full_version >= "3.9.2" and python_version < "4.0" -paramiko==3.5.1 ; python_full_version >= "3.9.2" and python_version < "4.0" +paramiko==4.0.0 ; python_full_version >= "3.9.2" and python_version < "4.0" parsedatetime==2.6 ; python_full_version >= "3.9.2" and python_version < "4.0" parso==0.8.4 ; python_full_version >= "3.9.2" and python_version < "4.0" -pbs-installer==2025.7.23 ; python_full_version >= "3.9.2" and python_version < "4.0" +pbs-installer==2025.8.7 ; python_full_version >= "3.9.2" and python_version < "4.0" pexpect==4.9.0 ; python_full_version >= "3.9.2" and python_version < "4.0" and (sys_platform != "win32" and sys_platform != "emscripten" or python_version < "3.10") and sys_platform != "win32" -pip==25.1.1 ; python_full_version >= "3.9.2" and python_version < "4.0" +pip==25.2 ; python_full_version >= "3.9.2" and python_version < "4.0" pkginfo==1.12.1.2 ; python_full_version >= "3.9.2" and python_version < "4.0" platformdirs==4.3.8 ; python_full_version >= "3.9.2" and python_version < "4.0" pluggy==1.6.0 ; python_full_version >= "3.9.2" and python_version < "4.0" ply==3.11 ; python_full_version >= "3.9.2" and python_version < "4.0" poetry-core==2.1.3 ; python_full_version >= "3.9.2" and python_version < "4.0" poetry-plugin-export==1.9.0 ; python_full_version >= "3.9.2" and python_version < "4.0" -poetry==2.1.3 ; python_full_version >= "3.9.2" and python_version < "4.0" +poetry==2.1.4 ; python_full_version >= "3.9.2" and python_version < "4.0" prompt-toolkit==3.0.51 ; python_full_version >= "3.9.2" and python_version < "4.0" proto-plus==1.26.1 ; python_full_version >= "3.9.2" and python_version < "4.0" protobuf==6.31.1 ; python_full_version >= "3.9.2" and python_version < "4.0" @@ -152,6 +152,7 @@ rfc3986==2.0.0 ; python_full_version >= "3.9.2" and python_version < "4.0" rich==14.1.0 ; python_full_version >= "3.9.2" and python_version < "4.0" roman-numerals-py==3.1.0 ; python_version >= "3.11" and python_version < "4.0" rsa==4.9.1 ; python_full_version >= "3.9.2" and python_version < "4.0" +ruff==0.12.8 ; python_full_version >= "3.9.2" and python_version < "4.0" s3transfer==0.13.1 ; python_full_version >= "3.9.2" and python_version < "4.0" secretstorage==3.3.3 ; python_full_version >= "3.9.2" and python_version < "4.0" and sys_platform == "linux" semantic-version==2.10.0 ; python_full_version >= "3.9.2" and python_version < "4.0" @@ -180,15 +181,15 @@ tomlkit==0.13.3 ; python_full_version >= "3.9.2" and python_version < "4.0" towncrier==24.8.0 ; python_full_version >= "3.9.2" and python_version < "4.0" tox==4.27.0 ; python_full_version >= "3.9.2" and python_version < "4.0" traitlets==5.14.3 ; python_full_version >= "3.9.2" and python_version < "4.0" -trove-classifiers==2025.5.9.12 ; python_full_version >= "3.9.2" and python_version < "4.0" +trove-classifiers==2025.8.6.13 ; python_full_version >= "3.9.2" and python_version < "4.0" twine==6.1.0 ; python_full_version >= "3.9.2" and python_version < "4.0" types-httplib2==0.22.0.20250622 ; python_full_version >= "3.9.2" and python_version < "4.0" types-pyrfc3339==2.0.1.20241107 ; python_full_version >= "3.9.2" and python_version < "4.0" types-python-dateutil==2.9.0.20250708 ; python_full_version >= "3.9.2" and python_version < "4.0" -types-pywin32==311.0.0.20250728 ; python_full_version >= "3.9.2" and python_version < "4.0" +types-pywin32==311.0.0.20250801 ; python_full_version >= "3.9.2" and python_version < "4.0" types-requests==2.31.0.6 ; python_full_version >= "3.9.2" and python_version < "3.10" types-requests==2.32.4.20250611 ; python_version >= "3.10" and python_version < "4.0" -types-setuptools==80.9.0.20250529 ; python_full_version >= "3.9.2" and python_version < "4.0" +types-setuptools==80.9.0.20250801 ; python_full_version >= "3.9.2" and python_version < "4.0" types-urllib3==1.26.25.14 ; python_full_version >= "3.9.2" and python_version < "3.10" typing-extensions==4.14.1 ; python_full_version >= "3.9.2" and python_version < "4.0" uritemplate==4.2.0 ; python_full_version >= "3.9.2" and python_version < "4.0" diff --git a/tox.ini b/tox.ini index 29e1dcf25..f74c56d99 100644 --- a/tox.ini +++ b/tox.ini @@ -98,7 +98,9 @@ commands = commands = {[testenv:cover]commands} [testenv:lint{,-posix}] -commands = python -m pylint --reports=n --rcfile=.pylintrc {[base]source_paths} +commands = + python -m pylint --reports=n --rcfile=.pylintrc {[base]source_paths} + ruff check [testenv:mypy] deps =