[Python-checkins] r55130 - python/branches/py3k-struni/Lib/pickle.py python/branches/py3k-struni/Lib/struct.py

guido.van.rossum python-checkins at python.org
Fri May 4 21:56:26 CEST 2007


Author: guido.van.rossum
Date: Fri May  4 21:56:22 2007
New Revision: 55130

Modified:
   python/branches/py3k-struni/Lib/pickle.py
   python/branches/py3k-struni/Lib/struct.py
Log:
Checkpoint.  Make pickle.py read/write bytes.
Fix strict.py so it reads/writes bytes and accepts both string types as format.


Modified: python/branches/py3k-struni/Lib/pickle.py
==============================================================================
--- python/branches/py3k-struni/Lib/pickle.py	(original)
+++ python/branches/py3k-struni/Lib/pickle.py	Fri May  4 21:56:22 2007
@@ -33,6 +33,7 @@
 import sys
 import struct
 import re
+import io
 
 __all__ = ["PickleError", "PicklingError", "UnpicklingError", "Pickler",
            "Unpickler", "dump", "dumps", "load", "loads"]
@@ -50,6 +51,9 @@
 # know how to read.
 HIGHEST_PROTOCOL = 2
 
+# The protocol we write by default.  May be less than HIGHEST_PROTOCOL.
+DEFAULT_PROTOCOL = 2
+
 # Why use struct.pack() for pickling but marshal.loads() for
 # unpickling?  struct.pack() is 40% faster than marshal.dumps(), but
 # marshal.loads() is twice as fast as struct.unpack()!
@@ -89,75 +93,69 @@
 except ImportError:
     PyStringMap = None
 
-# UnicodeType may or may not be exported (normally imported from types)
-try:
-    UnicodeType
-except NameError:
-    UnicodeType = None
-
 # Pickle opcodes.  See pickletools.py for extensive docs.  The listing
 # here is in kind-of alphabetical order of 1-character pickle code.
 # pickletools groups them by purpose.
 
