Skip to content

Commit

Permalink
Deprecate LegacyVersion/LegacySpecifier (#342)
Browse files Browse the repository at this point in the history
  • Loading branch information
di authored Oct 20, 2020
1 parent ef6d506 commit 5abbd38
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Changelog
*unreleased*
~~~~~~~~~~~~

* Deprecate the ``LegacyVersion`` and ``LegacySpecifier`` classes (:issue:`321`)
* Handle ``OSError`` on non-dynamic executables when attempting to resolve
the glibc version string.

Expand Down
25 changes: 15 additions & 10 deletions docs/specifiers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,11 @@ Reference
This class abstracts handling specifying the dependencies of a project. It
can be passed a single specifier (``>=3.0``), a comma-separated list of
specifiers (``>=3.0,!=3.1``), or no specifier at all. Each individual
specifier be attempted to be parsed as a PEP 440 specifier
specifier will be attempted to be parsed as a PEP 440 specifier
(:class:`Specifier`) or as a legacy, setuptools style specifier
(:class:`LegacySpecifier`). You may combine :class:`SpecifierSet` instances
using the ``&`` operator (``SpecifierSet(">2") & SpecifierSet("<4")``).
(deprecated :class:`LegacySpecifier`). You may combine
:class:`SpecifierSet` instances using the ``&`` operator
(``SpecifierSet(">2") & SpecifierSet("<4")``).

Both the membership tests and the combination support using raw strings
in place of already instantiated objects.
Expand Down Expand Up @@ -90,8 +91,8 @@ Reference
.. method:: contains(version, prereleases=None)

Determines if ``version``, which can be either a version string, a
:class:`Version`, or a :class:`LegacyVersion` object, is contained
within this set of specifiers.
:class:`Version`, or a deprecated :class:`LegacyVersion` object, is
contained within this set of specifiers.

This will either match or not match prereleases based on the
``prereleases`` parameter. When ``prereleases`` is set to ``None``
Expand All @@ -105,15 +106,15 @@ Reference

.. method:: __iter__()

Returns an iterator over all the underlying :class:`Specifier`
(or :class:`LegacySpecifier`) instances in this specifier set.
Returns an iterator over all the underlying :class:`Specifier` (or
deprecated :class:`LegacySpecifier`) instances in this specifier set.

.. method:: filter(iterable, prereleases=None)

Takes an iterable that can contain version strings, :class:`~.Version`,
and :class:`~.LegacyVersion` instances and will then filter it, returning
an iterable that contains only items which match the rules of this
specifier object.
and deprecated :class:`~.LegacyVersion` instances and will then filter
it, returning an iterable that contains only items which match the
rules of this specifier object.

This method is smarter than just
``filter(Specifier().contains, [...])`` because it implements the rule
Expand Down Expand Up @@ -170,6 +171,10 @@ Reference

.. class:: LegacySpecifier(specifier, prereleases=None)

.. deprecated:: 20.5

Use :class:`Specifier` instead.

This class abstracts the handling of a single legacy, setuptools style
specifier. It is generally not required to instantiate this manually,
preferring instead to work with :class:`SpecifierSet`.
Expand Down
6 changes: 5 additions & 1 deletion docs/version.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Reference

This function takes a version string and will parse it as a
:class:`Version` if the version is a valid PEP 440 version, otherwise it
will parse it as a :class:`LegacyVersion`.
will parse it as a deprecated :class:`LegacyVersion`.


.. class:: Version(version)
Expand Down Expand Up @@ -140,6 +140,10 @@ Reference

.. class:: LegacyVersion(version)

.. deprecated:: 20.5

Use :class:`Version` instead.

This class abstracts handling of a project's versions if they are not
compatible with the scheme defined in `PEP 440`_. It implements a similar
interface to that of :class:`Version`.
Expand Down
13 changes: 12 additions & 1 deletion packaging/specifiers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import functools
import itertools
import re
import warnings

from ._compat import string_types, with_metaclass
from ._typing import TYPE_CHECKING
Expand Down Expand Up @@ -275,6 +276,16 @@ class LegacySpecifier(_IndividualSpecifier):
">": "greater_than",
}

def __init__(self, spec="", prereleases=None):
# type: (str, Optional[bool]) -> None
super(LegacySpecifier, self).__init__(spec, prereleases)

warnings.warn(
"Creating a LegacyVersion has been deprecated and will be "
"removed in the next major release",
DeprecationWarning,
)

def _coerce_version(self, version):
# type: (Union[ParsedVersion, str]) -> LegacyVersion
if not isinstance(version, LegacyVersion):
Expand Down Expand Up @@ -307,7 +318,7 @@ def _compare_greater_than(self, prospective, spec):


def _require_version_compare(
fn # type: (Callable[[Specifier, ParsedVersion, str], bool])
fn, # type: (Callable[[Specifier, ParsedVersion, str], bool])
):
# type: (...) -> Callable[[Specifier, ParsedVersion, str], bool]
@functools.wraps(fn)
Expand Down
7 changes: 7 additions & 0 deletions packaging/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import collections
import itertools
import re
import warnings

from ._structures import Infinity, NegativeInfinity
from ._typing import TYPE_CHECKING
Expand Down Expand Up @@ -123,6 +124,12 @@ def __init__(self, version):
self._version = str(version)
self._key = _legacy_cmpkey(self._version)

warnings.warn(
"Creating a LegacyVersion has been deprecated and will be "
"removed in the next major release",
DeprecationWarning,
)

def __str__(self):
# type: () -> str
return self._version
Expand Down
7 changes: 7 additions & 0 deletions tests/test_specifiers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import itertools
import operator
import warnings

import pytest

Expand Down Expand Up @@ -632,6 +633,12 @@ def test_iteration(self, spec, expected_items):


class TestLegacySpecifier:
def test_legacy_specifier_is_deprecated(self):
with warnings.catch_warnings(record=True) as w:
LegacySpecifier(">=some-legacy-version")
assert len(w) == 1
assert issubclass(w[0].category, DeprecationWarning)

@pytest.mark.parametrize(
("version", "spec", "expected"),
[
Expand Down
7 changes: 7 additions & 0 deletions tests/test_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import itertools
import operator
import warnings

import pretend
import pytest
Expand Down Expand Up @@ -780,6 +781,12 @@ def test_micro_version(self):


class TestLegacyVersion:
def test_legacy_version_is_deprecated(self):
with warnings.catch_warnings(record=True) as w:
LegacyVersion("some-legacy-version")
assert len(w) == 1
assert issubclass(w[0].category, DeprecationWarning)

@pytest.mark.parametrize("version", VERSIONS + LEGACY_VERSIONS)
def test_valid_legacy_versions(self, version):
LegacyVersion(version)
Expand Down

0 comments on commit 5abbd38

Please sign in to comment.