PyXR

c:\python24\lib \ copy_reg.py



0001 """Helper to provide extensibility for pickle/cPickle.
0002 
0003 This is only useful to add pickle support for extension types defined in
0004 C, not for instances of user-defined classes.
0005 """
0006 
0007 from types import ClassType as _ClassType
0008 
0009 __all__ = ["pickle", "constructor",
0010            "add_extension", "remove_extension", "clear_extension_cache"]
0011 
0012 dispatch_table = {}
0013 
0014 def pickle(ob_type, pickle_function, constructor_ob=None):
0015     if type(ob_type) is _ClassType:
0016         raise TypeError("copy_reg is not intended for use with classes")
0017 
0018     if not callable(pickle_function):
0019         raise TypeError("reduction functions must be callable")
0020     dispatch_table[ob_type] = pickle_function
0021 
0022     # The constructor_ob function is a vestige of safe for unpickling.
0023     # There is no reason for the caller to pass it anymore.
0024     if constructor_ob is not None:
0025         constructor(constructor_ob)
0026 
0027 def constructor(object):
0028     if not callable(object):
0029         raise TypeError("constructors must be callable")
0030 
0031 # Example: provide pickling support for complex numbers.
0032 
0033 try:
0034     complex
0035 except NameError:
0036     pass
0037 else:
0038 
0039     def pickle_complex(c):
0040         return complex, (c.real, c.imag)
0041 
0042     pickle(complex, pickle_complex, complex)
0043 
0044 # Support for pickling new-style objects
0045 
0046 def _reconstructor(cls, base, state):
0047     if base is object:
0048         obj = object.__new__(cls)
0049     else:
0050         obj = base.__new__(cls, state)
0051         base.__init__(obj, state)
0052     return obj
0053 
0054 _HEAPTYPE = 1<<9
0055 
0056 # Python code for object.__reduce_ex__ for protocols 0 and 1
0057 
0058 def _reduce_ex(self, proto):
0059     assert proto < 2
0060     for base in self.__class__.__mro__:
0061         if hasattr(base, '__flags__') and not base.__flags__ & _HEAPTYPE:
0062             break
0063     else:
0064         base = object # not really reachable
0065     if base is object:
0066         state = None
0067     else:
0068         if base is self.__class__:
0069             raise TypeError, "can't pickle %s objects" % base.__name__
0070         state = base(self)
0071     args = (self.__class__, base, state)
0072     try:
0073         getstate = self.__getstate__
0074     except AttributeError:
0075         if getattr(self, "__slots__", None):
0076             raise TypeError("a class that defines __slots__ without "
0077                             "defining __getstate__ cannot be pickled")
0078         try:
0079             dict = self.__dict__
0080         except AttributeError:
0081             dict = None
0082     else:
0083         dict = getstate()
0084     if dict:
0085         return _reconstructor, args, dict
0086     else:
0087         return _reconstructor, args
0088 
0089 # Helper for __reduce_ex__ protocol 2
0090 
0091 def __newobj__(cls, *args):
0092     return cls.__new__(cls, *args)
0093 
0094 def _slotnames(cls):
0095     """Return a list of slot names for a given class.
0096 
0097     This needs to find slots defined by the class and its bases, so we
0098     can't simply return the __slots__ attribute.  We must walk down
0099     the Method Resolution Order and concatenate the __slots__ of each
0100     class found there.  (This assumes classes don't modify their
0101     __slots__ attribute to misrepresent their slots after the class is
0102     defined.)
0103     """
0104 
0105     # Get the value from a cache in the class if possible
0106     names = cls.__dict__.get("__slotnames__")
0107     if names is not None:
0108         return names
0109 
0110     # Not cached -- calculate the value
0111     names = []
0112     if not hasattr(cls, "__slots__"):
0113         # This class has no slots
0114         pass
0115     else:
0116         # Slots found -- gather slot names from all base classes
0117         for c in cls.__mro__:
0118             if "__slots__" in c.__dict__:
0119                 names += [name for name in c.__dict__["__slots__"]
0120                                if name not in ("__dict__", "__weakref__")]
0121 
0122     # Cache the outcome in the class if at all possible
0123     try:
0124         cls.__slotnames__ = names
0125     except:
0126         pass # But don't die if we can't
0127 
0128     return names
0129 
0130 # A registry of extension codes.  This is an ad-hoc compression
0131 # mechanism.  Whenever a global reference to <module>, <name> is about
0132 # to be pickled, the (<module>, <name>) tuple is looked up here to see
0133 # if it is a registered extension code for it.  Extension codes are
0134 # universal, so that the meaning of a pickle does not depend on
0135 # context.  (There are also some codes reserved for local use that
0136 # don't have this restriction.)  Codes are positive ints; 0 is
0137 # reserved.
0138 
0139 _extension_registry = {}                # key -> code
0140 _inverted_registry = {}                 # code -> key
0141 _extension_cache = {}                   # code -> object
0142 # Don't ever rebind those names:  cPickle grabs a reference to them when
0143 # it's initialized, and won't see a rebinding.
0144 
0145 def add_extension(module, name, code):
0146     """Register an extension code."""
0147     code = int(code)
0148     if not 1 <= code <= 0x7fffffff:
0149         raise ValueError, "code out of range"
0150     key = (module, name)
0151     if (_extension_registry.get(key) == code and
0152         _inverted_registry.get(code) == key):
0153         return # Redundant registrations are benign
0154     if key in _extension_registry:
0155         raise ValueError("key %s is already registered with code %s" %
0156                          (key, _extension_registry[key]))
0157     if code in _inverted_registry:
0158         raise ValueError("code %s is already in use for key %s" %
0159                          (code, _inverted_registry[code]))
0160     _extension_registry[key] = code
0161     _inverted_registry[code] = key
0162 
0163 def remove_extension(module, name, code):
0164     """Unregister an extension code.  For testing only."""
0165     key = (module, name)
0166     if (_extension_registry.get(key) != code or
0167         _inverted_registry.get(code) != key):
0168         raise ValueError("key %s is not registered with code %s" %
0169                          (key, code))
0170     del _extension_registry[key]
0171     del _inverted_registry[code]
0172     if code in _extension_cache:
0173         del _extension_cache[code]
0174 
0175 def clear_extension_cache():
0176     _extension_cache.clear()
0177 
0178 # Standard extension code assignments
0179 
0180 # Reserved ranges
0181 
0182 # First  Last Count  Purpose
0183 #     1   127   127  Reserved for Python standard library
0184 #   128   191    64  Reserved for Zope
0185 #   192   239    48  Reserved for 3rd parties
0186 #   240   255    16  Reserved for private use (will never be assigned)
0187 #   256   Inf   Inf  Reserved for future assignment
0188 
0189 # Extension codes are assigned by the Python Software Foundation.
0190 

Generated by PyXR 0.9.4
SourceForge.net Logo