Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-acme for openSUSE:Factory checked in at 2026-02-09 19:28:25 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-acme (Old) and /work/SRC/openSUSE:Factory/.python-acme.new.1670 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-acme" Mon Feb 9 19:28:25 2026 rev:79 rq:1332023 version:5.3.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-acme/python-acme.changes 2026-01-17 14:55:10.048221164 +0100 +++ /work/SRC/openSUSE:Factory/.python-acme.new.1670/python-acme.changes 2026-02-09 19:28:34.063223066 +0100 @@ -1,0 +2,12 @@ +Mon Feb 9 12:26:27 UTC 2026 - Markéta Machová <[email protected]> + +- Update to 5.3.0 + * Deprecated acme.crypto_util.Format in our effort to remove our + pyOpenSSL dependency + * achallenges.KeyAuthorizationAnnotatedChallenge, achallenges.DNS, + and achallenges.Other have a new field identifier, of type + acme.messages.Identifier. This should be used in place of the + domain field, which is now deprecated both as an attribute and + during object creation. + +------------------------------------------------------------------- Old: ---- acme-5.2.2.tar.gz New: ---- acme-5.3.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-acme.spec ++++++ --- /var/tmp/diff_new_pack.B51DxE/_old 2026-02-09 19:28:35.327275925 +0100 +++ /var/tmp/diff_new_pack.B51DxE/_new 2026-02-09 19:28:35.331276092 +0100 @@ -19,7 +19,7 @@ %{?sle15_python_module_pythons} %define libname acme Name: python-%{libname} -Version: 5.2.2 +Version: 5.3.0 Release: 0 Summary: Python library for the ACME protocol License: Apache-2.0 @@ -31,7 +31,7 @@ BuildRequires: %{python_module pyOpenSSL >= 25.0.0} BuildRequires: %{python_module pyRFC3339} BuildRequires: %{python_module pytest} -BuildRequires: %{python_module requests >= 2.20.0} +BuildRequires: %{python_module requests >= 2.25.1} BuildRequires: %{python_module setuptools} BuildRequires: %{python_module wheel} BuildRequires: fdupes @@ -40,7 +40,7 @@ Requires: python-josepy >= 2.0.0 Requires: python-pyOpenSSL >= 25.0.0 Requires: python-pyRFC3339 -Requires: python-requests >= 2.20.0 +Requires: python-requests >= 2.25.1 BuildArch: noarch %if %{?suse_version} < 1500 BuildRequires: %{python_module devel} ++++++ acme-5.2.2.tar.gz -> acme-5.3.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-5.2.2/PKG-INFO new/acme-5.3.0/PKG-INFO --- old/acme-5.2.2/PKG-INFO 2025-12-10 18:08:12.141301200 +0100 +++ new/acme-5.3.0/PKG-INFO 2026-02-03 18:51:45.522757800 +0100 @@ -1,8 +1,8 @@ Metadata-Version: 2.4 Name: acme -Version: 5.2.2 +Version: 5.3.0 Summary: ACME protocol implementation in Python -Author-email: Certbot Project <[email protected]> +Author: Certbot Project License-Expression: Apache-2.0 Project-URL: Homepage, https://github.com/certbot/certbot Classifier: Development Status :: 5 - Production/Stable diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-5.2.2/pyproject.toml new/acme-5.3.0/pyproject.toml --- old/acme-5.2.2/pyproject.toml 2025-12-10 18:08:09.000000000 +0100 +++ new/acme-5.3.0/pyproject.toml 2026-02-03 18:51:42.000000000 +0100 @@ -10,7 +10,7 @@ license = "Apache-2.0" requires-python = ">=3.10" authors = [ - { name = "Certbot Project", email = "[email protected]" }, + { name = "Certbot Project" }, ] classifiers = [ "Development Status :: 5 - Production/Stable", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-5.2.2/setup.py new/acme-5.3.0/setup.py --- old/acme-5.2.2/setup.py 2025-12-10 18:08:09.000000000 +0100 +++ new/acme-5.3.0/setup.py 2026-02-03 18:51:43.000000000 +0100 @@ -1,6 +1,6 @@ from setuptools import setup -version = '5.2.2' +version = '5.3.0' setup( version=version, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-5.2.2/src/acme/_internal/tests/challenges_test.py new/acme-5.3.0/src/acme/_internal/tests/challenges_test.py --- old/acme-5.2.2/src/acme/_internal/tests/challenges_test.py 2025-12-10 18:08:09.000000000 +0100 +++ new/acme-5.3.0/src/acme/_internal/tests/challenges_test.py 2026-02-03 18:51:42.000000000 +0100 @@ -1,5 +1,6 @@ """Tests for acme.challenges.""" import sys +from typing import TYPE_CHECKING import unittest from unittest import mock import urllib.parse as urllib_parse @@ -244,6 +245,12 @@ assert 'http://example.com/.well-known/acme-challenge/' \ 'evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA' == \ self.msg.uri('example.com') + assert 'http://1.2.3.4/.well-known/acme-challenge/' \ + 'evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA' == \ + self.msg.uri('1.2.3.4') + assert 'http://[::1]/.well-known/acme-challenge/' \ + 'evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA' == \ + self.msg.uri('::1') def test_to_partial_json(self): assert self.jmsg == self.msg.to_partial_json() @@ -261,71 +268,82 @@ assert not self.msg.update(token=b'..').good_token -class DNSTest(unittest.TestCase): +class TestDNS: - def setUp(self): + if TYPE_CHECKING: from acme.challenges import DNS - self.msg = DNS(token=jose.b64decode( - b'evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA')) - self.jmsg = { + + @pytest.fixture + def jmsg(self) -> dict: + jmsg = { 'type': 'dns', 'token': 'evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA', } + return jmsg - def test_to_partial_json(self): - assert self.jmsg == self.msg.to_partial_json() + @pytest.fixture + def msg(self) -> 'DNS': + from acme.challenges import DNS + msg = DNS(token=jose.b64decode( + b'evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA')) + return msg - def test_from_json(self): + def test_to_partial_json(self, msg: 'DNS', jmsg: dict): + assert jmsg == msg.to_partial_json() + + def test_from_json(self, msg: 'DNS', jmsg: dict): from acme.challenges import DNS - assert self.msg == DNS.from_json(self.jmsg) + assert msg == DNS.from_json(jmsg) - def test_from_json_hashable(self): + def test_from_json_hashable(self, jmsg: dict): from acme.challenges import DNS - hash(DNS.from_json(self.jmsg)) + hash(DNS.from_json(jmsg)) - def test_gen_check_validation(self): - ec_key_secp384r1 = JWKEC(key=test_util.load_ecdsa_private_key('ec_secp384r1_key.pem')) - for key, alg in [(KEY, jose.RS256), (ec_key_secp384r1, jose.ES384)]: - with self.subTest(key=key, alg=alg): - assert self.msg.check_validation( - self.msg.gen_validation(key, alg=alg), key.public_key()) + # Using fixtures in parametrize is an open issue + # https://github.com/pytest-dev/pytest/issues/349 + @pytest.mark.parametrize("key, alg", [ + (KEY, jose.RS256), + (JWKEC(key=test_util.load_ecdsa_private_key('ec_secp384r1_key.pem')), jose.ES384)]) + def test_gen_check_validation(self, key, alg, msg: 'DNS'): + assert msg.check_validation( + msg.gen_validation(key, alg=alg), key.public_key()) - def test_gen_check_validation_wrong_key(self): + def test_gen_check_validation_wrong_key(self, msg: 'DNS'): key2 = jose.JWKRSA.load(test_util.load_vector('rsa1024_key.pem')) - assert not self.msg.check_validation( - self.msg.gen_validation(KEY), key2.public_key()) + assert not msg.check_validation( + msg.gen_validation(KEY), key2.public_key()) - def test_check_validation_wrong_payload(self): + def test_check_validation_wrong_payload(self, msg: 'DNS'): validations = tuple( jose.JWS.sign(payload=payload, alg=jose.RS256, key=KEY) for payload in (b'', b'{}') ) for validation in validations: - assert not self.msg.check_validation( + assert not msg.check_validation( validation, KEY.public_key()) - def test_check_validation_wrong_fields(self): + def test_check_validation_wrong_fields(self, msg: 'DNS'): bad_validation = jose.JWS.sign( - payload=self.msg.update( + payload=msg.update( token=b'x' * 20).json_dumps().encode('utf-8'), alg=jose.RS256, key=KEY) - assert not self.msg.check_validation(bad_validation, KEY.public_key()) + assert not msg.check_validation(bad_validation, KEY.public_key()) - def test_gen_response(self): + def test_gen_response(self, msg: 'DNS'): with mock.patch('acme.challenges.DNS.gen_validation') as mock_gen: mock_gen.return_value = mock.sentinel.validation - response = self.msg.gen_response(KEY) + response = msg.gen_response(KEY) from acme.challenges import DNSResponse assert isinstance(response, DNSResponse) assert response.validation == mock.sentinel.validation - def test_validation_domain_name(self): - assert '_acme-challenge.le.wtf' == self.msg.validation_domain_name('le.wtf') + def test_validation_domain_name(self, msg: 'DNS'): + assert '_acme-challenge.le.wtf' == msg.validation_domain_name('le.wtf') - def test_validation_domain_name_ecdsa(self): + def test_validation_domain_name_ecdsa(self, msg: 'DNS'): ec_key_secp384r1 = JWKEC(key=test_util.load_ecdsa_private_key('ec_secp384r1_key.pem')) - assert self.msg.check_validation( - self.msg.gen_validation(ec_key_secp384r1, alg=jose.ES384), + assert msg.check_validation( + msg.gen_validation(ec_key_secp384r1, alg=jose.ES384), ec_key_secp384r1.public_key()) is True diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-5.2.2/src/acme/_internal/tests/crypto_util_test.py new/acme-5.3.0/src/acme/_internal/tests/crypto_util_test.py --- old/acme-5.2.2/src/acme/_internal/tests/crypto_util_test.py 2025-12-10 18:08:09.000000000 +0100 +++ new/acme-5.3.0/src/acme/_internal/tests/crypto_util_test.py 2026-02-03 18:51:42.000000000 +0100 @@ -16,9 +16,10 @@ class FormatTest(unittest.TestCase): def test_to_cryptography_encoding(self): - from acme.crypto_util import Format - assert Format.DER.to_cryptography_encoding() == serialization.Encoding.DER - assert Format.PEM.to_cryptography_encoding() == serialization.Encoding.PEM + with pytest.warns(DeprecationWarning, match='Format is deprecated'): + from acme.crypto_util import Format + assert Format.DER.to_cryptography_encoding() == serialization.Encoding.DER + assert Format.PEM.to_cryptography_encoding() == serialization.Encoding.PEM class MiscTests(unittest.TestCase): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-5.2.2/src/acme/challenges.py new/acme-5.3.0/src/acme/challenges.py --- old/acme-5.2.2/src/acme/challenges.py 2025-12-10 18:08:09.000000000 +0100 +++ new/acme-5.3.0/src/acme/challenges.py 2026-02-03 18:51:42.000000000 +0100 @@ -2,6 +2,7 @@ import abc import functools import hashlib +import ipaddress import logging from typing import Any from typing import cast @@ -365,17 +366,24 @@ """ return '/' + self.URI_ROOT_PATH + '/' + self.encode('token') - def uri(self, domain: str) -> str: + def uri(self, identifier: str) -> str: """Create an URI to the provisioned resource. Forms an URI to the HTTPS server provisioned resource (containing :attr:`~SimpleHTTP.token`). - :param str domain: Domain name being verified. + :param str identifier: Domain name or IP address being verified. :rtype: str """ - return "http://" + domain + self.path + try: + # https://datatracker.ietf.org/doc/html/rfc2732#section-2 + # IPv6 addresses in URLs should be enclosed in brackets. + ipaddress.IPv6Address(identifier) + identifier = "[" + identifier + "]" + except ipaddress.AddressValueError: + pass + return "http://" + identifier + self.path def validation(self, account_key: jose.JWK, **unused_kwargs: Any) -> str: """Generate validation. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-5.2.2/src/acme/crypto_util.py new/acme-5.3.0/src/acme/crypto_util.py --- old/acme-5.2.2/src/acme/crypto_util.py 2025-12-10 18:08:09.000000000 +0100 +++ new/acme-5.3.0/src/acme/crypto_util.py 2026-02-03 18:51:42.000000000 +0100 @@ -3,11 +3,14 @@ from datetime import datetime, timedelta, timezone import ipaddress import logging +from types import ModuleType import typing +from typing import Any from typing import Literal from typing import Optional from typing import Union import warnings +import sys from cryptography import x509 from cryptography.hazmat.primitives import hashes, serialization @@ -18,8 +21,38 @@ logger = logging.getLogger(__name__) +# https://github.com/pyca/cryptography/blob/1eab7a67dcc34b568e3c0df64e6222a2ac74b1ee/src/cryptography/utils.py#L66-L113 +class _ClientDeprecationModule(ModuleType): + """ + Internal class delegating to a module, and displaying warnings when attributes + related to deprecated attributes in the acme.client module. + """ + def __init__(self, module: ModuleType) -> None: + super().__init__(module.__name__) + self.__dict__['_module'] = module + + def __getattr__(self, attr: str) -> Any: + if attr == 'Format': + warnings.warn("acme.crypto_util.Format is deprecated and will be removed in " + "the next major release.", DeprecationWarning) + return getattr(self._module, attr) + + def __setattr__(self, attr: str, value: Any) -> None: # pragma: no cover + setattr(self._module, attr, value) + + def __delattr__(self, attr: str) -> None: # pragma: no cover + delattr(self._module, attr) + + def __dir__(self) -> list[str]: # pragma: no cover + return ['_module'] + dir(self._module) + + +# Patching ourselves to warn about deprecation and planned removal of some elements in the module. +sys.modules[__name__] = _ClientDeprecationModule(sys.modules[__name__]) + + class Format(enum.IntEnum): - """File format to be used when parsing or serializing X.509 structures. + """File format to be used when parsing or serializing X.509 structures. Deprecated. Backwards compatible with the `FILETYPE_ASN1` and `FILETYPE_PEM` constants from pyOpenSSL. @@ -36,7 +69,7 @@ return Encoding.PEM -# Even *more* annoyingly, due to a mypy bug, we can't use Union[] types in +# Annoyingly, due to a mypy bug, we can't use Union[] types in # isinstance expressions without causing false mypy errors. So we have to # recreate the type collection as a tuple here. And no, typing.get_args doesn't # work due to another mypy bug. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-5.2.2/src/acme.egg-info/PKG-INFO new/acme-5.3.0/src/acme.egg-info/PKG-INFO --- old/acme-5.2.2/src/acme.egg-info/PKG-INFO 2025-12-10 18:08:12.000000000 +0100 +++ new/acme-5.3.0/src/acme.egg-info/PKG-INFO 2026-02-03 18:51:45.000000000 +0100 @@ -1,8 +1,8 @@ Metadata-Version: 2.4 Name: acme -Version: 5.2.2 +Version: 5.3.0 Summary: ACME protocol implementation in Python -Author-email: Certbot Project <[email protected]> +Author: Certbot Project License-Expression: Apache-2.0 Project-URL: Homepage, https://github.com/certbot/certbot Classifier: Development Status :: 5 - Production/Stable
