o b1@sPUdZddlZddlZddlZddlZddlZddlmZ ddl m Z ddl m Z mZddlmZiZe eejfed<ejZdd Zd d Zd d ZeejeddZddZeejeddZddZeejeddZ ddZ!ddZ"ddZ#GdddZ$ia%e e&d fed!<ia'd"d#Z(d$d%Z)d&d'Z*Gd(d d Z+dS))z( Different styles of persisted objects. N)StringIO)Dict)logreflect)_PYPY oldModulescCst|j|j|jjffS)z3support function for copy_reg to pickle method refs)unpickleMethod__name____self__ __class__)methodr :/usr/lib/python3/dist-packages/twisted/persisted/styles.py pickleMethodsrcCst||}|S)a Retrieve the function object implementing a method name given the class it's on and a method name. @param classObject: A class to retrieve the method's function from. @type classObject: L{type} @param methodName: The name of the method whose function to retrieve. @type methodName: native L{str} @return: the function object corresponding to the given method name. @rtype: L{types.FunctionType} )getattr) classObject methodName methodObjectr r r_methodFunction"s rc Cs|dur t||Szt||}Wn&ty6td|d||dus'Jd|j|ur-t|||jYSwd}tj||g|R}|S)aS Support function for copy_reg to unpickle method refs. @param im_name: The name of the method. @type im_name: native L{str} @param im_self: The instance that the method was present on. @type im_self: L{object} @param im_class: The class where the method was declared. @type im_class: L{type} or L{None} NMethodz not on classz'No recourse: no instance to guess from.r ) rrAttributeErrorrmsgr rtypes MethodType)im_nameim_selfim_classmethodFunction maybeClassboundr r rr4s    rcCs4|jdkr td|ttd|j|jggfS)a Reduce, in the sense of L{pickle}'s C{object.__reduce__} special method, a function object into its constituent parts. @param f: The function to reduce. @type f: L{types.FunctionType} @return: a 2-tuple of a reference to L{_unpickleFunction} and a tuple of its arguments, a 1-tuple of the function's fully qualified name. @rtype: 2-tuple of C{callable, native string} zzCannot pickle lambda function: .)r _UniversalPicklingError_unpickleFunctiontuplejoin __module__ __qualname__)fr r r_pickleFunctionWs r(cCsddlm}||S)a Convert a function name into a function by importing it. This is a synonym for L{twisted.python.reflect.namedAny}, but imported locally to avoid circular imports, and also to provide a persistent name that can be stored (and deprecated) independently of C{namedAny}. @param fullyQualifiedName: The fully qualified name of a function. @type fullyQualifiedName: native C{str} @return: A function object imported from the given location. @rtype: L{types.FunctionType} r)namedAny)twisted.python.reflectr))fullyQualifiedNamer)r r rr"hs r"cCs t|jffS)z3support function for copy_reg to pickle module refs)unpickleModuler )moduler r r pickleModule~s r.cCs6|tvrtd|t|}t|t|iidS)z5support function for copy_reg to unpickle module refszModule has moved: %sx)rrr __import__)namer r rr,s  r,cCs t||ffS)z Reduce the given cStringO. This is only called on Python 2, because the cStringIO module only exists on Python 2. @param stringo: The string output to pickle. @type stringo: C{cStringIO.OutputType} )unpickleStringOgetvaluetell)stringor r r pickleStringOs r6cCst}|||||S)a Convert the output of L{pickleStringO} into an appropriate type for the current python version. This may be called on Python 3 and will convert a cStringIO into an L{io.StringIO}. @param val: The content of the file. @type val: L{bytes} @param sek: The seek position of the file. @type sek: L{int} @return: a file-like object which you can write bytes to. @rtype: C{cStringIO.OutputType} on Python 2, L{io.StringIO} on Python 3. ) _cStringIOwriteseekvalsekr/r r rr2s  r2cCst||ffS)aQ Reduce the given cStringI. This is only called on Python 2, because the cStringIO module only exists on Python 2. @param stringi: The string input to pickle. @type stringi: C{cStringIO.InputType} @return: a 2-tuple of (C{unpickleStringI}, (bytes, pointer)) @rtype: 2-tuple of (function, (bytes, int)) )unpickleStringIr3r4)stringir r r pickleStringIs r?cCst|}|||S)a Convert the output of L{pickleStringI} into an appropriate type for the current Python version. This may be called on Python 3 and will convert a cStringIO into an L{io.StringIO}. @param val: The content of the file. @type val: L{bytes} @param sek: The seek position of the file. @type sek: L{int} @return: a file-like object which you can read bytes from. @rtype: C{cStringIO.OutputType} on Python 2, L{io.StringIO} on Python 3. )r7r9r:r r rr=s r=c@s(eZdZdZddZddZddZdS) Ephemeralzh This type of object is never persisted; if possible, even references to it are eliminated. cCstdfS)zu Serialize any subclass of L{Ephemeral} in a way which replaces it with L{Ephemeral} itself. r )r@)selfr r r __reduce__szEphemeral.__reduce__cCsJtd|ts#ddl}t|ddr#||D] }td|qdS)Nz!WARNING: serializing ephemeral %sr get_referrersz referred to by )rrrgcrrC)rArDrr r r __getstate__s zEphemeral.__getstate__cCstd|jt|_dS)Nz#WARNING: unserializing ephemeral %s)rrr r@rAstater r r __setstate__s zEphemeral.__setstate__N)r r%r&__doc__rBrFrIr r r rr@s  r@ VersionedversionedsToUpgradecCs&ttD]}t|qiaiadSN)listrLvaluesrequireUpgradeupgraded) versionedr r r doUpgrades rScCs4t|}|tvr|tvrdt|<||SdSdS)z?Require that a Versioned instance be upgraded completely first.N)idrLrQversionUpgrade)objobjIDr r rrPs rPcCs@|tg}t|D]}||vrt|tr||q |ddS)z Get all of the parent classes of C{c}, not including C{c} itself, which are strict subclasses of L{Versioned}. @param c: a class @returns: list of classes N)rKinspectgetmro issubclassappend)clbr r r_aybabtu s    rac@s2eZdZdZdZdZddZd ddZd d ZdS) rKa This type of object is persisted with versioning information. I have a single class attribute, the int persistenceVersion. After I am unserialized (and styles.doUpgrade() is called), self.upgradeToVersionX() will be called for each version upgrade I must undergo. For example, if I serialize an instance of a Foo(Versioned) at version 4 and then unserialize it when the code is at version 9, the calls:: self.upgradeToVersion5() self.upgradeToVersion6() self.upgradeToVersion7() self.upgradeToVersion8() self.upgradeToVersion9() will be made. If any of these methods are undefined, a warning message will be printed. rr cCs|tt|<||_dSrM)rLrU__dict__rGr r rrI3s  zVersioned.__setstate__NcCst|p|j}t|j}|||j|D]$}d|jvr-|jD] }||vr,||=q#d|jvr=|j|t |d<q|S)z8Get state, adding a version number to it on its way out.persistenceForgetspersistenceVersionz.persistenceVersion) copyrbrar reverser]rcrdrqual)rAdictdctbasesbaseslotr r rrF7s"     zVersioned.__getstate__c CsZt|j}|||jd|jvrB|jd}|jd=d}d}|D]}d|jvr+q#|j|kr5|}|j}q#|rB||jdt|<|D]f}t|j vrQd|jvrQqD|j}dt|}|j |pbd}|ri|j|=||ksqJd||kr|d}|j d|d} | rt dt|t|jt ||f| |n t d ||||ksuqDdS) z (internal) Do a version upgrade.rdrNz%s.persistenceVersionz"Sorry, can't go backwards in time.rTzupgradeToVersion%sz'Upgrading %s (of %s @ %s) to version %sz(Warning: cannot upgrade {} to version {})rar rfr]rbrdrrgrK __bases__getrrrUformat) rArjpverhighestVersion highestBaserk currentVerspverName persistVersr r r rrVHsh           zVersioned.versionUpgraderM) r r%r&rJrdrcrIrFrVr r r rrKs  ),rJrecopyregcopy_regrZpickleriorr7typingrtwisted.pythonrrtwisted.python.compatrrstr ModuleType__annotations__ PicklingErrorr!rrrrr(r" FunctionTyper.r,r6r2r?r=r@rLintrQrSrPrarKr r r rsB