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

Undeprecate cmp #773

Merged
merged 10 commits into from
Feb 28, 2021
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.d/773.deprecation.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
``cmp`` has been undeprecated and will continue to be supported as syntactic sugar to set ``eq`` and ``order`` in one go.
2 changes: 0 additions & 2 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,4 @@ It behaves similarly to `sys.version_info` and is an instance of `VersionInfo`:
The serious business aliases used to be called ``attr.attributes`` and ``attr.attr``.
There are no plans to remove them but they shouldn't be used in new code.

The ``cmp`` argument to both `attr.s` and `attr.ib` has been deprecated in 19.2 and shouldn't be used.

.. autofunction:: assoc
16 changes: 5 additions & 11 deletions src/attr/_make.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,6 @@ def attrib(

:param cmp: Setting to ``True`` is equivalent to setting ``eq=True,
order=True``. Can also be set to a ``callable``.
Deprecated in favor of *eq* and *order*.
:type cmp: a `bool` or a `callable`.

:param Optional[bool] hash: Include this attribute in the generated
Expand Down Expand Up @@ -252,7 +251,8 @@ def attrib(
.. versionadded:: 19.2.0 *eq* and *order*
.. versionadded:: 20.1.0 *on_setattr*
.. versionchanged:: 20.3.0 *kw_only* backported to Python 2
.. versionchanged:: 21.1.0 *eq* and *order* also accept a custom callable.
.. versionchanged:: 21.1.0 *eq* and *order* also accept a custom callable
.. versionchanged:: 21.1.0 *cmp* undeprecated
"""
eq, eq_key, order, order_key = _determine_attrib_eq_order(
cmp, eq, order, True
Expand Down Expand Up @@ -1083,8 +1083,6 @@ def _determine_attrs_eq_order(cmp, eq, order, default_eq):

# cmp takes precedence due to bw-compatibility.
if cmp is not None:
warnings.warn(_CMP_DEPRECATION, DeprecationWarning, stacklevel=3)

return cmp, cmp

# If left None, equality is set to the specified default and ordering
Expand Down Expand Up @@ -1121,8 +1119,6 @@ def decide_callable_or_boolean(value):

# cmp takes precedence due to bw-compatibility.
if cmp is not None:
warnings.warn(_CMP_DEPRECATION, DeprecationWarning, stacklevel=3)

cmp, cmp_key = decide_callable_or_boolean(cmp)
return cmp, cmp_key, cmp, cmp_key

Expand Down Expand Up @@ -1263,9 +1259,7 @@ def attrs(
allow instances to be ordered. If ``None`` (default) mirror value of
*eq*.
:param Optional[bool] cmp: Setting to ``True`` is equivalent to setting
``eq=True, order=True``. Deprecated in favor of *eq* and *order*, has
precedence over them for backward-compatibility though. Must not be
mixed with *eq* or *order*.
``eq=True, order=True``. Must not be mixed with *eq* or *order*.
:param Optional[bool] hash: If ``None`` (default), the ``__hash__`` method
is generated according how *eq* and *frozen* are set.

Expand Down Expand Up @@ -1438,7 +1432,7 @@ def attrs(
.. versionchanged:: 21.1.0
``init=False`` injects ``__attrs_init__``
.. versionchanged:: 21.1.0 Support for ``__attrs_pre_init__``

.. versionchanged:: 21.1.0 *cmp* undeprecated
"""
if auto_detect and PY2:
raise PythonTooOldError(
Expand Down Expand Up @@ -2762,7 +2756,7 @@ def __init__(
default,
validator,
repr,
cmp, # XXX: unused, remove along with cmp
cmp,
hash,
init,
converter,
Expand Down
4 changes: 0 additions & 4 deletions tests/test_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -680,10 +680,6 @@ class C(object):

assert rv == attr.fields(C).x.cmp

if cmp is not None:
# Remove warning from creating the attribute if cmp is not None.
dc.pop()

(w,) = dc.list

assert (
Expand Down
64 changes: 1 addition & 63 deletions tests/test_make.py
Original file line number Diff line number Diff line change
Expand Up @@ -1862,24 +1862,6 @@ def test_mix(self, cmp, eq, order):
):
_determine_attrs_eq_order(cmp, eq, order, True)

def test_cmp_deprecated(self):
"""
Passing a cmp that is not None raises a DeprecationWarning.
"""
with pytest.deprecated_call() as dc:

@attr.s(cmp=True)
class C(object):
pass

(w,) = dc.list

assert (
"The usage of `cmp` is deprecated and will be removed on or after "
"2021-06-01. Please use `eq` and `order` instead."
== w.message.args[0]
)


class TestDetermineAttribEqOrder(object):
def test_default(self):
Expand Down Expand Up @@ -1968,45 +1950,6 @@ def test_mix(self, cmp, eq, order):
):
_determine_attrib_eq_order(cmp, eq, order, True)

def test_boolean_cmp_deprecated(self):
"""
Passing a cmp that is not None raises a DeprecationWarning.
"""
with pytest.deprecated_call() as dc:

assert (True, None, True, None) == _determine_attrib_eq_order(
True, None, None, True
)

(w,) = dc.list

assert (
"The usage of `cmp` is deprecated and will be removed on or after "
"2021-06-01. Please use `eq` and `order` instead."
== w.message.args[0]
)

def test_callable_cmp_deprecated(self):
"""
Passing a cmp that is not None raises a DeprecationWarning.
"""
with pytest.deprecated_call() as dc:

assert (
True,
str.lower,
True,
str.lower,
) == _determine_attrib_eq_order(str.lower, None, None, True)

(w,) = dc.list

assert (
"The usage of `cmp` is deprecated and will be removed on or after "
"2021-06-01. Please use `eq` and `order` instead."
== w.message.args[0]
)


class TestDocs:
@pytest.mark.parametrize(
Expand Down Expand Up @@ -2301,7 +2244,7 @@ def __ne__(self, o):
(None, None, True),
],
)
def test_override_order(self, slots, frozen, eq, order, cmp, recwarn):
def test_override_order(self, slots, frozen, eq, order, cmp):
"""
If order=True is passed, ignore __le__, __lt__, __gt__, __ge__.

Expand All @@ -2328,11 +2271,6 @@ class C(object):
assert C(2) > C(1)
assert C(2) >= C(1)

if cmp:
assert 1 == len(recwarn.list)
else:
assert 0 == len(recwarn.list)

@pytest.mark.parametrize("slots", [True, False])
@pytest.mark.parametrize("first", [True, False])
def test_total_ordering(self, slots, first):
Expand Down