-MARK            = '('   # push special markobject on stack
-STOP            = '.'   # every pickle ends with STOP
-POP             = '0'   # discard topmost stack item
-POP_MARK        = '1'   # discard stack top through topmost markobject
-DUP             = '2'   # duplicate top stack item
-FLOAT           = 'F'   # push float object; decimal string argument
-INT             = 'I'   # push integer or bool; decimal string argument
-BININT          = 'J'   # push four-byte signed int
-BININT1         = 'K'   # push 1-byte unsigned int
-LONG            = 'L'   # push long; decimal string argument
-BININT2         = 'M'   # push 2-byte unsigned int
-NONE            = 'N'   # push None
-PERSID          = 'P'   # push persistent object; id is taken from string arg
-BINPERSID       = 'Q'   #  "       "         "  ;  "  "   "     "  stack
-REDUCE          = 'R'   # apply callable to argtuple, both on stack
-STRING          = 'S'   # push string; NL-terminated string argument
-BINSTRING       = 'T'   # push string; counted binary string argument
-SHORT_BINSTRING = 'U'   #  "     "   ;    "      "       "      " < 256 bytes
-UNICODE         = 'V'   # push Unicode string; raw-unicode-escaped'd argument
-BINUNICODE      = 'X'   #   "     "       "  ; counted UTF-8 string argument
-APPEND          = 'a'   # append stack top to list below it
-BUILD           = 'b'   # call __setstate__ or __dict__.update()
-GLOBAL          = 'c'   # push self.find_class(modname, name); 2 string args
-DICT            = 'd'   # build a dict from stack items
-EMPTY_DICT      = '}'   # push empty dict
-APPENDS         = 'e'   # extend list on stack by topmost stack slice
-GET             = 'g'   # push item from memo on stack; index is string arg
-BINGET          = 'h'   #   "    "    "    "   "   "  ;   "    " 1-byte arg
-INST            = 'i'   # build & push class instance
-LONG_BINGET     = 'j'   # push item from memo on stack; index is 4-byte arg
-LIST            = 'l'   # build list from topmost stack items
-EMPTY_LIST      = ']'   # push empty list
-OBJ             = 'o'   # build & push class instance
-PUT             = 'p'   # store stack top in memo; index is string arg
-BINPUT          = 'q'   #   "     "    "   "   " ;   "    " 1-byte arg
-LONG_BINPUT     = 'r'   #   "     "    "   "   " ;   "    " 4-byte arg
-SETITEM         = 's'   # add key+value pair to dict
-TUPLE           = 't'   # build tuple from topmost stack items
-EMPTY_TUPLE     = ')'   # push empty tuple
-SETITEMS        = 'u'   # modify dict by adding topmost key+value pairs
-BINFLOAT        = 'G'   # push float; arg is 8-byte float encoding
+MARK           = b'('   # push special markobject on stack
+STOP           = b'.'   # every pickle ends with STOP
+POP            = b'0'   # discard topmost stack item
+POP_MARK       = b'1'   # discard stack top through topmost markobject
+DUP            = b'2'   # duplicate top stack item
+FLOAT          = b'F'   # push float object; decimal string argument
+INT            = b'I'   # push integer or bool; decimal string argument
+BININT         = b'J'   # push four-byte signed int
+BININT1        = b'K'   # push 1-byte unsigned int
+LONG           = b'L'   # push long; decimal string argument
+BININT2        = b'M'   # push 2-byte unsigned int
+NONE           = b'N'   # push None
+PERSID         = b'P'   # push persistent object; id is taken from string arg
+BINPERSID      = b'Q'   #  "       "         "  ;  "  "   "     "  stack
+REDUCE         = b'R'   # apply callable to argtuple, both on stack
+STRING         = b'S'   # push string; NL-terminated string argument
+BINSTRING      = b'T'   # push string; counted binary string argument
+SHORT_BINSTRING= b'U'   #  "     "   ;    "      "       "      " < 256 bytes
+UNICODE        = b'V'   # push Unicode string; raw-unicode-escaped'd argument
+BINUNICODE     = b'X'   #   "     "       "  ; counted UTF-8 string argument
+APPEND         = b'a'   # append stack top to list below it
+BUILD          = b'b'   # call __setstate__ or __dict__.update()
+GLOBAL         = b'c'   # push self.find_class(modname, name); 2 string args
+DICT           = b'd'   # build a dict from stack items
+EMPTY_DICT     = b'}'   # push empty dict
+APPENDS        = b'e'   # extend list on stack by topmost stack slice
+GET            = b'g'   # push item from memo on stack; index is string arg
+BINGET         = b'h'   #   "    "    "    "   "   "  ;   "    " 1-byte arg
+INST           = b'i'   # build & push class instance
+LONG_BINGET    = b'j'   # push item from memo on stack; index is 4-byte arg
+LIST           = b'l'   # build list from topmost stack items
+EMPTY_LIST     = b']'   # push empty list
+OBJ            = b'o'   # build & push class instance
+PUT            = b'p'   # store stack top in memo; index is string arg
+BINPUT         = b'q'   #   "     "    "   "   " ;   "    " 1-byte arg
+LONG_BINPUT    = b'r'   #   "     "    "   "   " ;   "    " 4-byte arg
+SETITEM        = b's'   # add key+value pair to dict
+TUPLE          = b't'   # build tuple from topmost stack items
+EMPTY_TUPLE    = b')'   # push empty tuple
+SETITEMS       = b'u'   # modify dict by adding topmost key+value pairs
+BINFLOAT       = b'G'   # push float; arg is 8-byte float encoding
 
-TRUE            = 'I01\n'  # not an opcode; see INT docs in pickletools.py
-FALSE           = 'I00\n'  # not an opcode; see INT docs in pickletools.py
+TRUE           = b'I01\n'  # not an opcode; see INT docs in pickletools.py
+FALSE          = b'I00\n'  # not an opcode; see INT docs in pickletools.py
 
 # Protocol 2
 
