Hello community, here is the log from the commit of package python-packaging for openSUSE:Factory checked in at 2018-03-26 12:32:04 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-packaging (Old) and /work/SRC/openSUSE:Factory/.python-packaging.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-packaging" Mon Mar 26 12:32:04 2018 rev:9 rq:590422 version:17.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-packaging/python-packaging.changes 2017-05-17 10:46:13.039506671 +0200 +++ /work/SRC/openSUSE:Factory/.python-packaging.new/python-packaging.changes 2018-03-26 12:32:11.396155035 +0200 @@ -1,0 +2,12 @@ +Thu Mar 22 20:37:57 UTC 2018 - [email protected] + +- Update to version 17.1 + * Fix utils.canonicalize_version when supplying non PEP 440 versions. +- Update to version 17.0 + * Drop support for python 2.6, 3.2, and 3.3. + * Define minimal pyparsing version to 2.0.2 (#91). + * Add epoch, release, pre, dev, and post attributes to Version and LegacyVersion (#34). + * Add Version().is_devrelease and LegacyVersion().is_devrelease to make it easy to determine if a release is a development release. + * Add utils.canonicalize_version to canonicalize version strings or Version instances (#121). + +------------------------------------------------------------------- Old: ---- packaging-16.8.tar.gz New: ---- packaging-17.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-packaging.spec ++++++ --- /var/tmp/diff_new_pack.sFJX7G/_old 2018-03-26 12:32:13.700072322 +0200 +++ /var/tmp/diff_new_pack.sFJX7G/_new 2018-03-26 12:32:13.704072178 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-packaging # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -20,7 +20,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-packaging -Version: 16.8 +Version: 17.1 Release: 0 Summary: Core utilities for Python packages License: Apache-2.0 @@ -28,7 +28,7 @@ Url: https://github.com/pypa/packaging Source: https://pypi.io/packages/source/p/packaging/packaging-%{version}.tar.gz BuildRequires: %{python_module base} -BuildRequires: %{python_module pyparsing} +BuildRequires: %{python_module pyparsing >= 2.0.2} BuildRequires: %{python_module six} BuildRequires: python-rpm-macros # do not add setuptools dependency, this is now a dependency @@ -43,9 +43,8 @@ # File "/usr/lib/python2.7/site-packages/packaging/requirements.py", line 59, in <module> # MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker") # TypeError: __call__() takes exactly 2 arguments (1 given) -Requires: python-pyparsing >= 2.2.0 +Requires: python-pyparsing >= 2.0.2 Requires: python-six -BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildArch: noarch %python_subpackages ++++++ packaging-16.8.tar.gz -> packaging-17.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/packaging-16.8/CHANGELOG.rst new/packaging-17.1/CHANGELOG.rst --- old/packaging-16.8/CHANGELOG.rst 2016-10-29 17:54:54.000000000 +0200 +++ new/packaging-17.1/CHANGELOG.rst 2018-02-28 18:51:13.000000000 +0100 @@ -1,6 +1,29 @@ Changelog --------- +17.1 - 2017-02-28 +~~~~~~~~~~~~~~~~~ + +* Fix ``utils.canonicalize_version`` when supplying non PEP 440 versions. + + +17.0 - 2017-02-28 +~~~~~~~~~~~~~~~~~ + +* Drop support for python 2.6, 3.2, and 3.3. + +* Define minimal pyparsing version to 2.0.2 (:issue:`91`). + +* Add ``epoch``, ``release``, ``pre``, ``dev``, and ``post`` attributes to + ``Version`` and ``LegacyVersion`` (:issue:`34`). + +* Add ``Version().is_devrelease`` and ``LegacyVersion().is_devrelease`` to + make it easy to determine if a release is a development release. + +* Add ``utils.canonicalize_version`` to canonicalize version strings or + ``Version`` instances (:issue:`121`). + + 16.8 - 2016-10-29 ~~~~~~~~~~~~~~~~~ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/packaging-16.8/PKG-INFO new/packaging-17.1/PKG-INFO --- old/packaging-16.8/PKG-INFO 2016-10-29 17:55:00.000000000 +0200 +++ new/packaging-17.1/PKG-INFO 2018-02-28 18:51:44.000000000 +0100 @@ -1,6 +1,6 @@ -Metadata-Version: 1.1 +Metadata-Version: 1.2 Name: packaging -Version: 16.8 +Version: 17.1 Summary: Core utilities for Python packages Home-page: https://github.com/pypa/packaging Author: Donald Stufft and individual contributors @@ -41,6 +41,29 @@ Changelog --------- + 17.1 - 2017-02-28 + ~~~~~~~~~~~~~~~~~ + + * Fix ``utils.canonicalize_version`` when supplying non PEP 440 versions. + + + 17.0 - 2017-02-28 + ~~~~~~~~~~~~~~~~~ + + * Drop support for python 2.6, 3.2, and 3.3. + + * Define minimal pyparsing version to 2.0.2 (`#91 <https://github.com/pypa/packaging/issues/91>`__). + + * Add ``epoch``, ``release``, ``pre``, ``dev``, and ``post`` attributes to + ``Version`` and ``LegacyVersion`` (`#34 <https://github.com/pypa/packaging/issues/34>`__). + + * Add ``Version().is_devrelease`` and ``LegacyVersion().is_devrelease`` to + make it easy to determine if a release is a development release. + + * Add ``utils.canonicalize_version`` to canonicalize version strings or + ``Version`` instances (`#121 <https://github.com/pypa/packaging/issues/121>`__). + + 16.8 - 2016-10-29 ~~~~~~~~~~~~~~~~~ @@ -204,14 +227,15 @@ * Initial release. Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: Apache Software License Classifier: License :: OSI Approved :: BSD License Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.2 -Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/packaging-16.8/docs/conf.py new/packaging-17.1/docs/conf.py --- old/packaging-16.8/docs/conf.py 2016-10-29 17:54:54.000000000 +0200 +++ new/packaging-17.1/docs/conf.py 2018-02-28 14:57:14.000000000 +0100 @@ -135,7 +135,7 @@ # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { - "http://docs.python.org/": None, + "https://docs.python.org/": None, } epub_theme = "epub" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/packaging-16.8/docs/development/getting-started.rst new/packaging-17.1/docs/development/getting-started.rst --- old/packaging-16.8/docs/development/getting-started.rst 2016-10-29 17:54:54.000000000 +0200 +++ new/packaging-17.1/docs/development/getting-started.rst 2018-02-28 14:57:14.000000000 +0100 @@ -37,11 +37,12 @@ $ tox ... - ERROR: py26: InterpreterNotFound: python2.6 py27: commands succeeded ERROR: pypy: InterpreterNotFound: pypy - ERROR: py32: InterpreterNotFound: python3.2 - py33: commands succeeded + ERROR: py34: InterpreterNotFound: python3.4 + ERROR: py35: InterpreterNotFound: python3.5 + py36: commands succeeded + ERROR: py37: InterpreterNotFound: python3.7 docs: commands succeeded pep8: commands succeeded diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/packaging-16.8/docs/development/submitting-patches.rst new/packaging-17.1/docs/development/submitting-patches.rst --- old/packaging-16.8/docs/development/submitting-patches.rst 2016-10-29 17:54:54.000000000 +0200 +++ new/packaging-17.1/docs/development/submitting-patches.rst 2018-02-28 14:57:14.000000000 +0100 @@ -75,6 +75,6 @@ * Use Sphinx parameter/attribute documentation `syntax`_. -.. _`Write comments as complete sentences.`: http://nedbatchelder.com/blog/201401/comments_should_be_sentences.html +.. _`Write comments as complete sentences.`: https://nedbatchelder.com/blog/201401/comments_should_be_sentences.html .. _`syntax`: http://sphinx-doc.org/domains.html#info-field-lists .. _`Studies have shown`: http://www.ibm.com/developerworks/rational/library/11-proven-practices-for-peer-review/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/packaging-16.8/docs/requirements.rst new/packaging-17.1/docs/requirements.rst --- old/packaging-16.8/docs/requirements.rst 2016-10-29 17:54:54.000000000 +0200 +++ new/packaging-17.1/docs/requirements.rst 2018-02-28 14:57:14.000000000 +0100 @@ -71,7 +71,7 @@ .. attribute:: extras - A list of extras that the requirement specifies. + A set of extras that the requirement specifies. .. attribute:: specifier diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/packaging-16.8/docs/utils.rst new/packaging-17.1/docs/utils.rst --- old/packaging-16.8/docs/utils.rst 2016-10-29 17:54:54.000000000 +0200 +++ new/packaging-17.1/docs/utils.rst 2018-02-28 14:57:14.000000000 +0100 @@ -26,3 +26,16 @@ 'oslo-concurrency' >>> canonicalize_name("requests") 'requests' + +.. function:: canonicalize_version(version) + + This function takes a string representing a package version (or a + ``Version`` instance), and returns the normalized form of it. + + :param str version: The version to normalize. + + .. doctest:: + + >>> from packaging.utils import canonicalize_version + >>> canonicalize_version('1.4.0.0.0') + '1.4' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/packaging-16.8/docs/version.rst new/packaging-17.1/docs/version.rst --- old/packaging-16.8/docs/version.rst 2016-10-29 17:54:54.000000000 +0200 +++ new/packaging-17.1/docs/version.rst 2018-02-28 14:57:14.000000000 +0100 @@ -21,6 +21,12 @@ <Version('1.0')> >>> v1 < v2 True + >>> v1.epoch + 0 + >>> v1.release + (1, 0) + >>> v1.pre + ('a', 5) >>> v1.is_prerelease True >>> v2.is_prerelease @@ -29,8 +35,11 @@ Traceback (most recent call last): ... InvalidVersion: Invalid version: 'french toast' + >>> Version("1.0").post >>> Version("1.0").is_postrelease False + >>> Version("1.0.post0").post + 0 >>> Version("1.0.post0").is_postrelease True @@ -66,15 +75,50 @@ instance. The base version is the public version of the project without any pre or post release markers. + .. attribute:: epoch + + An integer giving the version epoch of this :class:`Version` instance + + .. attribute:: release + + A tuple of integers giving the components of the release segment of + this :class:`Version` instance; that is, the ``1.2.3`` part of the + version number, including trailing zeroes but not including the epoch + or any prerelease/development/postrelease suffixes + .. attribute:: local A string representing the local version portion of this ``Version()`` if it has one, or ``None`` otherwise. + .. attribute:: pre + + If this :class:`Version` instance represents a prerelease, this + attribute will be a pair of the prerelease phase (the string ``"a"``, + ``"b"``, or ``"rc"``) and the prerelease number (an integer). If this + instance is not a prerelease, the attribute will be `None`. + .. attribute:: is_prerelease A boolean value indicating whether this :class:`Version` instance - represents a prerelease or a final release. + represents a prerelease and/or development release. + + .. attribute:: dev + + If this :class:`Version` instance represents a development release, + this attribute will be the development release number (an integer); + otherwise, it will be `None`. + + .. attribute:: is_devrelease + + A boolean value indicating whether this :class:`Version` instance + represents a development release. + + .. attribute:: post + + If this :class:`Version` instance represents a postrelease, this + attribute will be the postrelease number (an integer); otherwise, it + will be `None`. .. attribute:: is_postrelease @@ -106,18 +150,57 @@ :class:`LegacyVersion` instance. This will always be the entire version string. + .. attribute:: epoch + + This will always be ``-1`` since without `PEP 440`_ we do not have the + concept of version epochs. The value reflects the fact that + :class:`LegacyVersion` instances always compare less than + :class:`Version` instances. + + .. attribute:: release + + This will always be ``None`` since without `PEP 440`_ we do not have + the concept of a release segment or its components. It exists + primarily to allow a :class:`LegacyVersion` to be used as a stand in + for a :class:`Version`. + .. attribute:: local This will always be ``None`` since without `PEP 440`_ we do not have the concept of a local version. It exists primarily to allow a :class:`LegacyVersion` to be used as a stand in for a :class:`Version`. + .. attribute:: pre + + This will always be ``None`` since without `PEP 440`_ we do not have + the concept of a prerelease. It exists primarily to allow a + :class:`LegacyVersion` to be used as a stand in for a :class:`Version`. + .. attribute:: is_prerelease A boolean value indicating whether this :class:`LegacyVersion` - represents a prerelease or a final release. Since without `PEP 440`_ - there is no concept of pre or final releases this will always be - `False` and exists for compatibility with :class:`Version`. + represents a prerelease and/or development release. Since without + `PEP 440`_ there is no concept of pre or dev releases this will + always be `False` and exists for compatibility with :class:`Version`. + + .. attribute:: dev + + This will always be ``None`` since without `PEP 440`_ we do not have + the concept of a development release. It exists primarily to allow a + :class:`LegacyVersion` to be used as a stand in for a :class:`Version`. + + .. attribute:: is_devrelease + + A boolean value indicating whether this :class:`LegacyVersion` + represents a development release. Since without `PEP 440`_ there is + no concept of dev releases this will always be `False` and exists for + compatibility with :class:`Version`. + + .. attribute:: post + + This will always be ``None`` since without `PEP 440`_ we do not have + the concept of a postrelease. It exists primarily to allow a + :class:`LegacyVersion` to be used as a stand in for a :class:`Version`. .. attribute:: is_postrelease diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/packaging-16.8/packaging/__about__.py new/packaging-17.1/packaging/__about__.py --- old/packaging-16.8/packaging/__about__.py 2016-10-29 17:54:54.000000000 +0200 +++ new/packaging-17.1/packaging/__about__.py 2018-02-28 18:51:28.000000000 +0100 @@ -12,7 +12,7 @@ __summary__ = "Core utilities for Python packages" __uri__ = "https://github.com/pypa/packaging" -__version__ = "16.8" +__version__ = "17.1" __author__ = "Donald Stufft and individual contributors" __email__ = "[email protected]" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/packaging-16.8/packaging/_structures.py new/packaging-17.1/packaging/_structures.py --- old/packaging-16.8/packaging/_structures.py 2016-10-29 17:54:54.000000000 +0200 +++ new/packaging-17.1/packaging/_structures.py 2018-02-28 14:57:14.000000000 +0100 @@ -33,6 +33,7 @@ def __neg__(self): return NegativeInfinity + Infinity = Infinity() @@ -65,4 +66,5 @@ def __neg__(self): return Infinity + NegativeInfinity = NegativeInfinity() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/packaging-16.8/packaging/requirements.py new/packaging-17.1/packaging/requirements.py --- old/packaging-16.8/packaging/requirements.py 2016-10-29 17:54:54.000000000 +0200 +++ new/packaging-17.1/packaging/requirements.py 2018-02-28 14:57:14.000000000 +0100 @@ -60,8 +60,8 @@ MARKER_EXPR.setParseAction( lambda s, l, t: Marker(s[t._original_start:t._original_end]) ) -MARKER_SEPERATOR = SEMICOLON -MARKER = MARKER_SEPERATOR + MARKER_EXPR +MARKER_SEPARATOR = SEMICOLON +MARKER = MARKER_SEPARATOR + MARKER_EXPR VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER) URL_AND_MARKER = URL + Optional(MARKER) @@ -70,6 +70,9 @@ NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER) REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd +# pyparsing isn't thread safe during initialization, so we do it eagerly, see +# issue #104 +REQUIREMENT.parseString("x[]") class Requirement(object): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/packaging-16.8/packaging/specifiers.py new/packaging-17.1/packaging/specifiers.py --- old/packaging-16.8/packaging/specifiers.py 2016-10-29 17:54:54.000000000 +0200 +++ new/packaging-17.1/packaging/specifiers.py 2018-02-28 14:57:14.000000000 +0100 @@ -198,7 +198,7 @@ (prereleases or self.prereleases)): found_prereleases.append(version) # Either this is not a prerelease, or we should have been - # accepting prereleases from the begining. + # accepting prereleases from the beginning. else: yielded = True yield version diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/packaging-16.8/packaging/utils.py new/packaging-17.1/packaging/utils.py --- old/packaging-16.8/packaging/utils.py 2016-10-29 17:54:54.000000000 +0200 +++ new/packaging-17.1/packaging/utils.py 2018-02-28 18:49:49.000000000 +0100 @@ -5,6 +5,8 @@ import re +from .version import InvalidVersion, Version + _canonicalize_regex = re.compile(r"[-_.]+") @@ -12,3 +14,50 @@ def canonicalize_name(name): # This is taken from PEP 503. return _canonicalize_regex.sub("-", name).lower() + + +def canonicalize_version(version): + """ + This is very similar to Version.__str__, but has one subtle differences + with the way it handles the release segment. + """ + + try: + version = Version(version) + except InvalidVersion: + # Legacy versions cannot be normalized + return version + + parts = [] + + # Epoch + if version.epoch != 0: + parts.append("{0}!".format(version.epoch)) + + # Release segment + # NB: This strips trailing '.0's to normalize + parts.append( + re.sub( + r'(\.0)+$', + '', + ".".join(str(x) for x in version.release) + ) + ) + + # Pre-release + if version.pre is not None: + parts.append("".join(str(x) for x in version.pre)) + + # Post-release + if version.post is not None: + parts.append(".post{0}".format(version.post)) + + # Development release + if version.dev is not None: + parts.append(".dev{0}".format(version.dev)) + + # Local version segment + if version.local is not None: + parts.append("+{0}".format(version.local)) + + return "".join(parts) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/packaging-16.8/packaging/version.py new/packaging-17.1/packaging/version.py --- old/packaging-16.8/packaging/version.py 2016-10-29 17:54:54.000000000 +0200 +++ new/packaging-17.1/packaging/version.py 2018-02-28 14:57:14.000000000 +0100 @@ -90,6 +90,26 @@ return self._version @property + def epoch(self): + return -1 + + @property + def release(self): + return None + + @property + def pre(self): + return None + + @property + def post(self): + return None + + @property + def dev(self): + return None + + @property def local(self): return None @@ -101,6 +121,10 @@ def is_postrelease(self): return False + @property + def is_devrelease(self): + return False + _legacy_version_component_re = re.compile( r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE, @@ -154,6 +178,7 @@ return epoch, parts + # Deliberately not anchored to the start and end of the string, to make it # easier for 3rd party code to reuse VERSION_PATTERN = r""" @@ -237,33 +262,58 @@ parts = [] # Epoch - if self._version.epoch != 0: - parts.append("{0}!".format(self._version.epoch)) + if self.epoch != 0: + parts.append("{0}!".format(self.epoch)) # Release segment - parts.append(".".join(str(x) for x in self._version.release)) + parts.append(".".join(str(x) for x in self.release)) # Pre-release - if self._version.pre is not None: - parts.append("".join(str(x) for x in self._version.pre)) + if self.pre is not None: + parts.append("".join(str(x) for x in self.pre)) # Post-release - if self._version.post is not None: - parts.append(".post{0}".format(self._version.post[1])) + if self.post is not None: + parts.append(".post{0}".format(self.post)) # Development release - if self._version.dev is not None: - parts.append(".dev{0}".format(self._version.dev[1])) + if self.dev is not None: + parts.append(".dev{0}".format(self.dev)) # Local version segment - if self._version.local is not None: - parts.append( - "+{0}".format(".".join(str(x) for x in self._version.local)) - ) + if self.local is not None: + parts.append("+{0}".format(self.local)) return "".join(parts) @property + def epoch(self): + return self._version.epoch + + @property + def release(self): + return self._version.release + + @property + def pre(self): + return self._version.pre + + @property + def post(self): + return self._version.post[1] if self._version.post else None + + @property + def dev(self): + return self._version.dev[1] if self._version.dev else None + + @property + def local(self): + if self._version.local: + return ".".join(str(x) for x in self._version.local) + else: + return None + + @property def public(self): return str(self).split("+", 1)[0] @@ -272,27 +322,25 @@ parts = [] # Epoch - if self._version.epoch != 0: - parts.append("{0}!".format(self._version.epoch)) + if self.epoch != 0: + parts.append("{0}!".format(self.epoch)) # Release segment - parts.append(".".join(str(x) for x in self._version.release)) + parts.append(".".join(str(x) for x in self.release)) return "".join(parts) @property - def local(self): - version_string = str(self) - if "+" in version_string: - return version_string.split("+", 1)[1] - - @property def is_prerelease(self): - return bool(self._version.dev or self._version.pre) + return self.dev is not None or self.pre is not None @property def is_postrelease(self): - return bool(self._version.post) + return self.post is not None + + @property + def is_devrelease(self): + return self.dev is not None def _parse_letter_version(letter, number): @@ -326,7 +374,7 @@ return letter, int(number) -_local_version_seperators = re.compile(r"[\._-]") +_local_version_separators = re.compile(r"[\._-]") def _parse_local_version(local): @@ -336,7 +384,7 @@ if local is not None: return tuple( part.lower() if not part.isdigit() else int(part) - for part in _local_version_seperators.split(local) + for part in _local_version_separators.split(local) ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/packaging-16.8/packaging.egg-info/PKG-INFO new/packaging-17.1/packaging.egg-info/PKG-INFO --- old/packaging-16.8/packaging.egg-info/PKG-INFO 2016-10-29 17:55:00.000000000 +0200 +++ new/packaging-17.1/packaging.egg-info/PKG-INFO 2018-02-28 18:51:44.000000000 +0100 @@ -1,6 +1,6 @@ -Metadata-Version: 1.1 +Metadata-Version: 1.2 Name: packaging -Version: 16.8 +Version: 17.1 Summary: Core utilities for Python packages Home-page: https://github.com/pypa/packaging Author: Donald Stufft and individual contributors @@ -41,6 +41,29 @@ Changelog --------- + 17.1 - 2017-02-28 + ~~~~~~~~~~~~~~~~~ + + * Fix ``utils.canonicalize_version`` when supplying non PEP 440 versions. + + + 17.0 - 2017-02-28 + ~~~~~~~~~~~~~~~~~ + + * Drop support for python 2.6, 3.2, and 3.3. + + * Define minimal pyparsing version to 2.0.2 (`#91 <https://github.com/pypa/packaging/issues/91>`__). + + * Add ``epoch``, ``release``, ``pre``, ``dev``, and ``post`` attributes to + ``Version`` and ``LegacyVersion`` (`#34 <https://github.com/pypa/packaging/issues/34>`__). + + * Add ``Version().is_devrelease`` and ``LegacyVersion().is_devrelease`` to + make it easy to determine if a release is a development release. + + * Add ``utils.canonicalize_version`` to canonicalize version strings or + ``Version`` instances (`#121 <https://github.com/pypa/packaging/issues/121>`__). + + 16.8 - 2016-10-29 ~~~~~~~~~~~~~~~~~ @@ -204,14 +227,15 @@ * Initial release. Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: Apache Software License Classifier: License :: OSI Approved :: BSD License Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.2 -Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/packaging-16.8/packaging.egg-info/requires.txt new/packaging-17.1/packaging.egg-info/requires.txt --- old/packaging-16.8/packaging.egg-info/requires.txt 2016-10-29 17:55:00.000000000 +0200 +++ new/packaging-17.1/packaging.egg-info/requires.txt 2018-02-28 18:51:44.000000000 +0100 @@ -1,2 +1,2 @@ -pyparsing +pyparsing>=2.0.2 six diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/packaging-16.8/setup.py new/packaging-17.1/setup.py --- old/packaging-16.8/setup.py 2016-10-29 17:54:54.000000000 +0200 +++ new/packaging-17.1/setup.py 2018-02-28 14:57:14.000000000 +0100 @@ -50,9 +50,15 @@ author=about["__author__"], author_email=about["__email__"], - install_requires=["pyparsing", "six"], + python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', + + install_requires=[ + "pyparsing>=2.0.2", # Needed to avoid issue #91 + "six", + ], classifiers=[ + "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", @@ -60,12 +66,11 @@ "Programming Language :: Python", "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.2", - "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", ], packages=[ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/packaging-16.8/tests/test_utils.py new/packaging-17.1/tests/test_utils.py --- old/packaging-16.8/tests/test_utils.py 2016-10-29 17:54:54.000000000 +0200 +++ new/packaging-17.1/tests/test_utils.py 2018-02-28 18:49:49.000000000 +0100 @@ -5,7 +5,7 @@ import pytest -from packaging.utils import canonicalize_name +from packaging.utils import canonicalize_name, canonicalize_version @pytest.mark.parametrize( @@ -25,3 +25,23 @@ ) def test_canonicalize_name(name, expected): assert canonicalize_name(name) == expected + + [email protected]( + ("version", "expected"), + [ + ('1.4.0', '1.4'), + ('1.40.0', '1.40'), + ('1.4.0.0.00.000.0000', '1.4'), + ('1.0', '1'), + ('1.0+abc', '1+abc'), + ('1.0.dev0', '1.dev0'), + ('1.0.post0', '1.post0'), + ('1.0a0', '1a0'), + ('1.0rc0', '1rc0'), + ('100!0.0', '100!0'), + ('1.0.1-test7', '1.0.1-test7'), # LegacyVersion is unchanged + ] +) +def test_canonicalize_version(version, expected): + assert canonicalize_version(version) == expected diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/packaging-16.8/tests/test_version.py new/packaging-17.1/tests/test_version.py --- old/packaging-16.8/tests/test_version.py 2016-10-29 17:54:54.000000000 +0200 +++ new/packaging-17.1/tests/test_version.py 2018-02-28 14:57:14.000000000 +0100 @@ -264,6 +264,7 @@ ("version", "public"), [ ("1.0", "1.0"), + ("1.0.dev0", "1.0.dev0"), ("1.0.dev6", "1.0.dev6"), ("1.0a1", "1.0a1"), ("1.0a1.post5", "1.0a1.post5"), @@ -300,6 +301,7 @@ ("version", "base_version"), [ ("1.0", "1.0"), + ("1.0.dev0", "1.0"), ("1.0.dev6", "1.0"), ("1.0a1", "1.0"), ("1.0a1.post5", "1.0"), @@ -333,9 +335,84 @@ assert Version(version).base_version == base_version @pytest.mark.parametrize( + ("version", "epoch"), + [ + ("1.0", 0), + ("1.0.dev0", 0), + ("1.0.dev6", 0), + ("1.0a1", 0), + ("1.0a1.post5", 0), + ("1.0a1.post5.dev6", 0), + ("1.0rc4", 0), + ("1.0.post5", 0), + ("1!1.0", 1), + ("1!1.0.dev6", 1), + ("1!1.0a1", 1), + ("1!1.0a1.post5", 1), + ("1!1.0a1.post5.dev6", 1), + ("1!1.0rc4", 1), + ("1!1.0.post5", 1), + ("1.0+deadbeef", 0), + ("1.0.dev6+deadbeef", 0), + ("1.0a1+deadbeef", 0), + ("1.0a1.post5+deadbeef", 0), + ("1.0a1.post5.dev6+deadbeef", 0), + ("1.0rc4+deadbeef", 0), + ("1.0.post5+deadbeef", 0), + ("1!1.0+deadbeef", 1), + ("1!1.0.dev6+deadbeef", 1), + ("1!1.0a1+deadbeef", 1), + ("1!1.0a1.post5+deadbeef", 1), + ("1!1.0a1.post5.dev6+deadbeef", 1), + ("1!1.0rc4+deadbeef", 1), + ("1!1.0.post5+deadbeef", 1), + ], + ) + def test_version_epoch(self, version, epoch): + assert Version(version).epoch == epoch + + @pytest.mark.parametrize( + ("version", "release"), + [ + ("1.0", (1, 0)), + ("1.0.dev0", (1, 0)), + ("1.0.dev6", (1, 0)), + ("1.0a1", (1, 0)), + ("1.0a1.post5", (1, 0)), + ("1.0a1.post5.dev6", (1, 0)), + ("1.0rc4", (1, 0)), + ("1.0.post5", (1, 0)), + ("1!1.0", (1, 0)), + ("1!1.0.dev6", (1, 0)), + ("1!1.0a1", (1, 0)), + ("1!1.0a1.post5", (1, 0)), + ("1!1.0a1.post5.dev6", (1, 0)), + ("1!1.0rc4", (1, 0)), + ("1!1.0.post5", (1, 0)), + ("1.0+deadbeef", (1, 0)), + ("1.0.dev6+deadbeef", (1, 0)), + ("1.0a1+deadbeef", (1, 0)), + ("1.0a1.post5+deadbeef", (1, 0)), + ("1.0a1.post5.dev6+deadbeef", (1, 0)), + ("1.0rc4+deadbeef", (1, 0)), + ("1.0.post5+deadbeef", (1, 0)), + ("1!1.0+deadbeef", (1, 0)), + ("1!1.0.dev6+deadbeef", (1, 0)), + ("1!1.0a1+deadbeef", (1, 0)), + ("1!1.0a1.post5+deadbeef", (1, 0)), + ("1!1.0a1.post5.dev6+deadbeef", (1, 0)), + ("1!1.0rc4+deadbeef", (1, 0)), + ("1!1.0.post5+deadbeef", (1, 0)), + ], + ) + def test_version_release(self, version, release): + assert Version(version).release == release + + @pytest.mark.parametrize( ("version", "local"), [ ("1.0", None), + ("1.0.dev0", None), ("1.0.dev6", None), ("1.0a1", None), ("1.0a1.post5", None), @@ -369,8 +446,46 @@ assert Version(version).local == local @pytest.mark.parametrize( + ("version", "pre"), + [ + ("1.0", None), + ("1.0.dev0", None), + ("1.0.dev6", None), + ("1.0a1", ('a', 1)), + ("1.0a1.post5", ('a', 1)), + ("1.0a1.post5.dev6", ('a', 1)), + ("1.0rc4", ('rc', 4)), + ("1.0.post5", None), + ("1!1.0", None), + ("1!1.0.dev6", None), + ("1!1.0a1", ('a', 1)), + ("1!1.0a1.post5", ('a', 1)), + ("1!1.0a1.post5.dev6", ('a', 1)), + ("1!1.0rc4", ('rc', 4)), + ("1!1.0.post5", None), + ("1.0+deadbeef", None), + ("1.0.dev6+deadbeef", None), + ("1.0a1+deadbeef", ('a', 1)), + ("1.0a1.post5+deadbeef", ('a', 1)), + ("1.0a1.post5.dev6+deadbeef", ('a', 1)), + ("1.0rc4+deadbeef", ('rc', 4)), + ("1.0.post5+deadbeef", None), + ("1!1.0+deadbeef", None), + ("1!1.0.dev6+deadbeef", None), + ("1!1.0a1+deadbeef", ('a', 1)), + ("1!1.0a1.post5+deadbeef", ('a', 1)), + ("1!1.0a1.post5.dev6+deadbeef", ('a', 1)), + ("1!1.0rc4+deadbeef", ('rc', 4)), + ("1!1.0.post5+deadbeef", None), + ], + ) + def test_version_pre(self, version, pre): + assert Version(version).pre == pre + + @pytest.mark.parametrize( ("version", "expected"), [ + ("1.0.dev0", True), ("1.0.dev1", True), ("1.0a1.dev1", True), ("1.0b1.dev1", True), @@ -398,6 +513,117 @@ assert Version(version).is_prerelease is expected @pytest.mark.parametrize( + ("version", "dev"), + [ + ("1.0", None), + ("1.0.dev0", 0), + ("1.0.dev6", 6), + ("1.0a1", None), + ("1.0a1.post5", None), + ("1.0a1.post5.dev6", 6), + ("1.0rc4", None), + ("1.0.post5", None), + ("1!1.0", None), + ("1!1.0.dev6", 6), + ("1!1.0a1", None), + ("1!1.0a1.post5", None), + ("1!1.0a1.post5.dev6", 6), + ("1!1.0rc4", None), + ("1!1.0.post5", None), + ("1.0+deadbeef", None), + ("1.0.dev6+deadbeef", 6), + ("1.0a1+deadbeef", None), + ("1.0a1.post5+deadbeef", None), + ("1.0a1.post5.dev6+deadbeef", 6), + ("1.0rc4+deadbeef", None), + ("1.0.post5+deadbeef", None), + ("1!1.0+deadbeef", None), + ("1!1.0.dev6+deadbeef", 6), + ("1!1.0a1+deadbeef", None), + ("1!1.0a1.post5+deadbeef", None), + ("1!1.0a1.post5.dev6+deadbeef", 6), + ("1!1.0rc4+deadbeef", None), + ("1!1.0.post5+deadbeef", None), + ], + ) + def test_version_dev(self, version, dev): + assert Version(version).dev == dev + + @pytest.mark.parametrize( + ("version", "expected"), + [ + ("1.0", False), + ("1.0.dev0", True), + ("1.0.dev6", True), + ("1.0a1", False), + ("1.0a1.post5", False), + ("1.0a1.post5.dev6", True), + ("1.0rc4", False), + ("1.0.post5", False), + ("1!1.0", False), + ("1!1.0.dev6", True), + ("1!1.0a1", False), + ("1!1.0a1.post5", False), + ("1!1.0a1.post5.dev6", True), + ("1!1.0rc4", False), + ("1!1.0.post5", False), + ("1.0+deadbeef", False), + ("1.0.dev6+deadbeef", True), + ("1.0a1+deadbeef", False), + ("1.0a1.post5+deadbeef", False), + ("1.0a1.post5.dev6+deadbeef", True), + ("1.0rc4+deadbeef", False), + ("1.0.post5+deadbeef", False), + ("1!1.0+deadbeef", False), + ("1!1.0.dev6+deadbeef", True), + ("1!1.0a1+deadbeef", False), + ("1!1.0a1.post5+deadbeef", False), + ("1!1.0a1.post5.dev6+deadbeef", True), + ("1!1.0rc4+deadbeef", False), + ("1!1.0.post5+deadbeef", False), + ], + ) + def test_version_is_devrelease(self, version, expected): + assert Version(version).is_devrelease is expected + + @pytest.mark.parametrize( + ("version", "post"), + [ + ("1.0", None), + ("1.0.dev0", None), + ("1.0.dev6", None), + ("1.0a1", None), + ("1.0a1.post5", 5), + ("1.0a1.post5.dev6", 5), + ("1.0rc4", None), + ("1.0.post5", 5), + ("1!1.0", None), + ("1!1.0.dev6", None), + ("1!1.0a1", None), + ("1!1.0a1.post5", 5), + ("1!1.0a1.post5.dev6", 5), + ("1!1.0rc4", None), + ("1!1.0.post5", 5), + ("1.0+deadbeef", None), + ("1.0.dev6+deadbeef", None), + ("1.0a1+deadbeef", None), + ("1.0a1.post5+deadbeef", 5), + ("1.0a1.post5.dev6+deadbeef", 5), + ("1.0rc4+deadbeef", None), + ("1.0.post5+deadbeef", 5), + ("1!1.0+deadbeef", None), + ("1!1.0.dev6+deadbeef", None), + ("1!1.0a1+deadbeef", None), + ("1!1.0a1.post5+deadbeef", 5), + ("1!1.0a1.post5.dev6+deadbeef", 5), + ("1!1.0rc4+deadbeef", None), + ("1!1.0.post5+deadbeef", 5), + ], + ) + def test_version_post(self, version, post): + assert Version(version).post == post + + @pytest.mark.parametrize( ("version", "expected"), [ ("1.0.dev1", False), @@ -531,14 +757,38 @@ assert LegacyVersion(version).base_version == version @pytest.mark.parametrize("version", VERSIONS + LEGACY_VERSIONS) + def test_legacy_version_epoch(self, version): + assert LegacyVersion(version).epoch == -1 + + @pytest.mark.parametrize("version", VERSIONS + LEGACY_VERSIONS) + def test_legacy_version_release(self, version): + assert LegacyVersion(version).release is None + + @pytest.mark.parametrize("version", VERSIONS + LEGACY_VERSIONS) def test_legacy_version_local(self, version): assert LegacyVersion(version).local is None @pytest.mark.parametrize("version", VERSIONS + LEGACY_VERSIONS) + def test_legacy_version_pre(self, version): + assert LegacyVersion(version).pre is None + + @pytest.mark.parametrize("version", VERSIONS + LEGACY_VERSIONS) def test_legacy_version_is_prerelease(self, version): assert not LegacyVersion(version).is_prerelease @pytest.mark.parametrize("version", VERSIONS + LEGACY_VERSIONS) + def test_legacy_version_dev(self, version): + assert LegacyVersion(version).dev is None + + @pytest.mark.parametrize("version", VERSIONS + LEGACY_VERSIONS) + def test_legacy_version_is_devrelease(self, version): + assert not LegacyVersion(version).is_devrelease + + @pytest.mark.parametrize("version", VERSIONS + LEGACY_VERSIONS) + def test_legacy_version_post(self, version): + assert LegacyVersion(version).post is None + + @pytest.mark.parametrize("version", VERSIONS + LEGACY_VERSIONS) def test_legacy_version_is_postrelease(self, version): assert not LegacyVersion(version).is_postrelease diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/packaging-16.8/tox.ini new/packaging-17.1/tox.ini --- old/packaging-16.8/tox.ini 2016-10-29 17:54:54.000000000 +0200 +++ new/packaging-17.1/tox.ini 2018-02-28 14:57:14.000000000 +0100 @@ -1,33 +1,26 @@ [tox] -envlist = py26,py27,pypy,py32,py33,py34,docs,pep8,py2pep8 +envlist = py27,pypy,py34,py35,py36,py37,docs,pep8,py2pep8 [testenv] deps = coverage pretend pytest + https://github.com/pypa/pip/archive/master.zip#egg=pip +# The --ignore-installed install options is needed to install pip url +# (needed to issue #95). This can be removed once pip 10.0 is out. +install_command = + pip install {opts} {packages} --ignore-installed commands = python -m coverage run --source packaging/ -m pytest --strict {posargs} python -m coverage report -m --fail-under 100 -install_command = - pip install --find-links https://wheels.caremad.io/ {opts} {packages} - -# Python 2.6 doesn't support python -m on a package. -[testenv:py26] -commands = - python -m coverage.__main__ run --source packaging/ -m pytest --strict {posargs} - python -m coverage.__main__ report -m --fail-under 100 - -# coverage.py doesn't support Python 3.2 anymore. -[testenv:py32] -commands = - py.test --strict {posargs} [testenv:pypy] commands = py.test --capture=no --strict {posargs} [testenv:docs] +basepython = python3.6 deps = sphinx sphinx_rtd_theme @@ -37,14 +30,14 @@ sphinx-build -W -b doctest -d {envtmpdir}/doctrees docs docs/_build/html [testenv:pep8] -basepython = python3.2 +basepython = python3.4 deps = flake8 pep8-naming commands = flake8 . [testenv:py2pep8] -basepython = python2.6 +basepython = python2.7 deps = flake8 pep8-naming
