# Classes used for pickle testing. # They are moved to separate file, so they can be loaded # in other Python version for test_xpickle. import sys class C: def __eq__(self, other): return self.__dict__ == other.__dict__ # For test_load_classic_instance class D(C): def __init__(self, arg): pass class E(C): def __getinitargs__(self): return () import __main__ __main__.C = C C.__module__ = "__main__" __main__.D = D D.__module__ = "__main__" __main__.E = E E.__module__ = "__main__" # Simple mutable object. class Object: pass # Hashable immutable key object containing unheshable mutable data. class K: def __init__(self, value): self.value = value def __reduce__(self): # Shouldn't support the recursion itself return K, (self.value,) # For test_misc class myint(int): def __init__(self, x): self.str = str(x) # For test_misc and test_getinitargs class initarg(C): def __init__(self, a, b): self.a = a self.b = b def __getinitargs__(self): return self.a, self.b # For test_metaclass class metaclass(type): pass if sys.version_info >= (3,): # Syntax not compatible with Python 2 exec(''' class use_metaclass(object, metaclass=metaclass): pass ''') else: class use_metaclass(object): __metaclass__ = metaclass # Test classes for reduce_ex class R: def __init__(self, reduce=None): self.reduce = reduce def __reduce__(self, proto): return self.reduce class REX: def __init__(self, reduce_ex=None): self.reduce_ex = reduce_ex def __reduce_ex__(self, proto): return self.reduce_ex class REX_one(object): """No __reduce_ex__ here, but inheriting it from object""" _reduce_called = 0 def __reduce__(self): self._reduce_called = 1 return REX_one, () class REX_two(object): """No __reduce__ here, but inheriting it from object""" _proto = None def __reduce_ex__(self, proto): self._proto = proto return REX_two, () class REX_three(object): _proto = None def __reduce_ex__(self, proto): self._proto = proto return REX_two, () def __reduce__(self): raise AssertionError("This __reduce__ shouldn't be called") class REX_four(object): """Calling base class method should succeed""" _proto = None def __reduce_ex__(self, proto): self._proto = proto return object.__reduce_ex__(self, proto) class REX_five(object): """This one used to fail with infinite recursion""" _reduce_called = 0 def __reduce__(self): self._reduce_called = 1 return object.__reduce__(self) class REX_six(object): """This class is used to check the 4th argument (list iterator) of the reduce protocol. """ def __init__(self, items=None): self.items = items if items is not None else [] def __eq__(self, other): return type(self) is type(other) and self.items == other.items def append(self, item): self.items.append(item) def __reduce__(self): return type(self), (), None, iter(self.items), None class REX_seven(object): """This class is used to check the 5th argument (dict iterator) of the reduce protocol. """ def __init__(self, table=None): self.table = table if table is not None else {} def __eq__(self, other): return type(self) is type(other) and self.table == other.table def __setitem__(self, key, value): self.table[key] = value def __reduce__(self): return type(self), (), None, None, iter(self.table.items()) class REX_state(object): """This class is used to check the 3th argument (state) of the reduce protocol. """ def __init__(self, state=None): self.state = state def __eq__(self, other): return type(self) is type(other) and self.state == other.state def __setstate__(self, state): self.state = state def __reduce__(self): return type(self), (), self.state # For test_reduce_ex_None class REX_None: """ Setting __reduce_ex__ to None should fail """ __reduce_ex__ = None # For test_reduce_None class R_None: """ Setting __reduce__ to None should fail """ __reduce__ = None # For test_pickle_setstate_None class C_None_setstate: """ Setting __setstate__ to None should fail """ def __getstate__(self): return 1 __setstate__ = None # Test classes for newobj # For test_newobj_generic and test_newobj_proxies class MyInt(int): sample = 1 if sys.version_info >= (3,): class MyLong(int): sample = 1 else: class MyLong(long): sample = long(1) class MyFloat(float): sample = 1.0 class MyComplex(complex): sample = 1.0 + 0.0j class MyStr(str): sample = "hello" if sys.version_info >= (3,): class MyUnicode(str): sample = "hello \u1234" else: class MyUnicode(unicode): sample = unicode(r"hello \u1234", "raw-unicode-escape") class MyTuple(tuple): sample = (1, 2, 3) class MyList(list): sample = [1, 2, 3] class MyDict(dict): sample = {"a": 1, "b": 2} class MySet(set): sample = {"a", "b"} class MyFrozenSet(frozenset): sample = frozenset({"a", "b"}) myclasses = [MyInt, MyLong, MyFloat, MyComplex, MyStr, MyUnicode, MyTuple, MyList, MyDict, MySet, MyFrozenSet] # For test_newobj_overridden_new class MyIntWithNew(int): def __new__(cls, value): raise AssertionError class MyIntWithNew2(MyIntWithNew): __new__ = int.__new__ # For test_newobj_list_slots class SlotList(MyList): __slots__ = ["foo"] # Ruff "redefined while unused" false positive here due to `global` variables # being assigned (and then restored) from within test methods earlier in the file class SimpleNewObj(int): # noqa: F811 def __init__(self, *args, **kwargs): # raise an error, to make sure this isn't called raise TypeError("SimpleNewObj.__init__() didn't expect to get called") def __eq__(self, other): return int(self) == int(other) and self.__dict__ == other.__dict__ class ComplexNewObj(SimpleNewObj): def __getnewargs__(self): return ('%X' % self, 16) class ComplexNewObjEx(SimpleNewObj): def __getnewargs_ex__(self): return ('%X' % self,), {'base': 16} class ZeroCopyBytes(bytes): readonly = True c_contiguous = True f_contiguous = True zero_copy_reconstruct = True def __reduce_ex__(self, protocol): if protocol >= 5: import pickle return type(self)._reconstruct, (pickle.PickleBuffer(self),), None else: return type(self)._reconstruct, (bytes(self),) def __repr__(self): return "{}({!r})".format(self.__class__.__name__, bytes(self)) __str__ = __repr__ @classmethod def _reconstruct(cls, obj): with memoryview(obj) as m: obj = m.obj if type(obj) is cls: # Zero-copy return obj else: return cls(obj) class ZeroCopyBytearray(bytearray): readonly = False c_contiguous = True f_contiguous = True zero_copy_reconstruct = True def __reduce_ex__(self, protocol): if protocol >= 5: import pickle return type(self)._reconstruct, (pickle.PickleBuffer(self),), None else: return type(self)._reconstruct, (bytes(self),) def __repr__(self): return "{}({!r})".format(self.__class__.__name__, bytes(self)) __str__ = __repr__ @classmethod def _reconstruct(cls, obj): with memoryview(obj) as m: obj = m.obj if type(obj) is cls: # Zero-copy return obj else: return cls(obj) # For test_nested_names class Nested: class A: class B: class C: pass # For test_py_methods class PyMethodsTest: @staticmethod def cheese(): return "cheese" @classmethod def wine(cls): assert cls is PyMethodsTest return "wine" def biscuits(self): assert isinstance(self, PyMethodsTest) return "biscuits" class Nested: "Nested class" @staticmethod def ketchup(): return "ketchup" @classmethod def maple(cls): assert cls is PyMethodsTest.Nested return "maple" def pie(self): assert isinstance(self, PyMethodsTest.Nested) return "pie" # For test_c_methods class Subclass(tuple): class Nested(str): pass