From c58b0fb4acefefc81a12ab92ad3f37384218ee78 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 5 Oct 2019 18:16:35 -0700 Subject: [PATCH] Use ATTRS_EQ_FIELD for attrs 19.2 compat --- src/_pytest/assertion/util.py | 18 ++++-------------- src/_pytest/compat.py | 7 +++---- src/_pytest/mark/structures.py | 5 +++-- testing/test_assertion.py | 4 ++-- 4 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/_pytest/assertion/util.py b/src/_pytest/assertion/util.py index 21ec72803..c2a4e446f 100644 --- a/src/_pytest/assertion/util.py +++ b/src/_pytest/assertion/util.py @@ -8,7 +8,7 @@ from typing import Optional import _pytest._code from _pytest import outcomes from _pytest._io.saferepr import saferepr -from _pytest.compat import attrs_has_eq +from _pytest.compat import ATTRS_EQ_FIELD # The _reprcompare attribute on the util module is used by the new assertion # interpretation code and assertion rewriter to detect this plugin was @@ -113,18 +113,6 @@ 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) @@ -388,7 +376,9 @@ 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 attrsfieldhaseq(field)] + fields_to_check = [ + field.name for field in all_fields if getattr(field, ATTRS_EQ_FIELD) + ] same = [] diff = [] diff --git a/src/_pytest/compat.py b/src/_pytest/compat.py index 575e85b9a..3898fb252 100644 --- a/src/_pytest/compat.py +++ b/src/_pytest/compat.py @@ -356,8 +356,7 @@ if sys.version_info < (3, 5, 2): # pragma: no cover return f -attrs_has_eq = getattr(attr, "__version_info__", (0, 0)) >= (19, 2) -if attrs_has_eq: - attrs_no_eq = {"eq": False} +if getattr(attr, "__version_info__", ()) >= (19, 2): + ATTRS_EQ_FIELD = "eq" else: - attrs_no_eq = {"cmp": False} + ATTRS_EQ_FIELD = "cmp" diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py index 19333453f..2cab96d67 100644 --- a/src/_pytest/mark/structures.py +++ b/src/_pytest/mark/structures.py @@ -8,7 +8,7 @@ from typing import Set import attr from ..compat import ascii_escaped -from ..compat import attrs_no_eq +from ..compat import ATTRS_EQ_FIELD from ..compat import getfslineno from ..compat import NOTSET from _pytest.outcomes import fail @@ -368,7 +368,8 @@ class NodeKeywords(MutableMapping): return "".format(self.node) -@attr.s(hash=False, **attrs_no_eq) # type: ignore +# mypy cannot find this overload, remove when on attrs>=19.2 +@attr.s(hash=False, **{ATTRS_EQ_FIELD: False}) # type: ignore class NodeMarkers: """ internal structure for storing marks belonging to a node diff --git a/testing/test_assertion.py b/testing/test_assertion.py index 83370fb43..8fce5e279 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -9,7 +9,7 @@ import pytest from _pytest import outcomes from _pytest.assertion import truncate from _pytest.assertion import util -from _pytest.compat import attrs_no_eq +from _pytest.compat import ATTRS_EQ_FIELD def mock_config(): @@ -688,7 +688,7 @@ class TestAssert_reprcompare_attrsclass: @attr.s class SimpleDataObject: field_a = attr.ib() - field_b = attr.ib(**attrs_no_eq) + field_b = attr.ib(**{ATTRS_EQ_FIELD: False}) left = SimpleDataObject(1, "b") right = SimpleDataObject(1, "b")