Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate LegacyVersion/LegacySpecifier #342

Merged
merged 1 commit into from
Oct 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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