Rename all variables 'object' to 'obj' to avoid conflicts with the

type 'object'.  Also minor docstring tweakage, and rearranged a few
lines in save().
This commit is contained in:
Guido van Rossum 2003-01-28 15:10:22 +00:00
parent 570283584a
commit 3a41c61dd4
1 changed files with 113 additions and 112 deletions

View File

@ -196,8 +196,8 @@ class Pickler:
""" """
self.memo.clear() self.memo.clear()
def dump(self, object): def dump(self, obj):
"""Write a pickled representation of object to the open file object. """Write a pickled representation of obj to the open file.
Either the binary or ASCII format will be used, depending on the Either the binary or ASCII format will be used, depending on the
value of the bin flag passed to the constructor. value of the bin flag passed to the constructor.
@ -205,7 +205,7 @@ class Pickler:
""" """
if self.proto >= 2: if self.proto >= 2:
self.write(PROTO + chr(self.proto)) self.write(PROTO + chr(self.proto))
self.save(object) self.save(obj)
self.write(STOP) self.write(STOP)
def memoize(self, obj): def memoize(self, obj):
@ -247,28 +247,25 @@ class Pickler:
return GET + `i` + '\n' return GET + `i` + '\n'
def save(self, object): def save(self, obj):
memo = self.memo pid = self.persistent_id(obj)
pid = self.persistent_id(object)
if pid is not None: if pid is not None:
self.save_pers(pid) self.save_pers(pid)
return return
d = id(object) memo = self.memo
d = id(obj)
t = type(object)
if d in memo: if d in memo:
self.write(self.get(memo[d][0])) self.write(self.get(memo[d][0]))
return return
t = type(obj)
try: try:
f = self.dispatch[t] f = self.dispatch[t]
except KeyError: except KeyError:
pass pass
else: else:
f(self, object) f(self, obj)
return return
# The dispatch table doesn't know about type t. # The dispatch table doesn't know about type t.
@ -277,25 +274,25 @@ class Pickler:
except TypeError: # t is not a class except TypeError: # t is not a class
issc = 0 issc = 0
if issc: if issc:
self.save_global(object) self.save_global(obj)
return return
try: try:
reduce = dispatch_table[t] reduce = dispatch_table[t]
except KeyError: except KeyError:
try: try:
reduce = object.__reduce__ reduce = obj.__reduce__
except AttributeError: except AttributeError:
raise PicklingError, \ raise PicklingError, \
"can't pickle %s object: %s" % (`t.__name__`, "can't pickle %s object: %s" % (`t.__name__`,
`object`) `obj`)
else: else:
tup = reduce() tup = reduce()
else: else:
tup = reduce(object) tup = reduce(obj)
if type(tup) is StringType: if type(tup) is StringType:
self.save_global(object, tup) self.save_global(obj, tup)
return return
if type(tup) is not TupleType: if type(tup) is not TupleType:
@ -321,9 +318,9 @@ class Pickler:
"by %s must be a tuple" % reduce "by %s must be a tuple" % reduce
self.save_reduce(callable, arg_tup, state) self.save_reduce(callable, arg_tup, state)
self.memoize(object) self.memoize(obj)
def persistent_id(self, object): def persistent_id(self, obj):
return None return None
def save_pers(self, pid): def save_pers(self, pid):
@ -351,116 +348,116 @@ class Pickler:
dispatch = {} dispatch = {}
def save_none(self, object): def save_none(self, obj):
self.write(NONE) self.write(NONE)
dispatch[NoneType] = save_none dispatch[NoneType] = save_none
def save_bool(self, object): def save_bool(self, obj):
if self.proto >= 2: if self.proto >= 2:
self.write(object and NEWTRUE or NEWFALSE) self.write(obj and NEWTRUE or NEWFALSE)
else: else:
self.write(object and TRUE or FALSE) self.write(obj and TRUE or FALSE)
dispatch[bool] = save_bool dispatch[bool] = save_bool
def save_int(self, object, pack=struct.pack): def save_int(self, obj, pack=struct.pack):
if self.bin: if self.bin:
# If the int is small enough to fit in a signed 4-byte 2's-comp # If the int is small enough to fit in a signed 4-byte 2's-comp
# format, we can store it more efficiently than the general # format, we can store it more efficiently than the general
# case. # case.
# First one- and two-byte unsigned ints: # First one- and two-byte unsigned ints:
if object >= 0: if obj >= 0:
if object <= 0xff: if obj <= 0xff:
self.write(BININT1 + chr(object)) self.write(BININT1 + chr(obj))
return return
if object <= 0xffff: if obj <= 0xffff:
self.write(BININT2 + chr(object&0xff) + chr(object>>8)) self.write(BININT2 + chr(obj&0xff) + chr(obj>>8))
return return
# Next check for 4-byte signed ints: # Next check for 4-byte signed ints:
high_bits = object >> 31 # note that Python shift sign-extends high_bits = obj >> 31 # note that Python shift sign-extends
if high_bits == 0 or high_bits == -1: if high_bits == 0 or high_bits == -1:
# All high bits are copies of bit 2**31, so the value # All high bits are copies of bit 2**31, so the value
# fits in a 4-byte signed int. # fits in a 4-byte signed int.
self.write(BININT + pack("<i", object)) self.write(BININT + pack("<i", obj))
return return
# Text pickle, or int too big to fit in signed 4-byte format. # Text pickle, or int too big to fit in signed 4-byte format.
self.write(INT + `object` + '\n') self.write(INT + `obj` + '\n')
dispatch[IntType] = save_int dispatch[IntType] = save_int
def save_long(self, object, pack=struct.pack): def save_long(self, obj, pack=struct.pack):
if self.proto >= 2: if self.proto >= 2:
bytes = encode_long(object) bytes = encode_long(obj)
n = len(bytes) n = len(bytes)
if n < 256: if n < 256:
self.write(LONG1 + chr(n) + bytes) self.write(LONG1 + chr(n) + bytes)
else: else:
self.write(LONG4 + pack("<i", n) + bytes) self.write(LONG4 + pack("<i", n) + bytes)
self.write(LONG + `object` + '\n') self.write(LONG + `obj` + '\n')
dispatch[LongType] = save_long dispatch[LongType] = save_long
def save_float(self, object, pack=struct.pack): def save_float(self, obj, pack=struct.pack):
if self.bin: if self.bin:
self.write(BINFLOAT + pack('>d', object)) self.write(BINFLOAT + pack('>d', obj))
else: else:
self.write(FLOAT + `object` + '\n') self.write(FLOAT + `obj` + '\n')
dispatch[FloatType] = save_float dispatch[FloatType] = save_float
def save_string(self, object, pack=struct.pack): def save_string(self, obj, pack=struct.pack):
if self.bin: if self.bin:
n = len(object) n = len(obj)
if n < 256: if n < 256:
self.write(SHORT_BINSTRING + chr(n) + object) self.write(SHORT_BINSTRING + chr(n) + obj)
else: else:
self.write(BINSTRING + pack("<i", n) + object) self.write(BINSTRING + pack("<i", n) + obj)
else: else:
self.write(STRING + `object` + '\n') self.write(STRING + `obj` + '\n')
self.memoize(object) self.memoize(obj)
dispatch[StringType] = save_string dispatch[StringType] = save_string
def save_unicode(self, object, pack=struct.pack): def save_unicode(self, obj, pack=struct.pack):
if self.bin: if self.bin:
encoding = object.encode('utf-8') encoding = obj.encode('utf-8')
n = len(encoding) n = len(encoding)
self.write(BINUNICODE + pack("<i", n) + encoding) self.write(BINUNICODE + pack("<i", n) + encoding)
else: else:
object = object.replace("\\", "\\u005c") obj = obj.replace("\\", "\\u005c")
object = object.replace("\n", "\\u000a") obj = obj.replace("\n", "\\u000a")
self.write(UNICODE + object.encode('raw-unicode-escape') + '\n') self.write(UNICODE + obj.encode('raw-unicode-escape') + '\n')
self.memoize(object) self.memoize(obj)
dispatch[UnicodeType] = save_unicode dispatch[UnicodeType] = save_unicode
if StringType == UnicodeType: if StringType == UnicodeType:
# This is true for Jython # This is true for Jython
def save_string(self, object, pack=struct.pack): def save_string(self, obj, pack=struct.pack):
unicode = object.isunicode() unicode = obj.isunicode()
if self.bin: if self.bin:
if unicode: if unicode:
object = object.encode("utf-8") obj = obj.encode("utf-8")
l = len(object) l = len(obj)
if l < 256 and not unicode: if l < 256 and not unicode:
self.write(SHORT_BINSTRING + chr(l) + object) self.write(SHORT_BINSTRING + chr(l) + obj)
else: else:
s = pack("<i", l) s = pack("<i", l)
if unicode: if unicode:
self.write(BINUNICODE + s + object) self.write(BINUNICODE + s + obj)
else: else:
self.write(BINSTRING + s + object) self.write(BINSTRING + s + obj)
else: else:
if unicode: if unicode:
object = object.replace("\\", "\\u005c") obj = obj.replace("\\", "\\u005c")
object = object.replace("\n", "\\u000a") obj = obj.replace("\n", "\\u000a")
object = object.encode('raw-unicode-escape') obj = obj.encode('raw-unicode-escape')
self.write(UNICODE + object + '\n') self.write(UNICODE + obj + '\n')
else: else:
self.write(STRING + `object` + '\n') self.write(STRING + `obj` + '\n')
self.memoize(object) self.memoize(obj)
dispatch[StringType] = save_string dispatch[StringType] = save_string
def save_tuple(self, object): def save_tuple(self, obj):
write = self.write write = self.write
proto = self.proto proto = self.proto
n = len(object) n = len(obj)
if n == 0 and proto: if n == 0 and proto:
write(EMPTY_TUPLE) write(EMPTY_TUPLE)
return return
@ -468,24 +465,24 @@ class Pickler:
save = self.save save = self.save
memo = self.memo memo = self.memo
if n <= 3 and proto >= 2: if n <= 3 and proto >= 2:
for element in object: for element in obj:
save(element) save(element)
# Subtle. Same as in the big comment below. # Subtle. Same as in the big comment below.
if id(object) in memo: if id(obj) in memo:
get = self.get(memo[id(object)][0]) get = self.get(memo[id(obj)][0])
write(POP * n + get) write(POP * n + get)
else: else:
write(_tuplesize2code[n]) write(_tuplesize2code[n])
self.memoize(object) self.memoize(obj)
return return
# proto 0, or proto 1 and tuple isn't empty, or proto > 1 and tuple # proto 0, or proto 1 and tuple isn't empty, or proto > 1 and tuple
# has more than 3 elements. # has more than 3 elements.
write(MARK) write(MARK)
for element in object: for element in obj:
save(element) save(element)
if n and id(object) in memo: if n and id(obj) in memo:
# Subtle. d was not in memo when we entered save_tuple(), so # Subtle. d was not in memo when we entered save_tuple(), so
# the process of saving the tuple's elements must have saved # the process of saving the tuple's elements must have saved
# the tuple itself: the tuple is recursive. The proper action # the tuple itself: the tuple is recursive. The proper action
@ -493,7 +490,7 @@ class Pickler:
# simply GET the tuple (it's already constructed). This check # simply GET the tuple (it's already constructed). This check
# could have been done in the "for element" loop instead, but # could have been done in the "for element" loop instead, but
# recursive tuples are a rare thing. # recursive tuples are a rare thing.
get = self.get(memo[id(object)][0]) get = self.get(memo[id(obj)][0])
if proto: if proto:
write(POP_MARK + get) write(POP_MARK + get)
else: # proto 0 -- POP_MARK not available else: # proto 0 -- POP_MARK not available
@ -502,51 +499,51 @@ class Pickler:
# No recursion (including the empty-tuple case for protocol 0). # No recursion (including the empty-tuple case for protocol 0).
self.write(TUPLE) self.write(TUPLE)
if object: # No need to memoize empty tuple if obj: # No need to memoize empty tuple
self.memoize(object) self.memoize(obj)
dispatch[TupleType] = save_tuple dispatch[TupleType] = save_tuple
def save_empty_tuple(self, object): def save_empty_tuple(self, obj):
self.write(EMPTY_TUPLE) self.write(EMPTY_TUPLE)
def save_list(self, object): def save_list(self, obj):
write = self.write write = self.write
save = self.save save = self.save
if self.bin: if self.bin:
write(EMPTY_LIST) write(EMPTY_LIST)
self.memoize(object) self.memoize(obj)
n = len(object) n = len(obj)
if n > 1: if n > 1:
write(MARK) write(MARK)
for element in object: for element in obj:
save(element) save(element)
write(APPENDS) write(APPENDS)
elif n: elif n:
assert n == 1 assert n == 1
save(object[0]) save(obj[0])
write(APPEND) write(APPEND)
# else the list is empty, and we're already done # else the list is empty, and we're already done
else: # proto 0 -- can't use EMPTY_LIST or APPENDS else: # proto 0 -- can't use EMPTY_LIST or APPENDS
write(MARK + LIST) write(MARK + LIST)
self.memoize(object) self.memoize(obj)
for element in object: for element in obj:
save(element) save(element)
write(APPEND) write(APPEND)
dispatch[ListType] = save_list dispatch[ListType] = save_list
def save_dict(self, object): def save_dict(self, obj):
write = self.write write = self.write
save = self.save save = self.save
items = object.iteritems() items = obj.iteritems()
if self.bin: if self.bin:
write(EMPTY_DICT) write(EMPTY_DICT)
self.memoize(object) self.memoize(obj)
if len(object) > 1: if len(obj) > 1:
write(MARK) write(MARK)
for key, value in items: for key, value in items:
save(key) save(key)
@ -556,9 +553,9 @@ class Pickler:
else: # proto 0 -- can't use EMPTY_DICT or SETITEMS else: # proto 0 -- can't use EMPTY_DICT or SETITEMS
write(MARK + DICT) write(MARK + DICT)
self.memoize(object) self.memoize(obj)
# proto 0 or len(object) < 2 # proto 0 or len(obj) < 2
for key, value in items: for key, value in items:
save(key) save(key)
save(value) save(value)
@ -568,15 +565,15 @@ class Pickler:
if not PyStringMap is None: if not PyStringMap is None:
dispatch[PyStringMap] = save_dict dispatch[PyStringMap] = save_dict
def save_inst(self, object): def save_inst(self, obj):
cls = object.__class__ cls = obj.__class__
memo = self.memo memo = self.memo
write = self.write write = self.write
save = self.save save = self.save
if hasattr(object, '__getinitargs__'): if hasattr(obj, '__getinitargs__'):
args = object.__getinitargs__() args = obj.__getinitargs__()
len(args) # XXX Assert it's a sequence len(args) # XXX Assert it's a sequence
_keep_alive(args, memo) _keep_alive(args, memo)
else: else:
@ -594,12 +591,12 @@ class Pickler:
save(arg) save(arg)
write(INST + cls.__module__ + '\n' + cls.__name__ + '\n') write(INST + cls.__module__ + '\n' + cls.__name__ + '\n')
self.memoize(object) self.memoize(obj)
try: try:
getstate = object.__getstate__ getstate = obj.__getstate__
except AttributeError: except AttributeError:
stuff = object.__dict__ stuff = obj.__dict__
else: else:
stuff = getstate() stuff = getstate()
_keep_alive(stuff, memo) _keep_alive(stuff, memo)
@ -608,17 +605,17 @@ class Pickler:
dispatch[InstanceType] = save_inst dispatch[InstanceType] = save_inst
def save_global(self, object, name = None): def save_global(self, obj, name = None):
write = self.write write = self.write
memo = self.memo memo = self.memo
if name is None: if name is None:
name = object.__name__ name = obj.__name__
try: try:
module = object.__module__ module = obj.__module__
except AttributeError: except AttributeError:
module = whichmodule(object, name) module = whichmodule(obj, name)
try: try:
__import__(module) __import__(module)
@ -627,15 +624,15 @@ class Pickler:
except (ImportError, KeyError, AttributeError): except (ImportError, KeyError, AttributeError):
raise PicklingError( raise PicklingError(
"Can't pickle %r: it's not found as %s.%s" % "Can't pickle %r: it's not found as %s.%s" %
(object, module, name)) (obj, module, name))
else: else:
if klass is not object: if klass is not obj:
raise PicklingError( raise PicklingError(
"Can't pickle %r: it's not the same object as %s.%s" % "Can't pickle %r: it's not the same object as %s.%s" %
(object, module, name)) (obj, module, name))
write(GLOBAL + module + '\n' + name + '\n') write(GLOBAL + module + '\n' + name + '\n')
self.memoize(object) self.memoize(obj)
dispatch[ClassType] = save_global dispatch[ClassType] = save_global
dispatch[FunctionType] = save_global dispatch[FunctionType] = save_global
@ -700,18 +697,15 @@ class Unpickler:
arguments. Both methods should return a string. Thus file-like arguments. Both methods should return a string. Thus file-like
object can be a file object opened for reading, a StringIO object, object can be a file object opened for reading, a StringIO object,
or any other custom object that meets this interface. or any other custom object that meets this interface.
""" """
self.readline = file.readline self.readline = file.readline
self.read = file.read self.read = file.read
self.memo = {} self.memo = {}
def load(self): def load(self):
"""Read a pickled object representation from the open file object. """Read a pickled object representation from the open file.
Return the reconstituted object hierarchy specified in the file
object.
Return the reconstituted object hierarchy specified in the file.
""" """
self.mark = object() # any new unique object self.mark = object() # any new unique object
self.stack = [] self.stack = []
@ -991,6 +985,13 @@ class Unpickler:
self.append(value) self.append(value)
dispatch[OBJ] = load_obj dispatch[OBJ] = 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
def load_global(self): def load_global(self):
module = self.readline()[:-1] module = self.readline()[:-1]
name = self.readline()[:-1] name = self.readline()[:-1]
@ -1197,12 +1198,12 @@ try:
except ImportError: except ImportError:
from StringIO import StringIO from StringIO import StringIO
def dump(object, file, proto=1): def dump(obj, file, proto=1):
Pickler(file, proto).dump(object) Pickler(file, proto).dump(obj)
def dumps(object, proto=1): def dumps(obj, proto=1):
file = StringIO() file = StringIO()
Pickler(file, proto).dump(object) Pickler(file, proto).dump(obj)
return file.getvalue() return file.getvalue()
def load(file): def load(file):