[pypy-commit] pypy SomeString-charclass: Progress, add AsciiChar kind.
amauryfa
noreply at buildbot.pypy.org
Tue Jul 15 15:43:46 CEST 2014
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: SomeString-charclass
Changeset: r72438:58e84b592e0a
Date: 2014-07-13 20:12 +0200
http://bitbucket.org/pypy/pypy/changeset/58e84b592e0a/
Log: Progress, add AsciiChar kind.
diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py
--- a/rpython/annotator/model.py
+++ b/rpython/annotator/model.py
@@ -220,7 +220,10 @@
# Character classes.
class AnyChar(object):
+ """A character of any value."""
no_nul = False
+ is_ascii = False
+
_instances = {}
def __new__(cls):
@@ -244,6 +247,9 @@
AnyChar._register()
class NoNulChar(AnyChar):
+ """Any character except NUL '\0'.
+ Strings of this kind can be converted to char* with no loss."""
+
no_nul = True
def union(self, other):
@@ -253,13 +259,35 @@
return AnyChar()
NoNulChar._register()
-AsciiChar = AnyChar # So far
+class AsciiChar(NoNulChar):
+ """A character in the range(1, 128).
+
+ Strings of this kind can be decoded faster to unicode."""
+
+ is_ascii = True
+
+ def union(self, other):
+ if other.is_ascii:
+ return self
+ elif other.no_nul:
+ return NoNulChar()
+ else:
+ return AnyChar()
+AsciiChar._register()
+
def charkind_from_const(value):
+ try:
+ value.decode('ascii')
+ except UnicodeDecodeError:
+ pass
+ else:
+ return AsciiChar()
if '\x00' not in value:
return NoNulChar()
return AnyChar()
+
class SomeStringOrUnicode(SomeObject):
"""Base class for shared implementation of SomeString,
SomeUnicodeString and SomeByteArray.
@@ -284,14 +312,16 @@
return self.can_be_None
def nonnoneify(self):
- return self.__class__(can_be_None=False,
- charkind=self.charkind)
+ return self.basestringclass(can_be_None=False, charkind=self.charkind)
+
+ def noneify(self):
+ return self.basestringclass(can_be_None=True, charkind=self.charkind)
def nonnulify(self):
- if self.charkind == NoNulChar():
- charkind = NoNulChar()
- elif self.charkind == AnyChar():
- charkind = NoNulChar()
+ if self.charkind.no_nul:
+ return self
+ assert type(self.charkind) is AnyChar # so far the only one.
+ charkind = NoNulChar()
return self.__class__(can_be_None=self.can_be_None, charkind=charkind)
@@ -299,17 +329,11 @@
"Stands for an object which is known to be a string."
knowntype = str
- def noneify(self):
- return SomeString(can_be_None=True, charkind=self.charkind)
-
class SomeUnicodeString(SomeStringOrUnicode):
"Stands for an object which is known to be an unicode string"
knowntype = unicode
- def noneify(self):
- return SomeUnicodeString(can_be_None=True, charkind=self.charkind)
-
class SomeByteArray(SomeStringOrUnicode):
immutable = False
diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py
--- a/rpython/annotator/unaryop.py
+++ b/rpython/annotator/unaryop.py
@@ -487,7 +487,7 @@
def method_split(self, patt, max=-1):
if max == -1 and patt.is_constant() and patt.const == "\0":
- charkind = NoNulChar
+ charkind = NoNulChar()
else:
charkind = self.charkind
s_item = self.basestringclass(charkind=charkind)
diff --git a/rpython/rlib/rstring.py b/rpython/rlib/rstring.py
--- a/rpython/rlib/rstring.py
+++ b/rpython/rlib/rstring.py
@@ -523,15 +523,9 @@
_about_ = assert_str0
def compute_result_annotation(self, s_obj):
- if s_None.contains(s_obj):
+ if s_None.contains(s_obj): # probably a future str_or_None
return s_obj
- assert isinstance(s_obj, (SomeString, SomeUnicodeString))
- if s_obj.charkind.no_nul:
- return s_obj
- new_s_obj = SomeObject.__new__(s_obj.__class__)
- new_s_obj.__dict__ = s_obj.__dict__.copy()
- new_s_obj.charkind = NoNulChar()
- return new_s_obj
+ return s_obj.nonnulify()
def specialize_call(self, hop):
hop.exception_cannot_occur()
More information about the pypy-commit
mailing list