Edit File by line
/home/barbar84/www/wp-conte.../plugins/sujqvwi/AnonR/smanonr..../lib64/python3....
File: pickle.py
# The use of the Unpickler memo length as the memo key is just a
[500] Fix | Delete
# convention. The only requirement is that the memo values be unique.
[501] Fix | Delete
# But there appears no advantage to any other scheme, and this
[502] Fix | Delete
# scheme allows the Unpickler memo to be implemented as a plain (but
[503] Fix | Delete
# growable) array, indexed by memo key.
[504] Fix | Delete
if self.fast:
[505] Fix | Delete
return
[506] Fix | Delete
assert id(obj) not in self.memo
[507] Fix | Delete
idx = len(self.memo)
[508] Fix | Delete
self.write(self.put(idx))
[509] Fix | Delete
self.memo[id(obj)] = idx, obj
[510] Fix | Delete
[511] Fix | Delete
# Return a PUT (BINPUT, LONG_BINPUT) opcode string, with argument i.
[512] Fix | Delete
def put(self, idx):
[513] Fix | Delete
if self.proto >= 4:
[514] Fix | Delete
return MEMOIZE
[515] Fix | Delete
elif self.bin:
[516] Fix | Delete
if idx < 256:
[517] Fix | Delete
return BINPUT + pack("<B", idx)
[518] Fix | Delete
else:
[519] Fix | Delete
return LONG_BINPUT + pack("<I", idx)
[520] Fix | Delete
else:
[521] Fix | Delete
return PUT + repr(idx).encode("ascii") + b'\n'
[522] Fix | Delete
[523] Fix | Delete
# Return a GET (BINGET, LONG_BINGET) opcode string, with argument i.
[524] Fix | Delete
def get(self, i):
[525] Fix | Delete
if self.bin:
[526] Fix | Delete
if i < 256:
[527] Fix | Delete
return BINGET + pack("<B", i)
[528] Fix | Delete
else:
[529] Fix | Delete
return LONG_BINGET + pack("<I", i)
[530] Fix | Delete
[531] Fix | Delete
return GET + repr(i).encode("ascii") + b'\n'
[532] Fix | Delete
[533] Fix | Delete
def save(self, obj, save_persistent_id=True):
[534] Fix | Delete
self.framer.commit_frame()
[535] Fix | Delete
[536] Fix | Delete
# Check for persistent id (defined by a subclass)
[537] Fix | Delete
pid = self.persistent_id(obj)
[538] Fix | Delete
if pid is not None and save_persistent_id:
[539] Fix | Delete
self.save_pers(pid)
[540] Fix | Delete
return
[541] Fix | Delete
[542] Fix | Delete
# Check the memo
[543] Fix | Delete
x = self.memo.get(id(obj))
[544] Fix | Delete
if x is not None:
[545] Fix | Delete
self.write(self.get(x[0]))
[546] Fix | Delete
return
[547] Fix | Delete
[548] Fix | Delete
rv = NotImplemented
[549] Fix | Delete
reduce = getattr(self, "reducer_override", None)
[550] Fix | Delete
if reduce is not None:
[551] Fix | Delete
rv = reduce(obj)
[552] Fix | Delete
[553] Fix | Delete
if rv is NotImplemented:
[554] Fix | Delete
# Check the type dispatch table
[555] Fix | Delete
t = type(obj)
[556] Fix | Delete
f = self.dispatch.get(t)
[557] Fix | Delete
if f is not None:
[558] Fix | Delete
f(self, obj) # Call unbound method with explicit self
[559] Fix | Delete
return
[560] Fix | Delete
[561] Fix | Delete
# Check private dispatch table if any, or else
[562] Fix | Delete
# copyreg.dispatch_table
[563] Fix | Delete
reduce = getattr(self, 'dispatch_table', dispatch_table).get(t)
[564] Fix | Delete
if reduce is not None:
[565] Fix | Delete
rv = reduce(obj)
[566] Fix | Delete
else:
[567] Fix | Delete
# Check for a class with a custom metaclass; treat as regular
[568] Fix | Delete
# class
[569] Fix | Delete
if issubclass(t, type):
[570] Fix | Delete
self.save_global(obj)
[571] Fix | Delete
return
[572] Fix | Delete
[573] Fix | Delete
# Check for a __reduce_ex__ method, fall back to __reduce__
[574] Fix | Delete
reduce = getattr(obj, "__reduce_ex__", None)
[575] Fix | Delete
if reduce is not None:
[576] Fix | Delete
rv = reduce(self.proto)
[577] Fix | Delete
else:
[578] Fix | Delete
reduce = getattr(obj, "__reduce__", None)
[579] Fix | Delete
if reduce is not None:
[580] Fix | Delete
rv = reduce()
[581] Fix | Delete
else:
[582] Fix | Delete
raise PicklingError("Can't pickle %r object: %r" %
[583] Fix | Delete
(t.__name__, obj))
[584] Fix | Delete
[585] Fix | Delete
# Check for string returned by reduce(), meaning "save as global"
[586] Fix | Delete
if isinstance(rv, str):
[587] Fix | Delete
self.save_global(obj, rv)
[588] Fix | Delete
return
[589] Fix | Delete
[590] Fix | Delete
# Assert that reduce() returned a tuple
[591] Fix | Delete
if not isinstance(rv, tuple):
[592] Fix | Delete
raise PicklingError("%s must return string or tuple" % reduce)
[593] Fix | Delete
[594] Fix | Delete
# Assert that it returned an appropriately sized tuple
[595] Fix | Delete
l = len(rv)
[596] Fix | Delete
if not (2 <= l <= 6):
[597] Fix | Delete
raise PicklingError("Tuple returned by %s must have "
[598] Fix | Delete
"two to six elements" % reduce)
[599] Fix | Delete
[600] Fix | Delete
# Save the reduce() output and finally memoize the object
[601] Fix | Delete
self.save_reduce(obj=obj, *rv)
[602] Fix | Delete
[603] Fix | Delete
def persistent_id(self, obj):
[604] Fix | Delete
# This exists so a subclass can override it
[605] Fix | Delete
return None
[606] Fix | Delete
[607] Fix | Delete
def save_pers(self, pid):
[608] Fix | Delete
# Save a persistent id reference
[609] Fix | Delete
if self.bin:
[610] Fix | Delete
self.save(pid, save_persistent_id=False)
[611] Fix | Delete
self.write(BINPERSID)
[612] Fix | Delete
else:
[613] Fix | Delete
try:
[614] Fix | Delete
self.write(PERSID + str(pid).encode("ascii") + b'\n')
[615] Fix | Delete
except UnicodeEncodeError:
[616] Fix | Delete
raise PicklingError(
[617] Fix | Delete
"persistent IDs in protocol 0 must be ASCII strings")
[618] Fix | Delete
[619] Fix | Delete
def save_reduce(self, func, args, state=None, listitems=None,
[620] Fix | Delete
dictitems=None, state_setter=None, obj=None):
[621] Fix | Delete
# This API is called by some subclasses
[622] Fix | Delete
[623] Fix | Delete
if not isinstance(args, tuple):
[624] Fix | Delete
raise PicklingError("args from save_reduce() must be a tuple")
[625] Fix | Delete
if not callable(func):
[626] Fix | Delete
raise PicklingError("func from save_reduce() must be callable")
[627] Fix | Delete
[628] Fix | Delete
save = self.save
[629] Fix | Delete
write = self.write
[630] Fix | Delete
[631] Fix | Delete
func_name = getattr(func, "__name__", "")
[632] Fix | Delete
if self.proto >= 2 and func_name == "__newobj_ex__":
[633] Fix | Delete
cls, args, kwargs = args
[634] Fix | Delete
if not hasattr(cls, "__new__"):
[635] Fix | Delete
raise PicklingError("args[0] from {} args has no __new__"
[636] Fix | Delete
.format(func_name))
[637] Fix | Delete
if obj is not None and cls is not obj.__class__:
[638] Fix | Delete
raise PicklingError("args[0] from {} args has the wrong class"
[639] Fix | Delete
.format(func_name))
[640] Fix | Delete
if self.proto >= 4:
[641] Fix | Delete
save(cls)
[642] Fix | Delete
save(args)
[643] Fix | Delete
save(kwargs)
[644] Fix | Delete
write(NEWOBJ_EX)
[645] Fix | Delete
else:
[646] Fix | Delete
func = partial(cls.__new__, cls, *args, **kwargs)
[647] Fix | Delete
save(func)
[648] Fix | Delete
save(())
[649] Fix | Delete
write(REDUCE)
[650] Fix | Delete
elif self.proto >= 2 and func_name == "__newobj__":
[651] Fix | Delete
# A __reduce__ implementation can direct protocol 2 or newer to
[652] Fix | Delete
# use the more efficient NEWOBJ opcode, while still
[653] Fix | Delete
# allowing protocol 0 and 1 to work normally. For this to
[654] Fix | Delete
# work, the function returned by __reduce__ should be
[655] Fix | Delete
# called __newobj__, and its first argument should be a
[656] Fix | Delete
# class. The implementation for __newobj__
[657] Fix | Delete
# should be as follows, although pickle has no way to
[658] Fix | Delete
# verify this:
[659] Fix | Delete
#
[660] Fix | Delete
# def __newobj__(cls, *args):
[661] Fix | Delete
# return cls.__new__(cls, *args)
[662] Fix | Delete
#
[663] Fix | Delete
# Protocols 0 and 1 will pickle a reference to __newobj__,
[664] Fix | Delete
# while protocol 2 (and above) will pickle a reference to
[665] Fix | Delete
# cls, the remaining args tuple, and the NEWOBJ code,
[666] Fix | Delete
# which calls cls.__new__(cls, *args) at unpickling time
[667] Fix | Delete
# (see load_newobj below). If __reduce__ returns a
[668] Fix | Delete
# three-tuple, the state from the third tuple item will be
[669] Fix | Delete
# pickled regardless of the protocol, calling __setstate__
[670] Fix | Delete
# at unpickling time (see load_build below).
[671] Fix | Delete
#
[672] Fix | Delete
# Note that no standard __newobj__ implementation exists;
[673] Fix | Delete
# you have to provide your own. This is to enforce
[674] Fix | Delete
# compatibility with Python 2.2 (pickles written using
[675] Fix | Delete
# protocol 0 or 1 in Python 2.3 should be unpicklable by
[676] Fix | Delete
# Python 2.2).
[677] Fix | Delete
cls = args[0]
[678] Fix | Delete
if not hasattr(cls, "__new__"):
[679] Fix | Delete
raise PicklingError(
[680] Fix | Delete
"args[0] from __newobj__ args has no __new__")
[681] Fix | Delete
if obj is not None and cls is not obj.__class__:
[682] Fix | Delete
raise PicklingError(
[683] Fix | Delete
"args[0] from __newobj__ args has the wrong class")
[684] Fix | Delete
args = args[1:]
[685] Fix | Delete
save(cls)
[686] Fix | Delete
save(args)
[687] Fix | Delete
write(NEWOBJ)
[688] Fix | Delete
else:
[689] Fix | Delete
save(func)
[690] Fix | Delete
save(args)
[691] Fix | Delete
write(REDUCE)
[692] Fix | Delete
[693] Fix | Delete
if obj is not None:
[694] Fix | Delete
# If the object is already in the memo, this means it is
[695] Fix | Delete
# recursive. In this case, throw away everything we put on the
[696] Fix | Delete
# stack, and fetch the object back from the memo.
[697] Fix | Delete
if id(obj) in self.memo:
[698] Fix | Delete
write(POP + self.get(self.memo[id(obj)][0]))
[699] Fix | Delete
else:
[700] Fix | Delete
self.memoize(obj)
[701] Fix | Delete
[702] Fix | Delete
# More new special cases (that work with older protocols as
[703] Fix | Delete
# well): when __reduce__ returns a tuple with 4 or 5 items,
[704] Fix | Delete
# the 4th and 5th item should be iterators that provide list
[705] Fix | Delete
# items and dict items (as (key, value) tuples), or None.
[706] Fix | Delete
[707] Fix | Delete
if listitems is not None:
[708] Fix | Delete
self._batch_appends(listitems)
[709] Fix | Delete
[710] Fix | Delete
if dictitems is not None:
[711] Fix | Delete
self._batch_setitems(dictitems)
[712] Fix | Delete
[713] Fix | Delete
if state is not None:
[714] Fix | Delete
if state_setter is None:
[715] Fix | Delete
save(state)
[716] Fix | Delete
write(BUILD)
[717] Fix | Delete
else:
[718] Fix | Delete
# If a state_setter is specified, call it instead of load_build
[719] Fix | Delete
# to update obj's with its previous state.
[720] Fix | Delete
# First, push state_setter and its tuple of expected arguments
[721] Fix | Delete
# (obj, state) onto the stack.
[722] Fix | Delete
save(state_setter)
[723] Fix | Delete
save(obj) # simple BINGET opcode as obj is already memoized.
[724] Fix | Delete
save(state)
[725] Fix | Delete
write(TUPLE2)
[726] Fix | Delete
# Trigger a state_setter(obj, state) function call.
[727] Fix | Delete
write(REDUCE)
[728] Fix | Delete
# The purpose of state_setter is to carry-out an
[729] Fix | Delete
# inplace modification of obj. We do not care about what the
[730] Fix | Delete
# method might return, so its output is eventually removed from
[731] Fix | Delete
# the stack.
[732] Fix | Delete
write(POP)
[733] Fix | Delete
[734] Fix | Delete
# Methods below this point are dispatched through the dispatch table
[735] Fix | Delete
[736] Fix | Delete
dispatch = {}
[737] Fix | Delete
[738] Fix | Delete
def save_none(self, obj):
[739] Fix | Delete
self.write(NONE)
[740] Fix | Delete
dispatch[type(None)] = save_none
[741] Fix | Delete
[742] Fix | Delete
def save_bool(self, obj):
[743] Fix | Delete
if self.proto >= 2:
[744] Fix | Delete
self.write(NEWTRUE if obj else NEWFALSE)
[745] Fix | Delete
else:
[746] Fix | Delete
self.write(TRUE if obj else FALSE)
[747] Fix | Delete
dispatch[bool] = save_bool
[748] Fix | Delete
[749] Fix | Delete
def save_long(self, obj):
[750] Fix | Delete
if self.bin:
[751] Fix | Delete
# If the int is small enough to fit in a signed 4-byte 2's-comp
[752] Fix | Delete
# format, we can store it more efficiently than the general
[753] Fix | Delete
# case.
[754] Fix | Delete
# First one- and two-byte unsigned ints:
[755] Fix | Delete
if obj >= 0:
[756] Fix | Delete
if obj <= 0xff:
[757] Fix | Delete
self.write(BININT1 + pack("<B", obj))
[758] Fix | Delete
return
[759] Fix | Delete
if obj <= 0xffff:
[760] Fix | Delete
self.write(BININT2 + pack("<H", obj))
[761] Fix | Delete
return
[762] Fix | Delete
# Next check for 4-byte signed ints:
[763] Fix | Delete
if -0x80000000 <= obj <= 0x7fffffff:
[764] Fix | Delete
self.write(BININT + pack("<i", obj))
[765] Fix | Delete
return
[766] Fix | Delete
if self.proto >= 2:
[767] Fix | Delete
encoded = encode_long(obj)
[768] Fix | Delete
n = len(encoded)
[769] Fix | Delete
if n < 256:
[770] Fix | Delete
self.write(LONG1 + pack("<B", n) + encoded)
[771] Fix | Delete
else:
[772] Fix | Delete
self.write(LONG4 + pack("<i", n) + encoded)
[773] Fix | Delete
return
[774] Fix | Delete
if -0x80000000 <= obj <= 0x7fffffff:
[775] Fix | Delete
self.write(INT + repr(obj).encode("ascii") + b'\n')
[776] Fix | Delete
else:
[777] Fix | Delete
self.write(LONG + repr(obj).encode("ascii") + b'L\n')
[778] Fix | Delete
dispatch[int] = save_long
[779] Fix | Delete
[780] Fix | Delete
def save_float(self, obj):
[781] Fix | Delete
if self.bin:
[782] Fix | Delete
self.write(BINFLOAT + pack('>d', obj))
[783] Fix | Delete
else:
[784] Fix | Delete
self.write(FLOAT + repr(obj).encode("ascii") + b'\n')
[785] Fix | Delete
dispatch[float] = save_float
[786] Fix | Delete
[787] Fix | Delete
def save_bytes(self, obj):
[788] Fix | Delete
if self.proto < 3:
[789] Fix | Delete
if not obj: # bytes object is empty
[790] Fix | Delete
self.save_reduce(bytes, (), obj=obj)
[791] Fix | Delete
else:
[792] Fix | Delete
self.save_reduce(codecs.encode,
[793] Fix | Delete
(str(obj, 'latin1'), 'latin1'), obj=obj)
[794] Fix | Delete
return
[795] Fix | Delete
n = len(obj)
[796] Fix | Delete
if n <= 0xff:
[797] Fix | Delete
self.write(SHORT_BINBYTES + pack("<B", n) + obj)
[798] Fix | Delete
elif n > 0xffffffff and self.proto >= 4:
[799] Fix | Delete
self._write_large_bytes(BINBYTES8 + pack("<Q", n), obj)
[800] Fix | Delete
elif n >= self.framer._FRAME_SIZE_TARGET:
[801] Fix | Delete
self._write_large_bytes(BINBYTES + pack("<I", n), obj)
[802] Fix | Delete
else:
[803] Fix | Delete
self.write(BINBYTES + pack("<I", n) + obj)
[804] Fix | Delete
self.memoize(obj)
[805] Fix | Delete
dispatch[bytes] = save_bytes
[806] Fix | Delete
[807] Fix | Delete
def save_bytearray(self, obj):
[808] Fix | Delete
if self.proto < 5:
[809] Fix | Delete
if not obj: # bytearray is empty
[810] Fix | Delete
self.save_reduce(bytearray, (), obj=obj)
[811] Fix | Delete
else:
[812] Fix | Delete
self.save_reduce(bytearray, (bytes(obj),), obj=obj)
[813] Fix | Delete
return
[814] Fix | Delete
n = len(obj)
[815] Fix | Delete
if n >= self.framer._FRAME_SIZE_TARGET:
[816] Fix | Delete
self._write_large_bytes(BYTEARRAY8 + pack("<Q", n), obj)
[817] Fix | Delete
else:
[818] Fix | Delete
self.write(BYTEARRAY8 + pack("<Q", n) + obj)
[819] Fix | Delete
dispatch[bytearray] = save_bytearray
[820] Fix | Delete
[821] Fix | Delete
if _HAVE_PICKLE_BUFFER:
[822] Fix | Delete
def save_picklebuffer(self, obj):
[823] Fix | Delete
if self.proto < 5:
[824] Fix | Delete
raise PicklingError("PickleBuffer can only pickled with "
[825] Fix | Delete
"protocol >= 5")
[826] Fix | Delete
with obj.raw() as m:
[827] Fix | Delete
if not m.contiguous:
[828] Fix | Delete
raise PicklingError("PickleBuffer can not be pickled when "
[829] Fix | Delete
"pointing to a non-contiguous buffer")
[830] Fix | Delete
in_band = True
[831] Fix | Delete
if self._buffer_callback is not None:
[832] Fix | Delete
in_band = bool(self._buffer_callback(obj))
[833] Fix | Delete
if in_band:
[834] Fix | Delete
# Write data in-band
[835] Fix | Delete
# XXX The C implementation avoids a copy here
[836] Fix | Delete
if m.readonly:
[837] Fix | Delete
self.save_bytes(m.tobytes())
[838] Fix | Delete
else:
[839] Fix | Delete
self.save_bytearray(m.tobytes())
[840] Fix | Delete
else:
[841] Fix | Delete
# Write data out-of-band
[842] Fix | Delete
self.write(NEXT_BUFFER)
[843] Fix | Delete
if m.readonly:
[844] Fix | Delete
self.write(READONLY_BUFFER)
[845] Fix | Delete
[846] Fix | Delete
dispatch[PickleBuffer] = save_picklebuffer
[847] Fix | Delete
[848] Fix | Delete
def save_str(self, obj):
[849] Fix | Delete
if self.bin:
[850] Fix | Delete
encoded = obj.encode('utf-8', 'surrogatepass')
[851] Fix | Delete
n = len(encoded)
[852] Fix | Delete
if n <= 0xff and self.proto >= 4:
[853] Fix | Delete
self.write(SHORT_BINUNICODE + pack("<B", n) + encoded)
[854] Fix | Delete
elif n > 0xffffffff and self.proto >= 4:
[855] Fix | Delete
self._write_large_bytes(BINUNICODE8 + pack("<Q", n), encoded)
[856] Fix | Delete
elif n >= self.framer._FRAME_SIZE_TARGET:
[857] Fix | Delete
self._write_large_bytes(BINUNICODE + pack("<I", n), encoded)
[858] Fix | Delete
else:
[859] Fix | Delete
self.write(BINUNICODE + pack("<I", n) + encoded)
[860] Fix | Delete
else:
[861] Fix | Delete
obj = obj.replace("\\", "\\u005c")
[862] Fix | Delete
obj = obj.replace("\0", "\\u0000")
[863] Fix | Delete
obj = obj.replace("\n", "\\u000a")
[864] Fix | Delete
obj = obj.replace("\r", "\\u000d")
[865] Fix | Delete
obj = obj.replace("\x1a", "\\u001a") # EOF on DOS
[866] Fix | Delete
self.write(UNICODE + obj.encode('raw-unicode-escape') +
[867] Fix | Delete
b'\n')
[868] Fix | Delete
self.memoize(obj)
[869] Fix | Delete
dispatch[str] = save_str
[870] Fix | Delete
[871] Fix | Delete
def save_tuple(self, obj):
[872] Fix | Delete
if not obj: # tuple is empty
[873] Fix | Delete
if self.bin:
[874] Fix | Delete
self.write(EMPTY_TUPLE)
[875] Fix | Delete
else:
[876] Fix | Delete
self.write(MARK + TUPLE)
[877] Fix | Delete
return
[878] Fix | Delete
[879] Fix | Delete
n = len(obj)
[880] Fix | Delete
save = self.save
[881] Fix | Delete
memo = self.memo
[882] Fix | Delete
if n <= 3 and self.proto >= 2:
[883] Fix | Delete
for element in obj:
[884] Fix | Delete
save(element)
[885] Fix | Delete
# Subtle. Same as in the big comment below.
[886] Fix | Delete
if id(obj) in memo:
[887] Fix | Delete
get = self.get(memo[id(obj)][0])
[888] Fix | Delete
self.write(POP * n + get)
[889] Fix | Delete
else:
[890] Fix | Delete
self.write(_tuplesize2code[n])
[891] Fix | Delete
self.memoize(obj)
[892] Fix | Delete
return
[893] Fix | Delete
[894] Fix | Delete
# proto 0 or proto 1 and tuple isn't empty, or proto > 1 and tuple
[895] Fix | Delete
# has more than 3 elements.
[896] Fix | Delete
write = self.write
[897] Fix | Delete
write(MARK)
[898] Fix | Delete
for element in obj:
[899] Fix | Delete
save(element)
[900] Fix | Delete
[901] Fix | Delete
if id(obj) in memo:
[902] Fix | Delete
# Subtle. d was not in memo when we entered save_tuple(), so
[903] Fix | Delete
# the process of saving the tuple's elements must have saved
[904] Fix | Delete
# the tuple itself: the tuple is recursive. The proper action
[905] Fix | Delete
# now is to throw away everything we put on the stack, and
[906] Fix | Delete
# simply GET the tuple (it's already constructed). This check
[907] Fix | Delete
# could have been done in the "for element" loop instead, but
[908] Fix | Delete
# recursive tuples are a rare thing.
[909] Fix | Delete
get = self.get(memo[id(obj)][0])
[910] Fix | Delete
if self.bin:
[911] Fix | Delete
write(POP_MARK + get)
[912] Fix | Delete
else: # proto 0 -- POP_MARK not available
[913] Fix | Delete
write(POP * (n+1) + get)
[914] Fix | Delete
return
[915] Fix | Delete
[916] Fix | Delete
# No recursion.
[917] Fix | Delete
write(TUPLE)
[918] Fix | Delete
self.memoize(obj)
[919] Fix | Delete
[920] Fix | Delete
dispatch[tuple] = save_tuple
[921] Fix | Delete
[922] Fix | Delete
def save_list(self, obj):
[923] Fix | Delete
if self.bin:
[924] Fix | Delete
self.write(EMPTY_LIST)
[925] Fix | Delete
else: # proto 0 -- can't use EMPTY_LIST
[926] Fix | Delete
self.write(MARK + LIST)
[927] Fix | Delete
[928] Fix | Delete
self.memoize(obj)
[929] Fix | Delete
self._batch_appends(obj)
[930] Fix | Delete
[931] Fix | Delete
dispatch[list] = save_list
[932] Fix | Delete
[933] Fix | Delete
_BATCHSIZE = 1000
[934] Fix | Delete
[935] Fix | Delete
def _batch_appends(self, items):
[936] Fix | Delete
# Helper to batch up APPENDS sequences
[937] Fix | Delete
save = self.save
[938] Fix | Delete
write = self.write
[939] Fix | Delete
[940] Fix | Delete
if not self.bin:
[941] Fix | Delete
for x in items:
[942] Fix | Delete
save(x)
[943] Fix | Delete
write(APPEND)
[944] Fix | Delete
return
[945] Fix | Delete
[946] Fix | Delete
it = iter(items)
[947] Fix | Delete
while True:
[948] Fix | Delete
tmp = list(islice(it, self._BATCHSIZE))
[949] Fix | Delete
n = len(tmp)
[950] Fix | Delete
if n > 1:
[951] Fix | Delete
write(MARK)
[952] Fix | Delete
for x in tmp:
[953] Fix | Delete
save(x)
[954] Fix | Delete
write(APPENDS)
[955] Fix | Delete
elif n:
[956] Fix | Delete
save(tmp[0])
[957] Fix | Delete
write(APPEND)
[958] Fix | Delete
# else tmp is empty, and we're done
[959] Fix | Delete
if n < self._BATCHSIZE:
[960] Fix | Delete
return
[961] Fix | Delete
[962] Fix | Delete
def save_dict(self, obj):
[963] Fix | Delete
if self.bin:
[964] Fix | Delete
self.write(EMPTY_DICT)
[965] Fix | Delete
else: # proto 0 -- can't use EMPTY_DICT
[966] Fix | Delete
self.write(MARK + DICT)
[967] Fix | Delete
[968] Fix | Delete
self.memoize(obj)
[969] Fix | Delete
self._batch_setitems(obj.items())
[970] Fix | Delete
[971] Fix | Delete
dispatch[dict] = save_dict
[972] Fix | Delete
if PyStringMap is not None:
[973] Fix | Delete
dispatch[PyStringMap] = save_dict
[974] Fix | Delete
[975] Fix | Delete
def _batch_setitems(self, items):
[976] Fix | Delete
# Helper to batch up SETITEMS sequences; proto >= 1 only
[977] Fix | Delete
save = self.save
[978] Fix | Delete
write = self.write
[979] Fix | Delete
[980] Fix | Delete
if not self.bin:
[981] Fix | Delete
for k, v in items:
[982] Fix | Delete
save(k)
[983] Fix | Delete
save(v)
[984] Fix | Delete
write(SETITEM)
[985] Fix | Delete
return
[986] Fix | Delete
[987] Fix | Delete
it = iter(items)
[988] Fix | Delete
while True:
[989] Fix | Delete
tmp = list(islice(it, self._BATCHSIZE))
[990] Fix | Delete
n = len(tmp)
[991] Fix | Delete
if n > 1:
[992] Fix | Delete
write(MARK)
[993] Fix | Delete
for k, v in tmp:
[994] Fix | Delete
save(k)
[995] Fix | Delete
save(v)
[996] Fix | Delete
write(SETITEMS)
[997] Fix | Delete
elif n:
[998] Fix | Delete
k, v = tmp[0]
[999] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function