Hello community, here is the log from the commit of package python-acme for openSUSE:Factory checked in at 2020-10-07 14:19:03 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-acme (Old) and /work/SRC/openSUSE:Factory/.python-acme.new.4249 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-acme" Wed Oct 7 14:19:03 2020 rev:47 rq:839987 version:1.9.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-acme/python-acme.changes 2020-08-21 19:13:00.256670863 +0200 +++ /work/SRC/openSUSE:Factory/.python-acme.new.4249/python-acme.changes 2020-10-07 14:19:32.825536296 +0200 @@ -1,0 +2,14 @@ +Wed Oct 7 08:05:43 UTC 2020 - Marketa Calabkova <[email protected]> + +- update to version 1.9.0 + * sync with the main certbot package + +------------------------------------------------------------------- +Mon Sep 28 13:48:23 UTC 2020 - Hans-Peter Jansen <[email protected]> + +- update to version 1.8.0 + * Support for Python 3.5 has been removed. + * The acme library can now tell the ACME server to clear contact information by passing an empty + tuple to the contact field of a Registration message. + +------------------------------------------------------------------- Old: ---- acme-1.7.0.tar.gz acme-1.7.0.tar.gz.asc New: ---- acme-1.9.0.tar.gz acme-1.9.0.tar.gz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-acme.spec ++++++ --- /var/tmp/diff_new_pack.NWxrDe/_old 2020-10-07 14:19:33.413536763 +0200 +++ /var/tmp/diff_new_pack.NWxrDe/_new 2020-10-07 14:19:33.417536766 +0200 @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define libname acme Name: python-%{libname} -Version: 1.7.0 +Version: 1.9.0 Release: 0 Summary: Python library for the ACME protocol License: Apache-2.0 ++++++ acme-1.7.0.tar.gz -> acme-1.9.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-1.7.0/PKG-INFO new/acme-1.9.0/PKG-INFO --- old/acme-1.7.0/PKG-INFO 2020-08-04 20:20:18.842036200 +0200 +++ new/acme-1.9.0/PKG-INFO 2020-10-06 20:39:54.684130200 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: acme -Version: 1.7.0 +Version: 1.9.0 Summary: ACME protocol implementation in Python Home-page: https://github.com/letsencrypt/letsencrypt Author: Certbot Project @@ -15,12 +15,11 @@ Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Security -Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.* Provides-Extra: dev Provides-Extra: docs diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-1.7.0/acme/__init__.py new/acme-1.9.0/acme/__init__.py --- old/acme-1.7.0/acme/__init__.py 2020-08-04 20:20:15.000000000 +0200 +++ new/acme-1.9.0/acme/__init__.py 2020-10-06 20:39:49.000000000 +0200 @@ -20,11 +20,3 @@ # preserved (acme.jose.* is josepy.*) if mod == 'josepy' or mod.startswith('josepy.'): sys.modules['acme.' + mod.replace('josepy', 'jose', 1)] = sys.modules[mod] - - -if sys.version_info[:2] == (3, 5): - warnings.warn( - "Python 3.5 support will be dropped in the next release of " - "acme. Please upgrade your Python version.", - PendingDeprecationWarning, - ) # pragma: no cover diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-1.7.0/acme/client.py new/acme-1.9.0/acme/client.py --- old/acme-1.7.0/acme/client.py 2020-08-04 20:20:15.000000000 +0200 +++ new/acme-1.9.0/acme/client.py 2020-10-06 20:39:49.000000000 +0200 @@ -448,7 +448,7 @@ heapq.heapify(waiting) # mapping between original Authorization Resource and the most # recently updated one - updated = dict((authzr, authzr) for authzr in authzrs) + updated = {authzr: authzr for authzr in authzrs} while waiting: # find the smallest Retry-After, and sleep if necessary @@ -801,7 +801,7 @@ """ # Can't use response.links directly because it drops multiple links # of the same relation type, which is possible in RFC8555 responses. - if not 'Link' in response.headers: + if 'Link' not in response.headers: return [] links = parse_header_links(response.headers['Link']) return [l['url'] for l in links diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-1.7.0/acme/messages.py new/acme-1.9.0/acme/messages.py --- old/acme-1.7.0/acme/messages.py 2020-08-04 20:20:15.000000000 +0200 +++ new/acme-1.9.0/acme/messages.py 2020-10-06 20:39:49.000000000 +0200 @@ -206,7 +206,7 @@ external_account_required = jose.Field('externalAccountRequired', omitempty=True) def __init__(self, **kwargs): - kwargs = dict((self._internal_name(k), v) for k, v in kwargs.items()) + kwargs = {self._internal_name(k): v for k, v in kwargs.items()} super(Directory.Meta, self).__init__(**kwargs) @property @@ -315,6 +315,9 @@ # on new-reg key server ignores 'key' and populates it based on # JWS.signature.combined.jwk key = jose.Field('key', omitempty=True, decoder=jose.JWK.from_json) + # Contact field implements special behavior to allow messages that clear existing + # contacts while not expecting the `contact` field when loading from json. + # This is implemented in the constructor and *_json methods. contact = jose.Field('contact', omitempty=True, default=()) agreement = jose.Field('agreement', omitempty=True) status = jose.Field('status', omitempty=True) @@ -327,24 +330,73 @@ @classmethod def from_data(cls, phone=None, email=None, external_account_binding=None, **kwargs): - """Create registration resource from contact details.""" + """ + Create registration resource from contact details. + + The `contact` keyword being passed to a Registration object is meaningful, so + this function represents empty iterables in its kwargs by passing on an empty + `tuple`. + """ + + # Note if `contact` was in kwargs. + contact_provided = 'contact' in kwargs + + # Pop `contact` from kwargs and add formatted email or phone numbers details = list(kwargs.pop('contact', ())) if phone is not None: details.append(cls.phone_prefix + phone) if email is not None: details.extend([cls.email_prefix + mail for mail in email.split(',')]) - kwargs['contact'] = tuple(details) + + # Insert formatted contact information back into kwargs + # or insert an empty tuple if `contact` provided. + if details or contact_provided: + kwargs['contact'] = tuple(details) if external_account_binding: kwargs['external_account_binding'] = external_account_binding return cls(**kwargs) + def __init__(self, **kwargs): + """Note if the user provides a value for the `contact` member.""" + if 'contact' in kwargs: + # Avoid the __setattr__ used by jose.TypedJSONObjectWithFields + object.__setattr__(self, '_add_contact', True) + super(Registration, self).__init__(**kwargs) + def _filter_contact(self, prefix): return tuple( detail[len(prefix):] for detail in self.contact # pylint: disable=not-an-iterable if detail.startswith(prefix)) + def _add_contact_if_appropriate(self, jobj): + """ + The `contact` member of Registration objects should not be required when + de-serializing (as it would be if the Fields' `omitempty` flag were `False`), but + it should be included in serializations if it was provided. + + :param jobj: Dictionary containing this Registrations' data + :type jobj: dict + + :returns: Dictionary containing Registrations data to transmit to the server + :rtype: dict + """ + if getattr(self, '_add_contact', False): + jobj['contact'] = self.encode('contact') + + return jobj + + def to_partial_json(self): + """Modify josepy.JSONDeserializable.to_partial_json()""" + jobj = super(Registration, self).to_partial_json() + return self._add_contact_if_appropriate(jobj) + + def fields_to_partial_json(self): + """Modify josepy.JSONObjectWithFields.fields_to_partial_json()""" + jobj = super(Registration, self).fields_to_partial_json() + return self._add_contact_if_appropriate(jobj) + @property def phones(self): """All phones found in the ``contact`` field.""" @@ -413,7 +465,7 @@ omitempty=True, default=None) def __init__(self, **kwargs): - kwargs = dict((self._internal_name(k), v) for k, v in kwargs.items()) + kwargs = {self._internal_name(k): v for k, v in kwargs.items()} super(ChallengeBody, self).__init__(**kwargs) def encode(self, name): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-1.7.0/acme/util.py new/acme-1.9.0/acme/util.py --- old/acme-1.7.0/acme/util.py 2020-08-04 20:20:15.000000000 +0200 +++ new/acme-1.9.0/acme/util.py 2020-10-06 20:39:49.000000000 +0200 @@ -4,4 +4,4 @@ def map_keys(dikt, func): """Map dictionary keys.""" - return dict((func(key), value) for key, value in six.iteritems(dikt)) + return {func(key): value for key, value in six.iteritems(dikt)} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-1.7.0/acme.egg-info/PKG-INFO new/acme-1.9.0/acme.egg-info/PKG-INFO --- old/acme-1.7.0/acme.egg-info/PKG-INFO 2020-08-04 20:20:18.000000000 +0200 +++ new/acme-1.9.0/acme.egg-info/PKG-INFO 2020-10-06 20:39:54.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: acme -Version: 1.7.0 +Version: 1.9.0 Summary: ACME protocol implementation in Python Home-page: https://github.com/letsencrypt/letsencrypt Author: Certbot Project @@ -15,12 +15,11 @@ Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Security -Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.* Provides-Extra: dev Provides-Extra: docs diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-1.7.0/docs/Makefile new/acme-1.9.0/docs/Makefile --- old/acme-1.7.0/docs/Makefile 2020-08-04 20:20:15.000000000 +0200 +++ new/acme-1.9.0/docs/Makefile 2020-10-06 20:39:49.000000000 +0200 @@ -9,7 +9,7 @@ # User-friendly check for sphinx-build ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from https://www.sphinx-doc.org/) endif # Internal variables. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-1.7.0/docs/conf.py new/acme-1.9.0/docs/conf.py --- old/acme-1.7.0/docs/conf.py 2020-08-04 20:20:15.000000000 +0200 +++ new/acme-1.9.0/docs/conf.py 2020-10-06 20:39:49.000000000 +0200 @@ -120,7 +120,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -# http://docs.readthedocs.org/en/latest/theme.html#how-do-i-use-this-locally-and-on-read-the-docs +# https://docs.readthedocs.io/en/stable/faq.html#i-want-to-use-the-read-the-docs-theme-locally # on_rtd is whether we are on readthedocs.org on_rtd = os.environ.get('READTHEDOCS', None) == 'True' if not on_rtd: # only import and set the theme if we're building docs locally diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-1.7.0/docs/make.bat new/acme-1.9.0/docs/make.bat --- old/acme-1.7.0/docs/make.bat 2020-08-04 20:20:15.000000000 +0200 +++ new/acme-1.9.0/docs/make.bat 2020-10-06 20:39:49.000000000 +0200 @@ -65,7 +65,7 @@ echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ + echo.https://www.sphinx-doc.org/ exit /b 1 ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-1.7.0/setup.py new/acme-1.9.0/setup.py --- old/acme-1.7.0/setup.py 2020-08-04 20:20:16.000000000 +0200 +++ new/acme-1.9.0/setup.py 2020-10-06 20:39:50.000000000 +0200 @@ -4,9 +4,8 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -from setuptools.command.test import test as TestCommand -version = '1.7.0' +version = '1.9.0' # Please update tox.ini when modifying dependency version requirements install_requires = [ @@ -47,22 +46,6 @@ 'sphinx_rtd_theme', ] - -class PyTest(TestCommand): - user_options = [] - - def initialize_options(self): - TestCommand.initialize_options(self) - self.pytest_args = '' - - def run_tests(self): - import shlex - # import here, cause outside the eggs aren't loaded - import pytest - errno = pytest.main(shlex.split(self.pytest_args)) - sys.exit(errno) - - setup( name='acme', version=version, @@ -71,7 +54,7 @@ author="Certbot Project", author_email='[email protected]', license='Apache License 2.0', - python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*', + python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*', classifiers=[ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', @@ -80,7 +63,6 @@ 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', @@ -95,7 +77,4 @@ 'dev': dev_extras, 'docs': docs_extras, }, - test_suite='acme', - tests_require=["pytest"], - cmdclass={"test": PyTest}, ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-1.7.0/tests/client_test.py new/acme-1.9.0/tests/client_test.py --- old/acme-1.7.0/tests/client_test.py 2020-08-04 20:20:15.000000000 +0200 +++ new/acme-1.9.0/tests/client_test.py 2020-10-06 20:39:49.000000000 +0200 @@ -853,7 +853,7 @@ self.response.json.return_value = updated_order.to_json() self.response.text = CERT_SAN_PEM self.response.headers['Link'] ='<https://example.com/acme/cert/1>;rel="alternate", ' + \ - '<https://exaple.com/dir>;rel="index", ' + \ + '<https://example.com/dir>;rel="index", ' + \ '<https://example.com/acme/cert/2>;title="foo";rel="alternate"' deadline = datetime.datetime(9999, 9, 9) @@ -1342,7 +1342,7 @@ # test should fail if the default adapter type is changed by requests net = ClientNetwork(key=None, alg=None) session = requests.Session() - for scheme in session.adapters.keys(): + for scheme in session.adapters: client_network_adapter = net.session.adapters.get(scheme) default_adapter = session.adapters.get(scheme) self.assertEqual(client_network_adapter.__class__, default_adapter.__class__) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-1.7.0/tests/messages_test.py new/acme-1.9.0/tests/messages_test.py --- old/acme-1.7.0/tests/messages_test.py 2020-08-04 20:20:15.000000000 +0200 +++ new/acme-1.9.0/tests/messages_test.py 2020-10-06 20:39:49.000000000 +0200 @@ -254,6 +254,19 @@ from acme.messages import Registration hash(Registration.from_json(self.jobj_from)) + def test_default_not_transmitted(self): + from acme.messages import NewRegistration + empty_new_reg = NewRegistration() + new_reg_with_contact = NewRegistration(contact=()) + + self.assertEqual(empty_new_reg.contact, ()) + self.assertEqual(new_reg_with_contact.contact, ()) + + self.assertTrue('contact' not in empty_new_reg.to_partial_json()) + self.assertTrue('contact' not in empty_new_reg.fields_to_partial_json()) + self.assertTrue('contact' in new_reg_with_contact.to_partial_json()) + self.assertTrue('contact' in new_reg_with_contact.fields_to_partial_json()) + class UpdateRegistrationTest(unittest.TestCase): """Tests for acme.messages.UpdateRegistration."""