-PROTO           = '\x80'  # identify pickle protocol
-NEWOBJ          = '\x81'  # build object by applying cls.__new__ to argtuple
-EXT1            = '\x82'  # push object from extension registry; 1-byte index
-EXT2            = '\x83'  # ditto, but 2-byte index
-EXT4            = '\x84'  # ditto, but 4-byte index
-TUPLE1          = '\x85'  # build 1-tuple from stack top
-TUPLE2          = '\x86'  # build 2-tuple from two topmost stack items
-TUPLE3          = '\x87'  # build 3-tuple from three topmost stack items
-NEWTRUE         = '\x88'  # push True
-NEWFALSE        = '\x89'  # push False
-LONG1           = '\x8a'  # push long from < 256 bytes
-LONG4           = '\x8b'  # push really big long
+PROTO          = b'\x80'  # identify pickle protocol
+NEWOBJ         = b'\x81'  # build object by applying cls.__new__ to argtuple
+EXT1           = b'\x82'  # push object from extension registry; 1-byte index
+EXT2           = b'\x83'  # ditto, but 2-byte index
+EXT4           = b'\x84'  # ditto, but 4-byte index
+TUPLE1         = b'\x85'  # build 1-tuple from stack top
+TUPLE2         = b'\x86'  # build 2-tuple from two topmost stack items
+TUPLE3         = b'\x87'  # build 3-tuple from three topmost stack items
+NEWTRUE        = b'\x88'  # push True
+NEWFALSE       = b'\x89'  # push False
+LONG1          = b'\x8a'  # push long from < 256 bytes
+LONG4          = b'\x8b'  # push really big long
 
 _tuplesize2code = [EMPTY_TUPLE, TUPLE1, TUPLE2, TUPLE3]
 
@@ -170,15 +168,13 @@
 class Pickler:
 
     def __init__(self, file, protocol=None):
-        """This takes a file-like object for writing a pickle data stream.
+        """This takes a binary file for writing a pickle data stream.
+
+        All protocols now read and write bytes.
 
         The optional protocol argument tells the pickler to use the
         given protocol; supported protocols are 0, 1, 2.  The default
-        protocol is 0, to be backwards compatible.  (Protocol 0 is the
-        only protocol that can be written to a file opened in text
-        mode and read back successfully.  When using a protocol higher
-        than 0, make sure the file is opened in binary mode, both when
-        pickling and unpickling.)
+        protocol is 2; it's been supported for many years now.
 
         Protocol 1 is more efficient than protocol 0; protocol 2 is
         more efficient than protocol 1.
@@ -194,7 +190,7 @@
 
         """
         if protocol is None:
-            protocol = 0
+            protocol = DEFAULT_PROTOCOL
         if protocol < 0:
             protocol = HIGHEST_PROTOCOL
         elif not 0 <= protocol <= HIGHEST_PROTOCOL:
@@ -219,7 +215,7 @@
     def dump(self, obj):
         """Write a pickled representation of obj to the open file."""
         if self.proto >= 2:
-            self.write(PROTO + chr(self.proto))
+            self.write(PROTO + bytes([self.proto]))
         self.save(obj)
         self.write(STOP)
 
@@ -249,21 +245,21 @@
     def put(self, i, pack=struct.pack):
         if self.bin:
             if i < 256:
-                return BINPUT + chr(i)
+                return BINPUT + bytes([i])
             else:
                 return LONG_BINPUT + pack("<i", i)
 
-        return PUT + repr(i) + '\n'
+        return PUT + bytes(repr(i)) + b'\n'
 
     # Return a GET (BINGET, LONG_BINGET) opcode string, with argument i.
     def get(self, i, pack=struct.pack):
         if self.bin:
             if i < 256:
-                return BINGET + chr(i)
+                return BINGET + bytes([i])
             else:
                 return LONG_BINGET + pack("<i", i)
 
-        return GET + repr(i) + '\n'
+        return GET + bytes(repr(i)) + b'\n'
 
     def save(self, obj):
         # Check for persistent id (defined by a subclass)
@@ -312,7 +308,7 @@
                                         (t.__name__, obj))
 
         # Check for string returned by reduce(), meaning "save as global"
-        if type(rv) is StringType:
+        if inistance(rv, basestring):
             self.save_global(obj, rv)
             return
 
@@ -339,7 +335,7 @@
             self.save(pid)
             self.write(BINPERSID)
         else:
-            self.write(PERSID + str(pid) + '\n')
+            self.write(PERSID + bytes(str(pid)) + b'\n')
 
     def save_reduce(self, func, args, state=None,
                     listitems=None, dictitems=None, obj=None):
@@ -441,10 +437,10 @@
             # First one- and two-byte unsigned ints:
             if obj >= 0:
                 if obj <= 0xff:
-                    self.write(BININT1 + chr(obj))
+                    self.write(BININT1 + bytes([obj]))
                     return
                 if obj <= 0xffff:
-                    self.write("%c%c%c" % (BININT2, obj&0xff, obj>>8))
+                    self.write(BININT2 + bytes([obj&0xff, obj>>8]))
                     return
             # Next check for 4-byte signed ints:
             high_bits = obj >> 31  # note that Python shift sign-extends
@@ -454,7 +450,7 @@
                 self.write(BININT + pack("<i", obj))
                 return
         # Text pickle, or int too big to fit in signed 4-byte format.
-        self.write(INT + repr(obj) + '\n')
+        self.write(INT + bytes(repr(obj)) + b'\n')
     # XXX save_int is merged into save_long
     # dispatch[IntType] = save_int
 
@@ -466,10 +462,10 @@
             # First one- and two-byte unsigned ints:
             if obj >= 0:
                 if obj <= 0xff:
-                    self.write(BININT1 + chr(obj))
+                    self.write(BININT1 + bytes([obj]))
                     return
                 if obj <= 0xffff:
-                    self.write("%c%c%c" % (BININT2, obj&0xff, obj>>8))
+                    self.write(BININT2, bytes([obj&0xff, obj>>8]))
                     return
             # Next check for 4-byte signed ints:
             high_bits = obj >> 31  # note that Python shift sign-extends
@@ -479,74 +475,46 @@
                 self.write(BININT + pack("<i", obj))
                 return
         if self.proto >= 2:
-            bytes = encode_long(obj)
-            n = len(bytes)
+            encoded = encode_long(obj)
+            n = len(encoded)
             if n < 256:
-                self.write(LONG1 + chr(n) + bytes)
+                self.write(LONG1 + bytes([n]) + encoded)
             else:
-                self.write(LONG4 + pack("<i", n) + bytes)
+                self.write(LONG4 + pack("<i", n) + encoded)
             return
-        self.write(LONG + repr(obj) + '\n')
+        self.write(LONG + bytes(repr(obj)) + b'\n')
     dispatch[LongType] = save_long
 
     def save_float(self, obj, pack=struct.pack):
         if self.bin:
             self.write(BINFLOAT + pack('>d', obj))
         else:
-            self.write(FLOAT + repr(obj) + '\n')
+            self.write(FLOAT + bytes(repr(obj)) + b'\n')
     dispatch[FloatType] = save_float
 
     def save_string(self, obj, pack=struct.pack):
         if self.bin:
             n = len(obj)
             if n < 256:
-                self.write(SHORT_BINSTRING + chr(n) + obj)
+                self.write(SHORT_BINSTRING + bytes([n]) + bytes(obj))
             else:
-                self.write(BINSTRING + pack("<i", n) + obj)
+                self.write(BINSTRING + pack("<i", n) + bytes(obj))
         else:
-            self.write(STRING + repr(obj) + '\n')
+            self.write(STRING + bytes(repr(obj)) + b'\n')
         self.memoize(obj)
-    dispatch[StringType] = save_string
+    dispatch[str8] = save_string
 
     def save_unicode(self, obj, pack=struct.pack):
         if self.bin:
-            encoding = obj.encode('utf-8')
-            n = len(encoding)
-            self.write(BINUNICODE + pack("<i", n) + encoding)
+            encoded = obj.encode('utf-8')
+            n = len(encoded)
+            self.write(BINUNICODE + pack("<i", n) + encoded)
         else:
             obj = obj.replace("\\", "\\u005c")
             obj = obj.replace("\n", "\\u000a")
-            self.write(UNICODE + obj.encode('raw-unicode-escape') + '\n')
+            self.write(UNICODE + obj.encode('raw-unicode-escape') + 'b\n')
         self.memoize(obj)
-    dispatch[UnicodeType] = save_unicode
-
-    if StringType == UnicodeType:
-        # This is true for Jython
-        def save_string(self, obj, pack=struct.pack):
-            str = obj.isunicode()
-
-            if self.bin:
-                if str:
-                    obj = obj.encode("utf-8")
-                l = len(obj)
-                if l < 256 and not str:
-                    self.write(SHORT_BINSTRING + chr(l) + obj)
-                else:
-                    s = pack("<i", l)
-                    if str:
-                        self.write(BINUNICODE + s + obj)
-                    else:
-                        self.write(BINSTRING + s + obj)
-            else:
-                if str:
-                    obj = obj.replace("\\", "\\u005c")
-                    obj = obj.replace("\n", "\\u000a")
-                    obj = obj.encode('raw-unicode-escape')
-                    self.write(UNICODE + obj + '\n')
-                else:
-                    self.write(STRING + repr(obj) + '\n')
-            self.memoize(obj)
-        dispatch[StringType] = save_string
+    dispatch[str] = save_unicode
 
     def save_tuple(self, obj):
         write = self.write
@@ -736,14 +704,14 @@
             if code:
                 assert code > 0
                 if code <= 0xff:
-                    write(EXT1 + chr(code))
+                    write(EXT1 + bytes([code]))
                 elif code <= 0xffff:
-                    write("%c%c%c" % (EXT2, code&0xff, code>>8))
+                    write(EXT2 + bytes([code&0xff, code>>8]))
                 else:
                     write(EXT4 + pack("<i", code))
                 return
 
-        write(GLOBAL + module + '\n' + name + '\n')
+        write(GLOBAL + bytes(module) + b'\n' + bytes(name) + b'\n')
         self.memoize(obj)
 
     dispatch[ClassType] = save_global
@@ -806,7 +774,7 @@
 class Unpickler:
 
     def __init__(self, file):
-        """This takes a file-like object for reading a pickle data stream.
+        """This takes a binary file for reading a pickle data stream.
 
         The protocol version of the pickle is detected automatically, so no
         proto argument is needed.
@@ -817,10 +785,25 @@
         object can be a file object opened for reading, a StringIO object,
         or any other custom object that meets this interface.
         """
