Author: aliles Branch: Changeset: r53537:23f16a681b06 Date: 2012-03-12 23:44 -0700 http://bitbucket.org/pypy/pypy/changeset/23f16a681b06/
Log: Introduce a base class hierarchy for string objects. Hierarchy to be used to pull up shared code between character sequence objects. Currently on generic function specialization has been pulled up. diff --git a/pypy/objspace/std/abstractstring.py b/pypy/objspace/std/abstractstring.py new file mode 100644 --- /dev/null +++ b/pypy/objspace/std/abstractstring.py @@ -0,0 +1,49 @@ +from pypy.objspace.std.model import W_Object +from pypy.rlib.objectmodel import specialize + + +class W_AbstractBaseStringObject(W_Object): + __slots__ = () + + def __repr__(w_self): + """ representation for debugging purposes """ + return "%s(%r)" % (w_self.__class__.__name__, w_self.raw_value()) + + def is_w(self, space, w_other): + if not isinstance(w_other, W_AbstractBaseStringObject): + return False + if self is w_other: + return True + if self.user_overridden_class or w_other.user_overridden_class: + return False + return self.unwrap(space) is w_other.unwrap(space) + + def immutable_unique_id(w_self, space): + if w_self.user_overridden_class: + return None + return space.wrap(compute_unique_id(w_self.unwrap(space))) + + def raw_value(w_self): + raise NotImplemented("method not implemented") + + def unwrap(w_self, space): + raise NotImplemented("method not implemented") + + def str_w(w_self, space): + raise NotImplemented("method not implemented") + + def unicode_w(w_self, space): + raise NotImplemented("method not implemented") + + +@specialize.arg(2) +def is_generic(space, w_self, fun): + v = w_self._value + if len(v) == 0: + return space.w_False + if len(v) == 1: + return space.newbool(fun(v[0])) + for idx in range(len(v)): + if not fun(v[idx]): + return space.w_False + return space.w_True diff --git a/pypy/objspace/std/ropeobject.py b/pypy/objspace/std/ropeobject.py --- a/pypy/objspace/std/ropeobject.py +++ b/pypy/objspace/std/ropeobject.py @@ -28,24 +28,22 @@ assert node.is_bytestring() w_self._node = node - def __repr__(w_self): - """ representation for debugging purposes """ - return "%s(%r)" % (w_self.__class__.__name__, w_self._node) + def raw_value(w_self): + return w_self._node - def unwrap(w_self, space): + def str_w(w_self, space): return w_self._node.flatten_string() - str_w = unwrap + + def unicode_w(w_self, space): + # XXX should this use the default encoding? + from pypy.objspace.std.unicodetype import plain_str2unicode + return plain_str2unicode(space, w_self._node.flatten_string()) def create_if_subclassed(w_self): if type(w_self) is W_RopeObject: return w_self return W_RopeObject(w_self._node) - def unicode_w(w_self, space): - # XXX should this use the default encoding? - from pypy.objspace.std.unicodetype import plain_str2unicode - return plain_str2unicode(space, w_self._node.flatten_string()) - W_RopeObject.EMPTY = W_RopeObject(rope.LiteralStringNode.EMPTY) W_RopeObject.PREBUILT = [W_RopeObject(rope.LiteralStringNode.PREBUILT[i]) for i in range(256)] diff --git a/pypy/objspace/std/ropeunicodeobject.py b/pypy/objspace/std/ropeunicodeobject.py --- a/pypy/objspace/std/ropeunicodeobject.py +++ b/pypy/objspace/std/ropeunicodeobject.py @@ -84,25 +84,20 @@ def __init__(w_self, node): w_self._node = node - def __repr__(w_self): - """ representation for debugging purposes """ - return "%s(%r)" % (w_self.__class__.__name__, w_self._node) - - def unwrap(w_self, space): - # for testing - return w_self._node.flatten_unicode() + def raw_value(w_self): + return w_self._node def str_w(w_self, space): return space.str_w(space.str(w_self)) + def unicode_w(self, space): + return self._node.flatten_unicode() + def create_if_subclassed(w_self): if type(w_self) is W_RopeUnicodeObject: return w_self return W_RopeUnicodeObject(w_self._node) - def unicode_w(self, space): - return self._node.flatten_unicode() - W_RopeUnicodeObject.EMPTY = W_RopeUnicodeObject(rope.LiteralStringNode.EMPTY) registerimplementation(W_RopeUnicodeObject) diff --git a/pypy/objspace/std/stringobject.py b/pypy/objspace/std/stringobject.py --- a/pypy/objspace/std/stringobject.py +++ b/pypy/objspace/std/stringobject.py @@ -15,27 +15,17 @@ from pypy.rlib.rstring import StringBuilder, split from pypy.interpreter.buffer import StringBuffer +from pypy.objspace.std.abstractstring import W_AbstractBaseStringObject, \ + is_generic +from pypy.objspace.std.formatting import mod_format from pypy.objspace.std.stringtype import sliced, wrapstr, wrapchar, \ stringendswith, stringstartswith, joined2 -from pypy.objspace.std.formatting import mod_format - -class W_AbstractStringObject(W_Object): +class W_AbstractStringObject(W_AbstractBaseStringObject): __slots__ = () - def is_w(self, space, w_other): - if not isinstance(w_other, W_AbstractStringObject): - return False - if self is w_other: - return True - if self.user_overridden_class or w_other.user_overridden_class: - return False - return space.str_w(self) is space.str_w(w_other) - - def immutable_unique_id(self, space): - if self.user_overridden_class: - return None - return space.wrap(compute_unique_id(space.str_w(self))) + def unwrap(w_self, space): + return w_self.str_w(space) class W_StringObject(W_AbstractStringObject): @@ -45,11 +35,7 @@ def __init__(w_self, str): w_self._value = str - def __repr__(w_self): - """ representation for debugging purposes """ - return "%s(%r)" % (w_self.__class__.__name__, w_self._value) - - def unwrap(w_self, space): + def raw_value(w_self): return w_self._value def str_w(w_self, space): @@ -66,24 +52,6 @@ W_StringObject.PREBUILT = [W_StringObject(chr(i)) for i in range(256)] del i -@specialize.arg(2) -def _is_generic(space, w_self, fun): - v = w_self._value - if len(v) == 0: - return space.w_False - if len(v) == 1: - c = v[0] - return space.newbool(fun(c)) - else: - return _is_generic_loop(space, v, fun) - -@specialize.arg(2) -def _is_generic_loop(space, v, fun): - for idx in range(len(v)): - if not fun(v[idx]): - return space.w_False - return space.w_True - def _upper(ch): if ch.islower(): o = ord(ch) - 32 @@ -98,22 +66,21 @@ else: return ch -_isspace = lambda c: c.isspace() -_isdigit = lambda c: c.isdigit() -_isalpha = lambda c: c.isalpha() -_isalnum = lambda c: c.isalnum() - def str_isspace__String(space, w_self): - return _is_generic(space, w_self, _isspace) + isspace = lambda c: c.isspace() + return is_generic(space, w_self, isspace) def str_isdigit__String(space, w_self): - return _is_generic(space, w_self, _isdigit) + isdigit = lambda c: c.isdigit() + return is_generic(space, w_self, isdigit) def str_isalpha__String(space, w_self): - return _is_generic(space, w_self, _isalpha) + isalpha = lambda c: c.isalpha() + return is_generic(space, w_self, isalpha) def str_isalnum__String(space, w_self): - return _is_generic(space, w_self, _isalnum) + isalnum = lambda c: c.isalnum() + return is_generic(space, w_self, isalnum) def str_isupper__String(space, w_self): """Return True if all cased characters in S are uppercase and there is diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -17,25 +17,15 @@ from pypy.module.unicodedata import unicodedb from pypy.tool.sourcetools import func_with_new_name +from pypy.objspace.std.abstractstring import W_AbstractBaseStringObject from pypy.objspace.std.formatting import mod_format from pypy.objspace.std.stringtype import stringstartswith, stringendswith -class W_AbstractUnicodeObject(W_Object): +class W_AbstractUnicodeObject(W_AbstractBaseStringObject): __slots__ = () - def is_w(self, space, w_other): - if not isinstance(w_other, W_AbstractUnicodeObject): - return False - if self is w_other: - return True - if self.user_overridden_class or w_other.user_overridden_class: - return False - return space.unicode_w(self) is space.unicode_w(w_other) - - def immutable_unique_id(self, space): - if self.user_overridden_class: - return None - return space.wrap(compute_unique_id(space.unicode_w(self))) + def unwrap(w_self, space): + return w_self.unicode_w(space) class W_UnicodeObject(W_AbstractUnicodeObject): @@ -46,25 +36,20 @@ assert isinstance(unistr, unicode) w_self._value = unistr - def __repr__(w_self): - """ representation for debugging purposes """ - return "%s(%r)" % (w_self.__class__.__name__, w_self._value) - - def unwrap(w_self, space): - # for testing + def raw_value(w_self): return w_self._value - def create_if_subclassed(w_self): - if type(w_self) is W_UnicodeObject: - return w_self - return W_UnicodeObject(w_self._value) - def str_w(self, space): return space.str_w(space.str(self)) def unicode_w(self, space): return self._value + def create_if_subclassed(w_self): + if type(w_self) is W_UnicodeObject: + return w_self + return W_UnicodeObject(w_self._value) + W_UnicodeObject.EMPTY = W_UnicodeObject(u'') registerimplementation(W_UnicodeObject) @@ -305,23 +290,23 @@ def _isspace(uchar): return unicodedb.isspace(ord(uchar)) -def make_generic(funcname): - def func(space, w_self): - v = w_self._value - if len(v) == 0: - return space.w_False - for idx in range(len(v)): - if not getattr(unicodedb, funcname)(ord(v[idx])): - return space.w_False - return space.w_True - return func_with_new_name(func, "unicode_%s__Unicode" % (funcname, )) +def unicode_isspace__Unicode(space, w_self): + return is_generic(space, w_self, unicodedb.isspace) -unicode_isspace__Unicode = make_generic("isspace") -unicode_isalpha__Unicode = make_generic("isalpha") -unicode_isalnum__Unicode = make_generic("isalnum") -unicode_isdecimal__Unicode = make_generic("isdecimal") -unicode_isdigit__Unicode = make_generic("isdigit") -unicode_isnumeric__Unicode = make_generic("isnumeric") +def unicode_isalpha__Unicode(space, w_self): + return is_generic(space, w_self, unicodedb.isalpha) + +def unicode_isalnum__Unicode(space, w_self): + return is_generic(space, w_self, unicodedb.isalnum) + +def unicode_isdecimal__Unicode(space, w_self): + return is_generic(space, w_self, unicodedb.isdecimal) + +def unicode_isdigit__Unicode(space, w_self): + return is_generic(space, w_self, unicodedb.isdigit) + +def unicode_isnumeric__Unicode(space, w_self): + return is_generic(space, w_self, unicodedb.isnumeric) def unicode_islower__Unicode(space, w_unicode): cased = False _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit