[pypy-commit] pypy py3k: Port p3k diffs in defunct strutil.py to the rpython/ directory.

amauryfa noreply at buildbot.pypy.org
Sat Jun 29 18:29:52 CEST 2013


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: py3k
Changeset: r65100:2ab06d170d6f
Date: 2013-06-29 18:29 +0200
http://bitbucket.org/pypy/pypy/changeset/2ab06d170d6f/

Log:	Port p3k diffs in defunct strutil.py to the rpython/ directory.

	Yes, I know this is wrong, but:

	- it's a branch!

	- this is the fastest way to have a working py3k after the branch
	merge, so that other people can work on other parts.

	- I will remove those differences in rpython/, at least we start
	from a stable interpreter.

	- some pieces of code that were moved to rpython/ are specific to
	python2, like the 'L' suffix, and the 'long' type in error
	messages.

diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py
--- a/rpython/rlib/rarithmetic.py
+++ b/rpython/rlib/rarithmetic.py
@@ -673,6 +673,7 @@
 # String parsing support
 # ---------------------------
 
+ at objectmodel.enforceargs(unicode, None)
 def string_to_int(s, base=10):
     """Utility to converts a string to an integer.
     If base is 0, the proper base is guessed based on the leading
@@ -683,7 +684,7 @@
         ParseStringOverflowError, \
         ParseStringError, strip_spaces
     s = literal = strip_spaces(s)
-    p = NumberStringParser(s, literal, base, 'int')
+    p = NumberStringParser(s, literal, base, u'int')
     base = p.base
     result = 0
     while True:
diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py
--- a/rpython/rlib/rbigint.py
+++ b/rpython/rlib/rbigint.py
@@ -4,7 +4,7 @@
 from rpython.rlib.rfloat import isinf, isnan
 from rpython.rlib.rstring import StringBuilder
 from rpython.rlib.debug import make_sure_not_resized, check_regular_int
-from rpython.rlib.objectmodel import we_are_translated, specialize
+from rpython.rlib.objectmodel import we_are_translated, specialize, enforceargs
 from rpython.rlib import jit
 from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.rtyper import extregistry
@@ -254,16 +254,13 @@
 
     @staticmethod
     @jit.elidable
+    @enforceargs(unicode, None)
     def fromstr(s, base=0):
-        """As string_to_int(), but ignores an optional 'l' or 'L' suffix
-        and returns an rbigint."""
+        """As string_to_int(), but returns an rbigint."""
         from rpython.rlib.rstring import NumberStringParser, \
             strip_spaces
         s = literal = strip_spaces(s)
-        if (s.endswith('l') or s.endswith('L')) and base < 22:
-            # in base 22 and above, 'L' is a valid digit!  try: long('L',22)
-            s = s[:-1]
-        parser = NumberStringParser(s, literal, base, 'long')
+        parser = NumberStringParser(s, literal, base, u'int')
         return rbigint._from_numberstring_parser(parser)
 
     @staticmethod
diff --git a/rpython/rlib/rfloat.py b/rpython/rlib/rfloat.py
--- a/rpython/rlib/rfloat.py
+++ b/rpython/rlib/rfloat.py
@@ -27,6 +27,7 @@
 
 globals().update(rffi_platform.configure(CConfig))
 
+ at objectmodel.enforceargs(unicode)
 def string_to_float(s):
     """
     Conversion of string to float.
@@ -40,10 +41,25 @@
     s = strip_spaces(s)
 
     if not s:
-        raise ParseStringError("empty string for float()")
+        raise ParseStringError(u"empty string for float()")
 
 
-    low = s.lower()
+    try:
+        ascii_s = s.encode('ascii')
+    except UnicodeEncodeError:
+        # if s is not ASCII, it certainly is not a float literal (because the
+        # unicode-decimal to ascii-decimal conversion already happened
+        # earlier). We just set ascii_s to something which will fail when
+        # passed to rstring_to_float, to keep the code as similar as possible
+        # to the one we have on default.
+        #
+        # Note that CPython does something different and it encodes the string
+        # to UTF-8 before trying to parse it. We cannot since .encode('utf-8')
+        # is not RPython. However, it doesn't change anything since the UTF-8
+        # encoded string would make rstring_to_float to fail anyway.
+        ascii_s = "not a float"
+
+    low = ascii_s.lower()
     if low == "-inf" or low == "-infinity":
         return -INFINITY
     elif low == "inf" or low == "+inf":
@@ -56,9 +72,11 @@
         return -NAN
 
     try:
-        return rstring_to_float(s)
+        return rstring_to_float(ascii_s)
     except ValueError:
-        raise ParseStringError("invalid literal for float(): '%s'" % s)
+        # note that we still put the original unicode string in the error
+        # message, not ascii_s
+        raise ParseStringError(u"invalid literal for float(): '%s'" % s)
 
 def rstring_to_float(s):
     return rstring_to_float_impl(s)
diff --git a/rpython/rlib/rstring.py b/rpython/rlib/rstring.py
--- a/rpython/rlib/rstring.py
+++ b/rpython/rlib/rstring.py
@@ -4,10 +4,11 @@
 
 from rpython.annotator.model import (SomeObject, SomeString, s_None, SomeChar,
     SomeInteger, SomeUnicodeCodePoint, SomeUnicodeString, SomePtr, SomePBC)
-from rpython.rlib.objectmodel import newlist_hint, specialize
+from rpython.rlib.objectmodel import newlist_hint, specialize, enforceargs
 from rpython.rlib.rarithmetic import ovfcheck
 from rpython.rtyper.extregistry import ExtRegistryEntry
 from rpython.tool.pairtype import pairtype
+from rpython.tool.sourcetools import with_unicode_literals
 from rpython.rlib import jit
 
 
@@ -188,6 +189,8 @@
 
 # -------------- numeric parsing support --------------------
 
+ at enforceargs(unicode)
+ at with_unicode_literals
 def strip_spaces(s):
     # XXX this is not locale-dependent
     p = 0
@@ -200,6 +203,7 @@
     return s[p:q]
 
 class ParseStringError(Exception):
+    @enforceargs(None, unicode)
     def __init__(self, msg):
         self.msg = msg
 
@@ -211,9 +215,11 @@
 class NumberStringParser:
 
     def error(self):
-        raise ParseStringError("invalid literal for %s() with base %d: '%s'" %
+        raise ParseStringError(u"invalid literal for %s() with base %d: '%s'" %
                                (self.fname, self.original_base, self.literal))
 
+    @enforceargs(None, unicode, unicode, int, unicode)
+    @with_unicode_literals
     def __init__(self, s, literal, base, fname):
         self.literal = literal
         self.fname = fname
@@ -236,7 +242,7 @@
             else:
                 base = 10
         elif base < 2 or base > 36:
-            raise ParseStringError, "%s() base must be >= 2 and <= 36" % (fname,)
+            raise ParseStringError, u"%s() base must be >= 2 and <= 36" % (fname,)
         self.base = base
 
         if base == 16 and (s.startswith('0x') or s.startswith('0X')):
@@ -254,6 +260,7 @@
     def rewind(self):
         self.i = 0
 
+    @with_unicode_literals
     def next_digit(self): # -1 => exhausted
         if self.i < self.n:
             c = self.s[self.i]


More information about the pypy-commit mailing list