Author: Amaury Forgeot d'Arc <[email protected]>
Branch: py3.6
Changeset: r93461:77d216c5b248
Date: 2017-12-17 22:03 +0100
http://bitbucket.org/pypy/pypy/changeset/77d216c5b248/
Log: CPython Issue #28727: re.Pattern objects created by re.compile()
become comparable (only x==y and x!=y operators)
diff --git a/pypy/module/_sre/interp_sre.py b/pypy/module/_sre/interp_sre.py
--- a/pypy/module/_sre/interp_sre.py
+++ b/pypy/module/_sre/interp_sre.py
@@ -5,6 +5,7 @@
from pypy.interpreter.typedef import make_weakref_descr
from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
from pypy.interpreter.error import OperationError, oefmt
+from rpython.rlib.objectmodel import compute_hash
from rpython.rlib.rarithmetic import intmask
from rpython.rlib import jit
from rpython.rlib.rstring import StringBuilder, UnicodeBuilder
@@ -133,6 +134,24 @@
uflags = u'|'.join([item.decode('latin-1') for item in flag_items])
return space.newunicode(u're.compile(%s%s%s)' % (u, usep, uflags))
+ def descr_eq(self, space, w_other):
+ if not isinstance(w_other, W_SRE_Pattern):
+ return space.w_NotImplemented
+ other = w_other
+ # Compare the code and the pattern because the same pattern can
+ # produce different codes depending on the locale used to compile the
+ # pattern when the re.LOCALE flag is used. Don't compare groups,
+ # indexgroup nor groupindex: they are derivated from the pattern.
+ return space.newbool(
+ self.flags == other.flags and
+ self.code == other.code and
+ space.eq_w(self.w_pattern, other.w_pattern))
+
+ def descr_hash(self, space):
+ code = ''.join([chr(c) for c in self.code])
+ return space.newint(compute_hash(
+ (self.flags, code, space.hash_w(self.w_pattern))))
+
def fget_groupindex(self, space):
w_groupindex = self.w_groupindex
if space.isinstance_w(w_groupindex, space.w_dict):
@@ -488,6 +507,8 @@
__deepcopy__ = interp2app(W_SRE_Pattern.cannot_copy_w),
__repr__ = interp2app(W_SRE_Pattern.repr_w),
__weakref__ = make_weakref_descr(W_SRE_Pattern),
+ __eq__ = interp2app(W_SRE_Pattern.descr_eq),
+ __hash__ = interp2app(W_SRE_Pattern.descr_hash),
findall = interp2app(W_SRE_Pattern.findall_w),
finditer = interp2app(W_SRE_Pattern.finditer_w),
match = interp2app(W_SRE_Pattern.match_w),
diff --git a/pypy/module/_sre/test/test_app_sre.py
b/pypy/module/_sre/test/test_app_sre.py
--- a/pypy/module/_sre/test/test_app_sre.py
+++ b/pypy/module/_sre/test/test_app_sre.py
@@ -133,6 +133,33 @@
assert repr(r) == (
r"""re.compile('f(o"\\d)', re.IGNORECASE|re.DOTALL|re.VERBOSE)""")
+ def test_pattern_compare(self):
+ import re
+ pattern1 = re.compile('abc', re.IGNORECASE)
+
+ # equal to itself
+ assert pattern1 == pattern1
+ assert not(pattern1 != pattern1)
+ # equal
+ re.purge()
+ pattern2 = re.compile('abc', re.IGNORECASE)
+ assert hash(pattern2) == hash(pattern1)
+ assert pattern2 == pattern1
+
+ # not equal: different pattern
+ re.purge()
+ pattern3 = re.compile('XYZ', re.IGNORECASE)
+ # warranty that hash values are different
+ assert pattern3 != pattern1
+
+ # not equal: different flag (flags=0)
+ re.purge()
+ pattern4 = re.compile('abc')
+ assert pattern4 != pattern1
+
+ # only == and != comparison operators are supported
+ raises(TypeError, "pattern1 < pattern2")
+
class AppTestSreMatch:
spaceconfig = dict(usemodules=('array', ))
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit