Skip to content

Commit

Permalink
Fix warnings with attrs 19.2 and fix object assertions
Browse files Browse the repository at this point in the history
attrs 19.2 deprecated cmp in favor of the dataclass-ish eq/order duo.

This causes deprecation warnings that in turn break some of the cool new deep
object comparisons. Since we at attrs expected this to be a problem, it shipped
with helpers to write backward and forward compatible code.

This PR uses that and avoids changed to minimal versions.
  • Loading branch information
hynek committed Oct 1, 2019
1 parent 9a4c0b9 commit a79acf2
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 3 deletions.
15 changes: 14 additions & 1 deletion src/_pytest/assertion/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import _pytest._code
from _pytest import outcomes
from _pytest._io.saferepr import saferepr
from _pytest.compat import attrs_has_eq

# The _reprcompare attribute on the util module is used by the new assertion
# interpretation code and assertion rewriter to detect this plugin was
Expand Down Expand Up @@ -112,6 +113,18 @@ def isattrs(obj):
return getattr(obj, "__attrs_attrs__", None) is not None


if attrs_has_eq:

def attrsfieldhaseq(a):
return a.eq


else:

def attrsfieldhaseq(a):
return a.cmp


def isiterable(obj):
try:
iter(obj)
Expand Down Expand Up @@ -375,7 +388,7 @@ def _compare_eq_cls(left, right, verbose, type_fns):
fields_to_check = [field for field, info in all_fields.items() if info.compare]
elif isattrs(left):
all_fields = left.__attrs_attrs__
fields_to_check = [field.name for field in all_fields if field.cmp]
fields_to_check = [field.name for field in all_fields if attrsfieldhaseq(field)]

same = []
diff = []
Expand Down
7 changes: 7 additions & 0 deletions src/_pytest/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,3 +354,10 @@ def funcargnames(self):

def overload(f): # noqa: F811
return f


attrs_has_eq = getattr(attr, "__version_info__", (0, 0)) >= (19, 2)
if attrs_has_eq:
attrs_no_eq = {"eq": False}
else:
attrs_no_eq = {"cmp": False}
3 changes: 2 additions & 1 deletion src/_pytest/mark/structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import attr

from ..compat import ascii_escaped
from ..compat import attrs_no_eq
from ..compat import getfslineno
from ..compat import NOTSET
from _pytest.outcomes import fail
Expand Down Expand Up @@ -367,7 +368,7 @@ def __repr__(self):
return "<NodeKeywords for node {}>".format(self.node)


@attr.s(cmp=False, hash=False)
@attr.s(hash=False, **attrs_no_eq) # type: ignore
class NodeMarkers:
"""
internal structure for storing marks belonging to a node
Expand Down
3 changes: 2 additions & 1 deletion testing/test_assertion.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from _pytest import outcomes
from _pytest.assertion import truncate
from _pytest.assertion import util
from _pytest.compat import attrs_no_eq


def mock_config():
Expand Down Expand Up @@ -687,7 +688,7 @@ def test_attrs_with_attribute_comparison_off(self):
@attr.s
class SimpleDataObject:
field_a = attr.ib()
field_b = attr.ib(cmp=False)
field_b = attr.ib(**attrs_no_eq)

left = SimpleDataObject(1, "b")
right = SimpleDataObject(1, "b")
Expand Down

0 comments on commit a79acf2

Please sign in to comment.