-        self.readline = file.readline
+        try:
+            self.readline = file.readline
+        except AttributeError:
+            self.file = file
         self.read = file.read
         self.memo = {}
 
+    def readline(self):
+        # XXX Slow but at least correct
+        b = bytes()
+        while True:
+            c = self.file.read(1)
+            if not c:
+                break
+            b += c
+            if c == b'\n':
+                break
+        return b
+
     def load(self):
         """Read a pickled object representation from the open file.
 
@@ -834,7 +817,9 @@
         try:
             while 1:
                 key = read(1)
-                dispatch[key](self)
+                if not key:
+                    raise EOFError
+                dispatch[key[0]](self)
         except _Stop as stopinst:
             return stopinst.value
 
@@ -855,37 +840,33 @@
 
     dispatch = {}
 
-    def load_eof(self):
-        raise EOFError
-    dispatch[''] = load_eof
-
     def load_proto(self):
         proto = ord(self.read(1))
         if not 0 <= proto <= 2:
             raise ValueError, "unsupported pickle protocol: %d" % proto
-    dispatch[PROTO] = load_proto
+    dispatch[PROTO[0]] = load_proto
 
     def load_persid(self):
         pid = self.readline()[:-1]
         self.append(self.persistent_load(pid))
-    dispatch[PERSID] = load_persid
+    dispatch[PERSID[0]] = load_persid
 
     def load_binpersid(self):
         pid = self.stack.pop()
         self.append(self.persistent_load(pid))
-    dispatch[BINPERSID] = load_binpersid
+    dispatch[BINPERSID[0]] = load_binpersid
 
     def load_none(self):
         self.append(None)
-    dispatch[NONE] = load_none
+    dispatch[NONE[0]] = load_none
 
     def load_false(self):
         self.append(False)
-    dispatch[NEWFALSE] = load_false
+    dispatch[NEWFALSE[0]] = load_false
 
     def load_true(self):
         self.append(True)
-    dispatch[NEWTRUE] = load_true
+    dispatch[NEWTRUE[0]] = load_true
 
     def load_int(self):
         data = self.readline()
@@ -899,43 +880,43 @@
             except ValueError:
                 val = int(data)
         self.append(val)
-    dispatch[INT] = load_int
+    dispatch[INT[0]] = load_int
 
     def load_binint(self):
-        self.append(mloads('i' + self.read(4)))
-    dispatch[BININT] = load_binint
+        self.append(mloads(b'i' + self.read(4)))
+    dispatch[BININT[0]] = load_binint
 
     def load_binint1(self):
         self.append(ord(self.read(1)))
-    dispatch[BININT1] = load_binint1
+    dispatch[BININT1[0]] = load_binint1
 
     def load_binint2(self):
-        self.append(mloads('i' + self.read(2) + '\000\000'))
-    dispatch[BININT2] = load_binint2
+        self.append(mloads(b'i' + self.read(2) + '\000\000'))
+    dispatch[BININT2[0]] = load_binint2
 
     def load_long(self):
         self.append(int(self.readline()[:-1], 0))
-    dispatch[LONG] = load_long
+    dispatch[LONG[0]] = load_long
 
     def load_long1(self):
         n = ord(self.read(1))
-        bytes = self.read(n)
-        self.append(decode_long(bytes))
-    dispatch[LONG1] = load_long1
+        data = self.read(n)
+        self.append(decode_long(data))
+    dispatch[LONG1[0]] = load_long1
 
     def load_long4(self):
-        n = mloads('i' + self.read(4))
-        bytes = self.read(n)
-        self.append(decode_long(bytes))
-    dispatch[LONG4] = load_long4
+        n = mloads(b'i' + self.read(4))
+        data = self.read(n)
+        self.append(decode_long(data))
+    dispatch[LONG4[0]] = load_long4
 
     def load_float(self):
         self.append(float(self.readline()[:-1]))
-    dispatch[FLOAT] = load_float
+    dispatch[FLOAT[0]] = load_float
 
     def load_binfloat(self, unpack=struct.unpack):
         self.append(unpack('>d', self.read(8))[0])
-    dispatch[BINFLOAT] = load_binfloat
+    dispatch[BINFLOAT[0]] = load_binfloat
 
     def load_string(self):
         rep = self.readline()[:-1]
@@ -948,60 +929,60 @@
         else:
             raise ValueError, "insecure string pickle"
         self.append(rep.decode("string-escape"))
-    dispatch[STRING] = load_string
+    dispatch[STRING[0]] = load_string
 
     def load_binstring(self):
-        len = mloads('i' + self.read(4))
+        len = mloads(b'i' + self.read(4))
         self.append(self.read(len))
-    dispatch[BINSTRING] = load_binstring
+    dispatch[BINSTRING[0]] = load_binstring
 
     def load_unicode(self):
-        self.append(str(self.readline()[:-1],'raw-unicode-escape'))
-    dispatch[UNICODE] = load_unicode
+        self.append(str(self.readline()[:-1], 'raw-unicode-escape'))
+    dispatch[UNICODE[0]] = load_unicode
 
     def load_binunicode(self):
-        len = mloads('i' + self.read(4))
-        self.append(str(self.read(len),'utf-8'))
-    dispatch[BINUNICODE] = load_binunicode
+        len = mloads(b'i' + self.read(4))
+        self.append(str(self.read(len), 'utf-8'))
+    dispatch[BINUNICODE[0]] = load_binunicode
 
     def load_short_binstring(self):
         len = ord(self.read(1))
         self.append(self.read(len))
-    dispatch[SHORT_BINSTRING] = load_short_binstring
+    dispatch[SHORT_BINSTRING[0]] = load_short_binstring
 
     def load_tuple(self):
         k = self.marker()
         self.stack[k:] = [tuple(self.stack[k+1:])]
-    dispatch[TUPLE] = load_tuple
+    dispatch[TUPLE[0]] = load_tuple
 
     def load_empty_tuple(self):
         self.stack.append(())
-    dispatch[EMPTY_TUPLE] = load_empty_tuple
+    dispatch[EMPTY_TUPLE[0]] = load_empty_tuple
 
     def load_tuple1(self):
         self.stack[-1] = (self.stack[-1],)
-    dispatch[TUPLE1] = load_tuple1
+    dispatch[TUPLE1[0]] = load_tuple1
 
     def load_tuple2(self):
         self.stack[-2:] = [(self.stack[-2], self.stack[-1])]
-    dispatch[TUPLE2] = load_tuple2
+    dispatch[TUPLE2[0]] = load_tuple2
 
     def load_tuple3(self):
         self.stack[-3:] = [(self.stack[-3], self.stack[-2], self.stack[-1])]
-    dispatch[TUPLE3] = load_tuple3
+    dispatch[TUPLE3[0]] = load_tuple3
 
     def load_empty_list(self):
         self.stack.append([])
-    dispatch[EMPTY_LIST] = load_empty_list
+    dispatch[EMPTY_LIST[0]] = load_empty_list
 
     def load_empty_dictionary(self):
         self.stack.append({})
-    dispatch[EMPTY_DICT] = load_empty_dictionary
+    dispatch[EMPTY_DICT[0]] = load_empty_dictionary
 
     def load_list(self):
         k = self.marker()
         self.stack[k:] = [self.stack[k+1:]]
-    dispatch[LIST] = load_list
+    dispatch[LIST[0]] = load_list
 
     def load_dict(self):
         k = self.marker()
@@ -1012,7 +993,7 @@
             value = items[i+1]
             d[key] = value
         self.stack[k:] = [d]
-    dispatch[DICT] = load_dict
+    dispatch[DICT[0]] = load_dict
 
     # INST and OBJ differ only in how they get a class object.  It's not
     # only sensible to do the rest in a common routine, the two routines
@@ -1047,43 +1028,43 @@
         name = self.readline()[:-1]
         klass = self.find_class(module, name)
         self._instantiate(klass, self.marker())
-    dispatch[INST] = load_inst
+    dispatch[INST[0]] = load_inst
 
     def load_obj(self):
         # Stack is ... markobject classobject arg1 arg2 ...
         k = self.marker()
         klass = self.stack.pop(k+1)
         self._instantiate(klass, k)
-    dispatch[OBJ] = load_obj
+    dispatch[OBJ[0]] = load_obj
 
     def load_newobj(self):
         args = self.stack.pop()
         cls = self.stack[-1]
         obj = cls.__new__(cls, *args)
         self.stack[-1] = obj
-    dispatch[NEWOBJ] = load_newobj
+    dispatch[NEWOBJ[0]] = load_newobj
 
     def load_global(self):
         module = self.readline()[:-1]
         name = self.readline()[:-1]
         klass = self.find_class(module, name)
         self.append(klass)
-    dispatch[GLOBAL] = load_global
+    dispatch[GLOBAL[0]] = load_global
 
     def load_ext1(self):
         code = ord(self.read(1))
         self.get_extension(code)
-    dispatch[EXT1] = load_ext1
+    dispatch[EXT1[0]] = load_ext1
 
     def load_ext2(self):
-        code = mloads('i' + self.read(2) + '\000\000')
+        code = mloads(b'i' + self.read(2) + b'\000\000')
         self.get_extension(code)
-    dispatch[EXT2] = load_ext2
+    dispatch[EXT2[0]] = load_ext2
 
     def load_ext4(self):
-        code = mloads('i' + self.read(4))
+        code = mloads(b'i' + self.read(4))
         self.get_extension(code)
-    dispatch[EXT4] = load_ext4
+    dispatch[EXT4[0]] = load_ext4
 
     def get_extension(self, code):
         nil = []
@@ -1111,55 +1092,55 @@
         func = stack[-1]
         value = func(*args)
         stack[-1] = value
-    dispatch[REDUCE] = load_reduce
+    dispatch[REDUCE[0]] = load_reduce
 
     def load_pop(self):
         del self.stack[-1]
-    dispatch[POP] = load_pop
+    dispatch[POP[0]] = load_pop
 
     def load_pop_mark(self):
         k = self.marker()
         del self.stack[k:]
-    dispatch[POP_MARK] = load_pop_mark
+    dispatch[POP_MARK[0]] = load_pop_mark
 
     def load_dup(self):
         self.append(self.stack[-1])
-    dispatch[DUP] = load_dup
+    dispatch[DUP[0]] = load_dup
 
     def load_get(self):
         self.append(self.memo[self.readline()[:-1]])
-    dispatch[GET] = load_get
+    dispatch[GET[0]] = load_get
 
     def load_binget(self):
         i = ord(self.read(1))
         self.append(self.memo[repr(i)])
-    dispatch[BINGET] = load_binget
+    dispatch[BINGET[0]] = load_binget
 
     def load_long_binget(self):
-        i = mloads('i' + self.read(4))
+        i = mloads(b'i' + self.read(4))
         self.append(self.memo[repr(i)])
-    dispatch[LONG_BINGET] = load_long_binget
+    dispatch[LONG_BINGET[0]] = load_long_binget
 
     def load_put(self):
         self.memo[self.readline()[:-1]] = self.stack[-1]
-    dispatch[PUT] = load_put
+    dispatch[PUT[0]] = load_put
 
     def load_binput(self):
         i = ord(self.read(1))
         self.memo[repr(i)] = self.stack[-1]
-    dispatch[BINPUT] = load_binput
+    dispatch[BINPUT[0]] = load_binput
 
     def load_long_binput(self):
-        i = mloads('i' + self.read(4))
+        i = mloads(b'i' + self.read(4))
         self.memo[repr(i)] = self.stack[-1]
-    dispatch[LONG_BINPUT] = load_long_binput
+    dispatch[LONG_BINPUT[0]] = load_long_binput
 
     def load_append(self):
         stack = self.stack
         value = stack.pop()
         list = stack[-1]
         list.append(value)
-    dispatch[APPEND] = load_append
+    dispatch[APPEND[0]] = load_append
 
     def load_appends(self):
         stack = self.stack
@@ -1167,7 +1148,7 @@
         list = stack[mark - 1]
         list.extend(stack[mark + 1:])
         del stack[mark:]
-    dispatch[APPENDS] = load_appends
+    dispatch[APPENDS[0]] = load_appends
 
     def load_setitem(self):
         stack = self.stack
@@ -1175,7 +1156,7 @@
         key = stack.pop()
         dict = stack[-1]
         dict[key] = value
-    dispatch[SETITEM] = load_setitem
+    dispatch[SETITEM[0]] = load_setitem
 
     def load_setitems(self):
         stack = self.stack
@@ -1185,7 +1166,7 @@
             dict[stack[i]] = stack[i + 1]
 
         del stack[mark:]
-    dispatch[SETITEMS] = load_setitems
+    dispatch[SETITEMS[0]] = load_setitems
 
     def load_build(self):
         stack = self.stack
@@ -1216,16 +1197,16 @@
         if slotstate:
             for k, v in slotstate.items():
                 setattr(inst, k, v)
-    dispatch[BUILD] = load_build
+    dispatch[BUILD[0]] = load_build
 
     def load_mark(self):
         self.append(self.mark)
-    dispatch[MARK] = load_mark
+    dispatch[MARK[0]] = load_mark
 
     def load_stop(self):
         value = self.stack.pop()
         raise _Stop(value)
-    dispatch[STOP] = load_stop
+    dispatch[STOP[0]] = load_stop
 
 # Helper class for load_inst/load_obj
 
@@ -1332,16 +1313,11 @@
 
 # Shorthands
 
-try:
-    from cStringIO import StringIO
-except ImportError:
-    from StringIO import StringIO
-
 def dump(obj, file, protocol=None):
     Pickler(file, protocol).dump(obj)
 
 def dumps(obj, protocol=None):
-    file = StringIO()
+    file = io.BytesIO()
     Pickler(file, protocol).dump(obj)
     return file.getvalue()
 
@@ -1349,7 +1325,7 @@
     return Unpickler(file).load()
 
 def loads(str):
-    file = StringIO(str)
+    file = io.BytesIO(str)
     return Unpickler(file).load()
 
 # Doctest

Modified: python/branches/py3k-struni/Lib/struct.py
==============================================================================
--- python/branches/py3k-struni/Lib/struct.py	(original)
+++ python/branches/py3k-struni/Lib/struct.py	Fri May  4 21:56:22 2007
@@ -25,7 +25,11 @@
 
 The variable struct.error is an exception raised on errors.
 """
-__version__ = '0.1'
+
+# XXX Move the bytes and str8 casts into the _struct module
+
+__version__ = '3.0'
+
 
 from _struct import Struct, error
 
@@ -36,7 +40,7 @@
     # Internal: compile struct pattern
     if len(_cache) >= _MAXCACHE:
         _cache.clear()
-    s = Struct(fmt)
+    s = Struct(str8(fmt))
     _cache[fmt] = s
     return s
 
@@ -60,7 +64,7 @@
         o = _cache[fmt]
     except KeyError:
         o = _compile(fmt)
-    return o.pack(*args)
+    return bytes(o.pack(*args))
 
 def pack_into(fmt, buf, offset, *args):
     """
@@ -72,7 +76,7 @@
         o = _cache[fmt]
     except KeyError:
         o = _compile(fmt)
-    return o.pack_into(buf, offset, *args)
+    return bytes(o.pack_into(buf, offset, *args))
 
 def unpack(fmt, s):
     """


More information about the Python-checkins mailing list