Author: Matti Picus <matti.pi...@gmail.com> Branch: py3.6 Changeset: r97317:1b696e1a6058 Date: 2019-08-28 09:50 +0300 http://bitbucket.org/pypy/pypy/changeset/1b696e1a6058/
Log: merge default into py3.6 diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -2225,9 +2225,12 @@ _sigcheck.space = space return space.newbytes(rurandom.urandom(context, size, _signal_checker)) except OSError as e: - # 'rurandom' should catch and retry internally if it gets EINTR - # (at least in os.read(), which is probably enough in practice) - raise wrap_oserror(space, e, eintr_retry=False) + # CPython raises NotImplementedError if /dev/urandom cannot be found. + # To maximize compatibility, we should also raise NotImplementedError + # and not OSError (although CPython also raises OSError in case it + # could open /dev/urandom but there are further problems). + raise wrap_oserror(space, e, + w_exception_class=space.w_NotImplementedError, einter_retry=False) def ctermid(space): """ctermid() -> string diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py --- a/rpython/rlib/rarithmetic.py +++ b/rpython/rlib/rarithmetic.py @@ -878,9 +878,8 @@ Raises ParseStringOverflowError in case the result does not fit. """ from rpython.rlib.rstring import ( - NumberStringParser, ParseStringOverflowError, strip_spaces) - s = literal = strip_spaces(s) - p = NumberStringParser(s, literal, base, 'int', + NumberStringParser, ParseStringOverflowError) + p = NumberStringParser(s, s, base, 'int', allow_underscores=allow_underscores, no_implicit_octal=no_implicit_octal) base = p.base diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py --- a/rpython/rlib/rbigint.py +++ b/rpython/rlib/rbigint.py @@ -298,12 +298,14 @@ and returns an rbigint.""" from rpython.rlib.rstring import NumberStringParser, \ strip_spaces - s = literal = strip_spaces(s) + s = literal = strip_spaces(s) # XXX could get rid of this slice + end = len(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] + end -= 1 parser = NumberStringParser(s, literal, base, 'long', - allow_underscores=allow_underscores) + allow_underscores=allow_underscores, + end=end) return rbigint._from_numberstring_parser(parser) @staticmethod diff --git a/rpython/rlib/rstring.py b/rpython/rlib/rstring.py --- a/rpython/rlib/rstring.py +++ b/rpython/rlib/rstring.py @@ -500,26 +500,34 @@ (self.fname, self.original_base)) def __init__(self, s, literal, base, fname, allow_underscores=False, - no_implicit_octal=False): + no_implicit_octal=False, start=0, end=-1): self.fname = fname sign = 1 - if s.startswith('-'): + self.s = s + self.start = start + if end == -1: + end = len(s) + self.end = end + self._strip_spaces() + if self._startswith('-'): sign = -1 - s = strip_spaces(s[1:]) - elif s.startswith('+'): - s = strip_spaces(s[1:]) + self.start += 1 + self._strip_spaces() + elif self._startswith('+'): + self.start += 1 + self._strip_spaces() self.sign = sign self.original_base = base self.allow_underscores = allow_underscores if base == 0: - if s.startswith('0x') or s.startswith('0X'): + if self._startswith('0x') or self._startswith('0X'): base = 16 - elif s.startswith('0b') or s.startswith('0B'): + elif self._startswith('0b') or self._startswith('0B'): base = 2 - elif s.startswith('0'): # also covers the '0o' case - if no_implicit_octal and not (s.startswith('0o') or - s.startswith('0O')): + elif self._startswith('0'): # also covers the '0o' case + if no_implicit_octal and not (self._startswith('0o') or + self._startswith('0O')): base = 1 # this makes only the digit '0' valid... else: base = 8 @@ -530,30 +538,44 @@ self.base = base # Leading underscores are not allowed - if s.startswith('_'): + if self._startswith('_'): self.error() - if base == 16 and (s.startswith('0x') or s.startswith('0X')): - s = s[2:] - if base == 8 and (s.startswith('0o') or s.startswith('0O')): - s = s[2:] - if base == 2 and (s.startswith('0b') or s.startswith('0B')): - s = s[2:] - if not s: + if base == 16 and (self._startswith('0x') or self._startswith('0X')): + self.start += 2 + if base == 8 and (self._startswith('0o') or self._startswith('0O')): + self.start += 2 + if base == 2 and (self._startswith('0b') or self._startswith('0B')): + self.start += 2 + if self.start == self.end: self.error() - self.s = s - self.n = len(s) - self.i = 0 + self.i = self.start + + def _startswith(self, prefix): + return startswith(self.s, prefix, start=self.start, end=self.end) + + def _strip_spaces(self): + # XXX this is not locale-dependent + p = self.start + q = self.end + s = self.s + while p < q and s[p] in ' \f\n\r\t\v': + p += 1 + while p < q and s[q-1] in ' \f\n\r\t\v': + q -= 1 + assert q >= p + self.start = p + self.end = q def rewind(self): - self.i = 0 + self.i = self.start def next_digit(self): # -1 => exhausted - if self.i < self.n: + if self.i < self.end: c = self.s[self.i] if self.allow_underscores and c == '_': self.i += 1 - if self.i >= self.n: + if self.i >= self.end: self.error() c = self.s[self.i] digit = ord(c) @@ -576,7 +598,7 @@ # After exhausting all n digits in next_digit(), you can walk them # again in reverse order by calling prev_digit() exactly n times i = self.i - 1 - assert i >= 0 + assert i >= self.start self.i = i c = self.s[i] if self.allow_underscores and c == '_': diff --git a/rpython/rlib/test/test_rarithmetic.py b/rpython/rlib/test/test_rarithmetic.py --- a/rpython/rlib/test/test_rarithmetic.py +++ b/rpython/rlib/test/test_rarithmetic.py @@ -337,6 +337,10 @@ res = self.interpret(f, [123]) assert res == 4 + 2 + def test_string_to_int_translates(self): + def f(s): + return string_to_int(str(s)) + self.interpret(f, [123]) == 123 def test_int_real_union(): from rpython.rtyper.lltypesystem.rffi import r_int_real diff --git a/rpython/rlib/test/test_rbigint.py b/rpython/rlib/test/test_rbigint.py --- a/rpython/rlib/test/test_rbigint.py +++ b/rpython/rlib/test/test_rbigint.py @@ -356,6 +356,29 @@ assert rbigint.fromstr('123L', 21).tolong() == 441 + 42 + 3 assert rbigint.fromstr('1891234174197319').tolong() == 1891234174197319 + def test__from_numberstring_parser_rewind_bug(self): + from rpython.rlib.rstring import NumberStringParser + s = "-99" + p = NumberStringParser(s, s, 10, 'int') + assert p.sign == -1 + res = p.next_digit() + assert res == 9 + res = p.next_digit() + assert res == 9 + res = p.next_digit() + assert res == -1 + p.rewind() + res = p.next_digit() + assert res == 9 + res = p.next_digit() + assert res == 9 + res = p.next_digit() + assert res == -1 + + @given(longs) + def test_fromstr_hypothesis(self, l): + assert rbigint.fromstr(str(l)).tolong() == l + def test_from_numberstring_parser(self): from rpython.rlib.rstring import NumberStringParser parser = NumberStringParser("1231231241", "1231231241", 10, "long") _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit