Author: Philip Jenvey <[email protected]>
Branch: py3k-stdlib-2.7.6-merge
Changeset: r69877:d9272670e477
Date: 2014-03-11 16:55 -0700
http://bitbucket.org/pypy/pypy/changeset/d9272670e477/

Log:    merge py3k

diff --git a/lib-python/3/datetime.py b/lib-python/3/datetime.py
--- a/lib-python/3/datetime.py
+++ b/lib-python/3/datetime.py
@@ -333,7 +333,7 @@
     Representation: (days, seconds, microseconds).  Why?  Because I
     felt like it.
     """
-    __slots__ = '_days', '_seconds', '_microseconds'
+    __slots__ = '_days', '_seconds', '_microseconds', '_hashcode'
 
     def __new__(cls, days=0, seconds=0, microseconds=0,
                 milliseconds=0, minutes=0, hours=0, weeks=0):
@@ -426,14 +426,14 @@
         assert isinstance(s, int) and 0 <= s < 24*3600
         assert isinstance(us, int) and 0 <= us < 1000000
 
+        if abs(d) > 999999999:
+            raise OverflowError("timedelta # of days is too large: %d" % d)
+
         self = object.__new__(cls)
-
         self._days = d
         self._seconds = s
         self._microseconds = us
-        if abs(d) > 999999999:
-            raise OverflowError("timedelta # of days is too large: %d" % d)
-
+        self._hashcode = -1
         return self
 
     def __repr__(self):
@@ -617,7 +617,9 @@
         return _cmp(self._getstate(), other._getstate())
 
     def __hash__(self):
-        return hash(self._getstate())
+        if self._hashcode == -1:
+            self._hashcode = hash(self._getstate())
+        return self._hashcode
 
     def __bool__(self):
         return (self._days != 0 or
@@ -665,7 +667,7 @@
     Properties (readonly):
     year, month, day
     """
-    __slots__ = '_year', '_month', '_day'
+    __slots__ = '_year', '_month', '_day', '_hashcode'
 
     def __new__(cls, year, month=None, day=None):
         """Constructor.
@@ -679,12 +681,14 @@
             # Pickle support
             self = object.__new__(cls)
             self.__setstate(year)
+            self._hashcode = -1
             return self
         year, month, day = _check_date_fields(year, month, day)
         self = object.__new__(cls)
         self._year = year
         self._month = month
         self._day = day
+        self._hashcode = -1
         return self
 
     # Additional constructors
@@ -847,7 +851,9 @@
 
     def __hash__(self):
         "Hash."
-        return hash(self._getstate())
+        if self._hashcode == -1:
+            self._hashcode = hash(self._getstate())
+        return self._hashcode
 
     # Computations
 
@@ -1022,7 +1028,7 @@
     Properties (readonly):
     hour, minute, second, microsecond, tzinfo
     """
-    __slots__ = '_hour', '_minute', '_second', '_microsecond', '_tzinfo'
+    __slots__ = '_hour', '_minute', '_second', '_microsecond', '_tzinfo', 
'_hashcode'
 
     def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None):
         """Constructor.
@@ -1037,6 +1043,7 @@
             # Pickle support
             self = object.__new__(cls)
             self.__setstate(hour, minute or None)
+            self._hashcode = -1
             return self
         hour, minute, second, microsecond = _check_time_fields(
             hour, minute, second, microsecond)
@@ -1047,6 +1054,7 @@
         self._second = second
         self._microsecond = microsecond
         self._tzinfo = tzinfo
+        self._hashcode = -1
         return self
 
     # Read-only field accessors
@@ -1142,16 +1150,20 @@
 
     def __hash__(self):
         """Hash."""
-        tzoff = self.utcoffset()
-        if not tzoff:  # zero or None
-            return hash(self._getstate()[0])
-        h, m = divmod(timedelta(hours=self.hour, minutes=self.minute) - tzoff,
-                      timedelta(hours=1))
-        assert not m % timedelta(minutes=1), "whole minute"
-        m //= timedelta(minutes=1)
-        if 0 <= h < 24:
-            return hash(time(h, m, self.second, self.microsecond))
-        return hash((h, m, self.second, self.microsecond))
+        if self._hashcode == -1:
+            tzoff = self.utcoffset()
+            if not tzoff:  # zero or None
+                self._hashcode = hash(self._getstate()[0])
+            else:
+                h, m = divmod(timedelta(hours=self.hour, minutes=self.minute) 
- tzoff,
+                              timedelta(hours=1))
+                assert not m % timedelta(minutes=1), "whole minute"
+                m //= timedelta(minutes=1)
+                if 0 <= h < 24:
+                    self._hashcode = hash(time(h, m, self.second, 
self.microsecond))
+                else:
+                    self._hashcode = hash((h, m, self.second, 
self.microsecond))
+        return self._hashcode
 
     # Conversion to string
 
@@ -1292,12 +1304,11 @@
             return (basestate, self._tzinfo)
 
     def __setstate(self, string, tzinfo):
+        if tzinfo is not None and not isinstance(tzinfo, _tzinfo_class):
+            raise TypeError("bad tzinfo state arg")
         self._hour, self._minute, self._second, us1, us2, us3 = string
         self._microsecond = (((us1 << 8) | us2) << 8) | us3
-        if tzinfo is None or isinstance(tzinfo, _tzinfo_class):
-            self._tzinfo = tzinfo
-        else:
-            raise TypeError("bad tzinfo state arg")
+        self._tzinfo = tzinfo
 
     def __reduce__(self):
         return (time, self._getstate())
@@ -1320,8 +1331,9 @@
                 microsecond=0, tzinfo=None):
         if isinstance(year, bytes) and len(year) == 10 and 1 <= year[2] <= 12:
             # Pickle support
-            self = date.__new__(cls, year[:4])
+            self = object.__new__(cls)
             self.__setstate(year, month)
+            self._hashcode = -1
             return self
         year, month, day = _check_date_fields(year, month, day)
         hour, minute, second, microsecond = _check_time_fields(
@@ -1336,6 +1348,7 @@
         self._second = second
         self._microsecond = microsecond
         self._tzinfo = tzinfo
+        self._hashcode = -1
         return self
 
     # Read-only field accessors
@@ -1736,12 +1749,15 @@
         return base + otoff - myoff
 
     def __hash__(self):
-        tzoff = self.utcoffset()
-        if tzoff is None:
-            return hash(self._getstate()[0])
-        days = _ymd2ord(self.year, self.month, self.day)
-        seconds = self.hour * 3600 + self.minute * 60 + self.second
-        return hash(timedelta(days, seconds, self.microsecond) - tzoff)
+        if self._hashcode == -1:
+            tzoff = self.utcoffset()
+            if tzoff is None:
+                self._hashcode = hash(self._getstate()[0])
+            else:
+                days = _ymd2ord(self.year, self.month, self.day)
+                seconds = self.hour * 3600 + self.minute * 60 + self.second
+                self._hashcode = hash(timedelta(days, seconds, 
self.microsecond) - tzoff)
+        return self._hashcode
 
     # Pickle support.
 
@@ -1758,14 +1774,13 @@
             return (basestate, self._tzinfo)
 
     def __setstate(self, string, tzinfo):
+        if tzinfo is not None and not isinstance(tzinfo, _tzinfo_class):
+            raise TypeError("bad tzinfo state arg")
         (yhi, ylo, self._month, self._day, self._hour,
          self._minute, self._second, us1, us2, us3) = string
         self._year = yhi * 256 + ylo
         self._microsecond = (((us1 << 8) | us2) << 8) | us3
-        if tzinfo is None or isinstance(tzinfo, _tzinfo_class):
-            self._tzinfo = tzinfo
-        else:
-            raise TypeError("bad tzinfo state arg")
+        self._tzinfo = tzinfo
 
     def __reduce__(self):
         return (self.__class__, self._getstate())
diff --git a/pypy/interpreter/pyparser/dfa_generated.py 
b/pypy/interpreter/pyparser/dfa_generated.py
--- a/pypy/interpreter/pyparser/dfa_generated.py
+++ b/pypy/interpreter/pyparser/dfa_generated.py
@@ -27,7 +27,7 @@
      'I': 1, 'J': 1, 'K': 1, 'L': 1,
      'M': 1, 'N': 1, 'O': 1, 'P': 1,
      'Q': 1, 'R': 3, 'S': 1, 'T': 1,
-     'U': 1, 'V': 1, 'W': 1, 'X': 1,
+     'U': 3, 'V': 1, 'W': 1, 'X': 1,
      'Y': 1, 'Z': 1, '[': 14, '\\': 18,
      ']': 14, '^': 13, '_': 1, '`': 14,
      'a': 1, 'b': 2, 'c': 1, 'd': 1,
@@ -35,7 +35,7 @@
      'i': 1, 'j': 1, 'k': 1, 'l': 1,
      'm': 1, 'n': 1, 'o': 1, 'p': 1,
      'q': 1, 'r': 3, 's': 1, 't': 1,
-     'u': 1, 'v': 1, 'w': 1, 'x': 1,
+     'u': 3, 'v': 1, 'w': 1, 'x': 1,
      'y': 1, 'z': 1, '{': 14, '|': 13,
      '}': 14, '~': 14, '\x80': 1},
     # 1
diff --git a/pypy/interpreter/pyparser/gendfa.py 
b/pypy/interpreter/pyparser/gendfa.py
--- a/pypy/interpreter/pyparser/gendfa.py
+++ b/pypy/interpreter/pyparser/gendfa.py
@@ -149,9 +149,11 @@
     funny = group(states, operator, bracket, special)
     # ____________________________________________________________
     def makeStrPrefix ():
-        return chain(states,
-                     maybe(states, groupStr(states, "bB")),
-                     maybe(states, groupStr(states, "rR")))
+        return group(states,
+                     chain(states,
+                           maybe(states, groupStr(states, "bB")),
+                           maybe(states, groupStr(states, "rR"))),
+                     maybe(states, groupStr(states, "uU")))
     # ____________________________________________________________
     contStr = group(states,
                     chain(states,
diff --git a/pypy/interpreter/pyparser/parsestring.py 
b/pypy/interpreter/pyparser/parsestring.py
--- a/pypy/interpreter/pyparser/parsestring.py
+++ b/pypy/interpreter/pyparser/parsestring.py
@@ -22,13 +22,18 @@
     quote = s[ps]
     rawmode = False
     unicode_literal = True
+    saw_u = False
 
     # string decoration handling
     if quote == 'b' or quote == 'B':
         ps += 1
         quote = s[ps]
         unicode_literal = False
-    if quote == 'r' or quote == 'R':
+    elif quote == 'u' or quote == 'U':
+        ps += 1
+        quote = s[ps]
+        saw_u = True
+    if not saw_u and quote == 'r' or quote == 'R':
         ps += 1
         quote = s[ps]
         rawmode = True
diff --git a/pypy/interpreter/pyparser/pytokenize.py 
b/pypy/interpreter/pyparser/pytokenize.py
--- a/pypy/interpreter/pyparser/pytokenize.py
+++ b/pypy/interpreter/pyparser/pytokenize.py
@@ -25,6 +25,8 @@
            '"' : doubleDFA,
            'r' : None,
            'R' : None,
+           "u" : None,
+           "U" : None,
            'b' : None,
            'B' : None}
 
@@ -33,6 +35,8 @@
         prefix = uniPrefix + rawPrefix
         endDFAs[prefix + "'''"] = single3DFA
         endDFAs[prefix + '"""'] = double3DFA
+endDFAs["u'''"] = single3DFA
+endDFAs['U"""'] = double3DFA
 
 whiteSpaceStatesAccepts = [True]
 whiteSpaceStates = [{'\t': 0, ' ': 0, '\x0c': 0}]
@@ -44,6 +48,7 @@
 triple_quoted = {}
 for t in ("'''", '"""',
           "r'''", 'r"""', "R'''", 'R"""',
+          "u'''", 'u"""', "U'''", 'U"""',
           "b'''", 'b"""', "B'''", 'B"""',
           "br'''", 'br"""', "Br'''", 'Br"""',
           "bR'''", 'bR"""', "BR'''", 'BR"""'):
@@ -51,6 +56,7 @@
 single_quoted = {}
 for t in ("'", '"',
           "r'", 'r"', "R'", 'R"',
+          "u'", 'u"', "U'", 'U"',
           "b'", 'b"', "B'", 'B"',
           "br'", 'br"', "Br'", 'Br"',
           "bR'", 'bR"', "BR'", 'BR"'):
diff --git a/pypy/interpreter/pyparser/test/test_parsestring.py 
b/pypy/interpreter/pyparser/test/test_parsestring.py
--- a/pypy/interpreter/pyparser/test/test_parsestring.py
+++ b/pypy/interpreter/pyparser/test/test_parsestring.py
@@ -62,6 +62,19 @@
         ret = space.unwrap(w_ret)
         assert ret == eval("# -*- coding: koi8-u -*-\nu'\x81'")
 
+    def test_unicode_pep414(self):
+        space = self.space
+        for s in [u'hello world', u'hello\n world']:
+            self.parse_and_compare(repr(s), unicode(s))
+
+        self.parse_and_compare("u'''hello\\x42 world'''",
+                               u'hello\x42 world')
+        self.parse_and_compare("u'''hello\\u0842 world'''",
+                               u'hello\u0842 world')
+
+        space.raises_w(space.w_ValueError,
+                       parsestring.parsestr, space, None, "ur'foo'")
+
     def test_unicode_literals(self):
         space = self.space
         w_ret = parsestring.parsestr(space, None, repr("hello"))
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to