Author: Philip Jenvey <[email protected]>
Branch: py3k
Changeset: r60185:950bba699a87
Date: 2013-01-18 13:28 -0800
http://bitbucket.org/pypy/pypy/changeset/950bba699a87/
Log: o add py3's inherent comparisons o avoid binding comparison
descriptors when possible, as you can't bind descriptors to None
itself! but it's also an optimization
diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -550,17 +550,26 @@
def _invoke_comparison(space, w_descr, w_obj1, w_obj2):
if w_descr is not None:
- try:
- w_impl = space.get(w_descr, w_obj1)
- except OperationError as e:
- # see testForExceptionsRaisedInInstanceGetattr2 in
- # test_class
- if not e.match(space, space.w_AttributeError):
- raise
+ # a special case for performance (see get_and_call_function) but
+ # also avoids binding via __get__ when unnecessary; in
+ # particular when w_obj1 is None, __get__(None, type(None))
+ # won't actually bind =]
+ descr = space.interpclass_w(w_descr)
+ typ = type(descr)
+ if typ is Function or typ is FunctionWithFixedCode:
+ w_res = descr.funccall(w_obj1, w_obj2)
else:
- w_res = space.call_function(w_impl, w_obj2)
- if _check_notimplemented(space, w_res):
- return w_res
+ try:
+ w_impl = space.get(w_descr, w_obj1)
+ except OperationError as e:
+ # see testForExceptionsRaisedInInstanceGetattr2 in
+ # test_class
+ if not e.match(space, space.w_AttributeError):
+ raise
+ else:
+ w_res = space.call_function(w_impl, w_obj2)
+ if _check_notimplemented(space, w_res):
+ return w_res
return None
def _make_comparison_impl(symbol, specialnames):
diff --git a/pypy/objspace/std/objecttype.py b/pypy/objspace/std/objecttype.py
--- a/pypy/objspace/std/objecttype.py
+++ b/pypy/objspace/std/objecttype.py
@@ -205,6 +205,19 @@
reduce_1 = app.interphook('reduce_1')
reduce_2 = app.interphook('reduce_2')
+def descr__eq__(space, w_self, w_other):
+ if space.is_w(w_self, w_other):
+ return space.w_True
+ # Return NotImplemented instead of False, so if two objects are
+ # compared, both get a chance at the comparison (issue #1393)
+ return space.w_NotImplemented
+
+def descr__ne__(space, w_self, w_other):
+ return space.not_(space.eq(w_self, w_other))
+
+def descr_richcompare(space, w_self, w_other):
+ return space.w_NotImplemented
+
# ____________________________________________________________
object_typedef = StdTypeDef("object",
@@ -222,5 +235,11 @@
__format__ = gateway.interp2app(descr___format__),
__subclasshook__ = gateway.interp2app(descr___subclasshook__,
as_classmethod=True),
+ __eq__ = gateway.interp2app(descr__eq__),
+ __ne__ = gateway.interp2app(descr__ne__),
+ __le__ = gateway.interp2app(descr_richcompare),
+ __lt__ = gateway.interp2app(descr_richcompare),
+ __ge__ = gateway.interp2app(descr_richcompare),
+ __gt__ = gateway.interp2app(descr_richcompare),
__init__ = gateway.interp2app(descr__init__),
)
diff --git a/pypy/objspace/std/test/test_obj.py
b/pypy/objspace/std/test/test_obj.py
--- a/pypy/objspace/std/test/test_obj.py
+++ b/pypy/objspace/std/test/test_obj.py
@@ -248,6 +248,17 @@
y += 2
assert object.__hash__(x) == object.__hash__(y)
+ def test_richcompare(self):
+ o = object()
+ o2 = object()
+ assert o.__eq__(o) is True
+ assert o.__eq__(o2) is NotImplemented
+ assert o.__ne__(o) is False
+ assert o.__ne__(o2) is True
+ assert o.__le__(o2) is NotImplemented
+ assert o.__lt__(o2) is NotImplemented
+ assert o.__ge__(o2) is NotImplemented
+ assert o.__gt__(o2) is NotImplemented
def test_isinstance_shortcut():
from pypy.objspace.std import objspace
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit