Skip to content

Commit

Permalink
Use a compatibility function for method comparison
Browse files Browse the repository at this point in the history
This is a rough attempt at building a compatibility function that
allows us to detect whether an object defines its own __reduce__ or
__reduce_ex__ on any interpreter. Some versions of PyPy 2.7 don't seem
to return True with "is" comparisons, and instead require ==.

I have arbitrarily chosen int as a builtin that derives from object and
doesn't define its own __reduce__. I think this is fairly safe to do in
2.7-only code, since it is stable now.
  • Loading branch information
pganssle committed Jan 14, 2020
1 parent af2018f commit 4849c42
Showing 1 changed file with 15 additions and 2 deletions.
17 changes: 15 additions & 2 deletions src/attr/_make.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,19 @@
_sentinel = object()


if PY2 and object.__reduce__ is not int.__reduce__:
# In pypy2.7, you can't use `is` on methods, but we want to use whichever
# method tells us `object.__reduce__` equals `int.__reduce__`
def _method_eq(a, b):
return a == b


else:

def _method_eq(a, b):
return a is b


class _Nothing(object):
"""
Sentinel class to indicate the lack of a value when ``None`` is ambiguous.
Expand Down Expand Up @@ -496,8 +509,8 @@ def __init__(

if (
cache_hash
and cls.__reduce__ is object.__reduce__
and cls.__reduce_ex__ is object.__reduce_ex__
and _method_eq(cls.__reduce__, object.__reduce__)
and _method_eq(cls.__reduce_ex__, object.__reduce_ex__)
):
self._cls_dict["__reduce__"] = _cache_hash_reduce

Expand Down

0 comments on commit 4849c42

Please sign in to comment.