Author: Amaury Forgeot d'Arc <amaur...@gmail.com> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit