U C^@sdZddlmZddlZddlmZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlZddlZddlZddlZddlZzddlmZWnek rdZYnXe jZeZeZeZe dkZ dZ!e re"e#j$j%Z!ej&ddkr\ddl m'Z'zdd l(m)Z)Wn"ek rJdd l)m)Z)YnXe*fZ+d Z,d Z-n8e"e_.dd l m/Z'dd lm0Z)e1fZ+d Z,d Z-ddl2m3Z3eZ4ddZ5ddZ6ej&dddkrddl m7Z7n2ej&dddkrddl m7Z8ddZ7nddZ7ddZ9dWddZ:ddZ;d d!Zej&ddd&krLe>Z?e j@d'ZAe j@d(ZBe j@d)ZCeAeBeCfZDejEZEejFZFiZGejHID] \ZJZKe"eKe"kreJeGeK<qd*d+ZLej&dkrd,d-ZMnd.d-ZMd/d0ZNGd1d2d2e'ZOd3d4ZPd5d6ZQdXd7d8ZRdYd9d:ZSe jTZTe jUZUd;d<ZVd=d>ZWd?d@ZXdAdBZYdCdDZZdEdFZ[e[GdGdHdHe\Z]dIdJZ^dKdLZ_dZdMdNZ`dOdPZadQdRZbdSdTZcdUdVZddS)[aU This class is defined to override standard pickle functionality The goals of it follow: -Serialize lambdas and nested functions to compiled byte code -Deal with main module correctly -Deal with other non-serializable objects It does not include an unpickler, as standard python unpickling suffices. This module was extracted from the `cloud` package, developed by `PiCloud, Inc. `_. Copyright (c) 2012, Regents of the University of California. Copyright (c) 2009 `PiCloud, Inc. `_. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of California, Berkeley nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. )print_functionN)partial)EnumPyPy)Pickler)StringIOFT)_Pickler)BytesIO) _find_specc Cs@t2t|}|dkr2tj}|t|<|t|<W5QRX|SN)_DYNAMIC_CLASS_TRACKER_LOCK_DYNAMIC_CLASS_TRACKER_BY_CLASSgetuuidZuuid4hex_DYNAMIC_CLASS_TRACKER_BY_ID) class_defclass_tracker_idr@/tmp/pip-install-6_kvzl1k/srsly/srsly/cloudpickle/cloudpickle.py_ensure_trackingls  rc Cs0|dk r,tt||}|t|<W5QRX|Sr )r r setdefaultr)rrrrr_lookup_class_or_trackvsr)r) _getattributercCst||dfSr )_py34_getattributeobjnamerrrrsrcCst||ddfSr )getattrr rrrrsc Cs|t|dd}|dk r|SttjD]P\}}|dks&|dkr@q&z t||d|kr^|WSWq&tk rtYq&Xq&dS)aUFind the module an object belongs to. This function differs from ``pickle.whichmodule`` in two ways: - it does not mangle the cases where obj's module is __main__ and obj was not found in any module. - Errors arising during module introspection are ignored, as those errors are considered unwanted side effects. __module__N__main__r)r#listsysmodulesitemsr Exception)r!r" module_namemodulerrr _whichmodules r-cCs|dkrt|dd}|dkr(t|dd}t||}|dkr>dS|dkrJdStj|d}|dkrddSt|rpdSzt||\}}Wntk rYdSX||kS)zDDetermine if obj can be pickled as attribute of a file-backed moduleN __qualname____name__Fr%)r#r-r'r(r _is_dynamicrAttributeError)r!r"r+r,obj2parentrrr _is_globals&   r4csdt|}|dkr`|jfddt|D}|jrX|jD]}t|tjr:|t|O}q:|t|<|S)zC Find all globals names read or written to by codeblock co Ncsh|]\}}|qSrr).0_opargnamesrr sz(_extract_code_globals..) _extract_code_globals_cacherco_names_walk_global_ops co_consts isinstancetypesCodeType_extract_code_globals)coZ out_namesconstrr8rrBs   rBcCsg}|D]}t|tjrt|dr|jr|jd}ttjD]N}|dk r<| |r>> cell.cell_contents = value In earlier Python3 versions, the cell_contents attribute of a cell is read only, but this limitation can be worked around by leveraging the Python 3 ``nonlocal`` keyword. In Python2 however, this attribute is read only, and there is no ``nonlocal`` keyword. For this reason, we need to come up with more complicated hacks to set this attribute. The chosen approach is to create a function with a STORE_DEREF opcode, which sets the content of a closure variable. Typically: >>> def inner(value): ... lambda: cell # the lambda makes cell a closure ... cell = value # cell is a closure, so this triggers a STORE_DEREF (Note that in Python2, A STORE_DEREF can never be triggered from an inner function. The function g for example here >>> def f(var): ... def g(): ... var += 1 ... return g will not modify the closure variable ``var```inplace, but instead try to load a local variable var and increment it. As g does not assign the local variable ``var`` any initial value, calling f(1)() will fail at runtime.) Our objective is to set the value of a given cell ``cell``. So we need to somewhat reference our ``cell`` object into the ``inner`` function so that this object (and not the smoke cell of the lambda function) gets affected by the STORE_DEREF operation. In inner, ``cell`` is referenced as a cell variable (an enclosing variable that is referenced by the inner function). If we create a new function cell_set with the exact same code as ``inner``, but with ``cell`` marked as a free variable instead, the STORE_DEREF will be applied on its closure - ``cell``, which we can specify explicitly during construction! The new cell_set variable thus actually sets the contents of a specified cell! Note: we do not make use of the ``nonlocal`` keyword to set the contents of a cell in early python3 versions to limit possible syntax errors in case test and checker libraries decide to parse the whole file. Nrr _cell_setr)r' version_info cell_contentsr@ FunctionType_cell_set_template_code)cellvaluerUrrrcell_sets9r\cCsdd}|j}trRt|j|j|j|j|j|j |j |j |j |j |j|j|jd}nBt|j|j|j|j|j|j|j |j |j |j |j |j|j|jd}|S)Ncsfdd|dS)NcsSr rrrZrrXzI_make_cell_set_template_code.._cell_set_factory..r)r[rr]r_cell_set_factoryWs z7_make_cell_set_template_code.._cell_set_factoryr)__code__PY2r@rA co_argcount co_nlocals co_stacksizeco_flagsco_coder>r< co_varnames co_filenameco_nameco_firstlineno co_lnotab co_cellvarsco_kwonlyargcount)r`rCrYrrr_make_cell_set_template_codeVsJrorS STORE_GLOBAL DELETE_GLOBAL LOAD_GLOBALcCs tt|Sr )r#r@r"rrr _builtin_typesrtccst|dd}trtt|}t|}d}d}||kr||}|d7}|tkr*||||dd|}d}|d7}|tkr|d}|tkr*||fVq*dS) s Yield (opcode, argument number) tuples for all global-referencing instructions in *code*. rgr_rriN)r#rbmapordrK HAVE_ARGUMENT EXTENDED_ARG GLOBAL_OPS)rNni extended_argopr7rrrr=s"  r=ccs.t|D]}|j}|tkr ||jfVq dS)ruN)disget_instructionsopcoder|arg)rNinstrrrrrr=sc Cst|j}t|jdkr&|jdj}n i}t|jD]}||jq4g}|D]<\}}z||}||krv||WqRtk rYqRXqR|D]}| |q|S)zDRetrieve a copy of the dict of a class without the inherited methodsrvr) dict__dict__rK __bases__reversedupdater)rMKeyErrorpop)clsclsdictZinherited_dictbaseZ to_remover"r[Z base_valuerrr_extract_class_dicts"  rc@seZdZejZdAddZddZddZeee <e rHdd Z e ee <d d Z e eej<d d Zeeej<dBddZeeej<ddZddZddZddZddZesddZeeej<eejdZeej Z!edj Z"eee<eee!<eee"<e#j$dddkree%j&Z'eee'<d d!Z(e(eej)<de*j+fd"d#Z,e,ee<e,eej-<d$d%Z.e.eej/<d&d'Z0e r|e0eej1<d(d)Z2e2ee3<d*d+Z4e4ee5<e4ee6<d,d-Z7ee8j9ekre7ee8j9<d.d/Z:ee8j;ekre:ee8j;<d0d1Zz eeeeD<d6d7ZEeEeeFjG<d8d9ZHeHeeIjJ<d:d;ZKeKeeIjL<eMed<rd=d>ZNeNeejO<d?d@ZPdS)C CloudPicklerNcCs&|dkr t}tj|||di|_dS)Nprotocol)DEFAULT_PROTOCOLr__init__ globals_ref)selffilerrrrrszCloudPickler.__init__c Cs^|zt||WStk rX}z$d|jdkrFd}t|nW5d}~XYnXdS)N recursionrz?Could not pickle object as excessively deep recursion required.) inject_addonsrdump RuntimeErrorargspickle PicklingError)rr!emsgrrrrs zCloudPickler.dumpcCs||dSr )savetobytesrr!rrrsave_memoryviewszCloudPickler.save_memoryviewcCs|t|dSr )rstrrrrr save_bufferszCloudPickler.save_buffercCs<t|r$|jt|jt|f|dn|jt|jf|ddS)z, Save a module as an import r!N)r0 save_reducedynamic_subimportr/vars subimportrrrr save_modules zCloudPickler.save_modulecCstrt|drT|j|j|j|j|j|j|j|j |j |j |j |j |j|j|j|jf}q|j|j|j|j|j|j|j |j |j |j |j |j|j|j|jf}n<|j|j|j|j|j|j |j |j |j |j |j|j|j|jf}|jtj||ddS)z$ Save a code object co_posonlyargcountrN)PY3rHrcrrnrdrerfrgr>r<rhrirjrkrl co_freevarsrmrr@rA)rr!rrrrsave_codeobjectsf   zCloudPickler.save_codeobjectcCsDt||drtj|||dStr6t|jtr6||S||SdS)z Registered with the dispatch to handle all function types. Determines what kind of function obj is (e.g. lambda, defined at interactive prompt, etc) and handles the pickling appropriately. rsN) r4r save_globalPYPYr?rabuiltin_code_typesave_pypy_builtin_funcsave_function_tuple)rr!r"rrr save_function!s   zCloudPickler.save_functioncCs4tj|ji|j|j|jf|jf}|j|d|idS)aSave pypy equivalent of builtin functions. PyPy does not have the concept of builtin-functions. Instead, builtin-functions are simple function instances, but with a builtin-code attribute. Most of the time, builtin functions should be pickled by attribute. But PyPy has flaky support for __qualname__, so some builtin functions such as float.__new__ will be classified as dynamic. For this reason only, we created this special routine. Because builtin-functions are not expected to have closure or globals, there is no additional hack (compared the one already implemented in pickle) to protect ourselves from reference cycles. A simple (reconstructor, newargs, obj.__dict__) tuple is save_reduced. Note also that PyPy improved their support for __qualname__ in v3.6, so this routing should be removed when cloudpickle supports only PyPy 3.6 and later. r!N)r@rXrar/ __defaults__ __closure__rr)rr!rvrrrr0sz#CloudPickler.save_pypy_builtin_funcc Csttdd|D}t|dd}|jt|j|j|||jt|df|ddD]}||dqJ|D]}||q`dS)a Special handling for dynamic Enum subclasses Use a dedicated Enum constructor (inspired by EnumMeta.__call__) as the EnumMeta metaclass has complex initialization that makes the Enum subclasses hold references to their own instances. css|]}|j|jfVqdSr )r"r[)r5rrrr Osz2CloudPickler._save_dynamic_enum..r.Nr)_generate_next_value__member_names_ _member_map_ _member_type__value2member_map_) rr#r_make_skeleton_enumrr/r$rr)rr!rmembersqualnameattrnamememberrrr_save_dynamic_enumHs  zCloudPickler._save_dynamic_enumc CsFt|}|ddd|krHddl}||\}}}}dd|D|d<d|ddi}t|dr|j|d<t|jtr||jn|jD]}||dq|d d}t|tr||d <|j } |j } | t | t j tdk rt|tr|||n,t|} |jt| |j|j|t|df|d | || t j| t jdS) zSave a class that can't be stored as module global. This method is used to serialize classes that are defined inside functions, or that otherwise can't be serialized as attribute lookups from global modules. __weakref__N _abc_implrcSsg|] }|qSrr)r5Zsubclass_weakrefrrr rsz3CloudPickler.save_dynamic_class..__doc__ __slots__rr)rrabc _get_dumprHrr? string_typespropertyrwrite_rehydrate_skeleton_classrMARKr issubclassrtyper_make_skeleton_classr/rrTUPLEREDUCE) rr!rrregistryr6 type_kwargskrrrtprrrsave_dynamic_classbsF           zCloudPickler.save_dynamic_classc Cs,t|r |jt|jf|ddS|j}|j}||\}}}}}} |t|tj t |t | |phd} |t|||dk rt|nd| f|tj|||||||j|j|j| d} t|drtjdkr|j| d<t|d r|j| d <t|d r |j| d <|| |tj|tjdS) a Pickles an actual func object. A func comprises: code, globals, defaults, closure, and dict. We extract and save these, injecting reducing functions at certain points to recreate the func object. Keep in mind that some of these pieces can contain a ref to the func itself. Thus, a naive save on these pieces could trigger an infinite loop of save's. To get around that, we first create a skeleton func object using just the code (this is safe, since this won't contain a ref to the func), and memoize it as soon as it's created. The other stuff can then be filled in later. rNr)globalsdefaultsrclosure_valuesr,r"doc_cloudpickle_submodules__annotations__rS annotationsr.r__kwdefaults__ kwdefaults)is_tornado_coroutiner_rebuild_tornado_coroutine __wrapped__rrextract_func_data_fill_functionrrrR itertoolschainvalues_make_skel_funcrKrmemoizer$r/rrHr'rVrr.rr) rfuncrrrN f_globalsrrdct base_globalsZ submodulesstaterrrrsP            z CloudPickler.save_function_tuplec Cs|j}t|}i}|D]}||jkr|j|||<q|j}|jdk rTttt|jnd}|j}|j t |ji} | ikrdD]&} |jdk r~| |jkr~|j| | | <q~|||||| fS)z Turn the function into a tuple of data necessary to recreate it: code, globals, defaults, closure_values, dict N)rEr/__path____file__) rarB __globals__rrr&rx_get_cell_contentsrrrid) rrrNZfunc_global_refsrvarrclosurerrrrrrrs$  zCloudPickler.extract_func_datacCsnt|dddk }|r4t|j|jff}|j|d|iSt|d}|rbt|j|jff}|j|d|iSt||S)N__self__r! __objclass__)r#rr/rrHrrr)rr!Zis_boundrZ is_unboundrrrsave_builtin_function_or_method4s z,CloudPickler.save_builtin_function_or_methodfromhexg?rrcCs|t|j|jfSr )rr#rr/rrrrsave_getset_descriptorUsz#CloudPickler.save_getset_descriptorcCs|tdkr|jtd|dS|ttkr:|jttf|dS|ttkrX|jttf|dS|tkrv|jtt|f|dS|dk rtj|||dn(t||ds| |ntj|||ddS)z Save a "global". The name of this method is somewhat misleading: all types get dispatched here. Nr rrs) rrEllipsisNotImplemented_BUILTIN_TYPE_NAMESrtrrr4r)rr!r"packrrrrZs"     zCloudPickler.save_globalcCsf|jdkr |t|j|jfnBtr@|jtj|j|jf|dn"|jtj|j|jt |jf|ddSNr) rrr#Zim_classr/rr@ MethodType__func__rrrrrsave_instancemethodts z CloudPickler.save_instancemethodc Cs |j}|j|}|r$|||dS|j}|j}|j}t|dr^|}t|t ||nd}|t j |j r|||D] }||q~|t j n0|D] }||q|t j|jd|jd||z |j} Wntk r|j} YnX| } t | ||| |t jdS)z8Inner logic to save instance. Based off pickle.save_instN__getinitargs__r ) __class__dispatchrmemorrrHr rKr _keep_aliverbinOBJINSTr$r/r __getstate__r1rBUILD) rr!rfrrrrrgetstatestuffrrr save_insts>           zCloudPickler.save_instcCs$|jt|j|j|j|jf|ddSr)rrfgetfsetfdelrrrrr save_propertyszCloudPickler.save_propertycCs |j}|jt||f|ddSr)rrr)rr!Z orig_funcrrrsave_classmethodszCloudPickler.save_classmethodcCs6Gddd}||}t|ts(|f}|tj|S)z5itemgetter serializer (needed for namedtuple support)c@seZdZddZdS)z+CloudPickler.save_itemgetter..DummycSs|Sr r)ritemrrr __getitem__sz7CloudPickler.save_itemgetter..Dummy.__getitem__N)r/r$r.rrrrrDummysr )r?tupleroperator itemgetter)rr!r r)rrrsave_itemgetters   zCloudPickler.save_itemgettercCs2Gdddt}g}||||tjt|S)zattrgetter serializerc@seZdZdddZddZdS)z+CloudPickler.save_attrgetter..DummyNcSs||_||_dSr )attrsindex)rr%r&rrrrsz4CloudPickler.save_attrgetter..Dummy.__init__cSsXt|d}t|d}|dkr4t|}||nd|||g||<t|||S)Nr%r&rF)object__getattribute__rKrMjoinr)rrr%r&rrrr(s   z.Dummy.__getattribute__)N)r/r$r.rr(rrrrr s r )r'rr" attrgetterr!)rr!r r%rrrsave_attrgetters  zCloudPickler.save_attrgettercCsvz ddl}Wntk r(ddl}YnXt|dr>t|dsHtd|tjkrf|jt tdf|dS|tj kr|jt tdf|dS|tj krtd |j rtd t|d r| rtd d |jkrd|jkrtd|j|j}|}z(|}|d|}||Wn$tk rBtd|YnX||||||_||||dS)z Save a filerNr"modez5Cannot pickle files that do not map to an actual filestdoutrstderrzCannot pickle standard inputzCannot pickle closed filesisattyz+Cannot pickle files that map to tty objectsr+z7Cannot pickle files that are not opened for reading: %sz*Cannot pickle file %s as it cannot be read)r ImportErroriorHrrr'r-rr#r.stdinclosedr/r,r"tellseekreadIOErrorrrr)rr!Z pystringIOr"retvalZcurloccontentsrrr save_files@            zCloudPickler.save_filecCs|tddSNr)r _gen_ellipsisrrrr save_ellipsis szCloudPickler.save_ellipsiscCs|tddSr=)r_gen_not_implementedrrrrsave_not_implementedsz!CloudPickler.save_not_implementedcCs|tjt|fdSr )rweakrefWeakSetr&rrrr save_weaksetszCloudPickler.save_weaksetcCs|jtj|jf|ddSr)rlogging getLoggerr"rrrr save_loggerszCloudPickler.save_loggercCs|jtjd|ddS)Nrr)rrErFrrrrsave_root_logger#szCloudPickler.save_root_loggerMappingProxyTypecCs|jtjt|f|ddSr)rr@rIrrrrrsave_mappingproxy)szCloudPickler.save_mappingproxycCsdS)zPPlug in system. Register additional pickling functions if modules already loadedNr)rrrrr/szCloudPickler.inject_addons)N)N)Qr/r$r.rr copyrrr memoryviewrbrbufferrr@rGrrArrXrrrrrrrBuiltinFunctionTyperfloatrZclassmethod_descriptor_type__repr__Zwrapper_descriptor_typeZmethod_wrapper_typer'rVrupperZmethod_descriptorrGetSetDescriptorTypestructrr ClassTyper rrZ InstanceTyperrr classmethod staticmethodr$r"r#r+r*r<r?rAr NameErrorr3 TextIOWrapperrrrDrBrCrGrELoggerrH RootLoggerrHrJrIrrrrrrs      TD4       -    )        rcCs0dtjkrdStjd}t|ds&dS||S)zj Return whether *func* is a Tornado coroutine function. Running coroutines are not supported. z tornado.genFis_coroutine_function)r'r(rHr[rgenrrrr6s    rcCsddlm}||S)Nr)r])Ztornador] coroutiner\rrrrDs rcCst||d|dS)awSerialize obj as bytes streamed into file protocol defaults to cloudpickle.DEFAULT_PROTOCOL which is an alias to pickle.HIGHEST_PROTOCOL. This setting favors maximum communication speed between processes running the same Python version. Set protocol=pickle.DEFAULT_PROTOCOL instead if you need to ensure compatibility with older versions of Python. rN)rr)r!rrrrrrKs rcCs8t}z"t||d}|||WS|XdS)aSerialize obj as a string of bytes allocated in memory protocol defaults to cloudpickle.DEFAULT_PROTOCOL which is an alias to pickle.HIGHEST_PROTOCOL. This setting favors maximum communication speed between processes running the same Python version. Set protocol=pickle.DEFAULT_PROTOCOL instead if you need to ensure compatibility with older versions of Python. rN)rcloserrgetvalue)r!rrcprrrdumpsXs    rbcCst|tj|Sr ) __import__r'r(rsrrrrqsrcCst|}|j||Sr )r@rGrr)r"rmodrrrrvs  rcCstSr )rrrrrr>|sr>cCstSr )rrrrrr@sr@cCs&z|jWStk r tYSXdSr )rW ValueError_empty_cell_valuer]rrrrsrcCs|S)zCreate a new instance of a class. Parameters ---------- cls : type The class to create an instance of. Returns ------- instance : cls A new instance of ``cls``. rrrrrinstances rhc@seZdZdZeddZdS)rfz sentinel for empty closures cCs|jSr )r/rgrrr __reduce__sz_empty_cell_value.__reduce__N)r/r$r.rrUrirrrrrfsrfcGst|dkr|d}|d}nt|dkrV|d}ddddg}tt||dd }nHt|d kr|d}dddd dg}tt||dd }ntd |f|j|d|d|_|d|_d |kr|d |_d|kr|d|_ d|kr|d|_ d |kr |d |_ d|kr |d|_ d|kr4|d|_ d|krH|d|j}|d k rt||dD]\}}|tk rft||qf|S)zFills in the rest of function data into the skeleton function object The skeleton itself is create by _make_skel_func(). rrrvrrrrrNr,z$Unexpected _fill_value arguments: %rrrr"rrr)rKrziprerrrrrrr/r$r.rrrrfr\)rrrkeyscellsrZr[rrrrsF                     rcsfddjdS)NcsSr rrr]rrr^r_z"_make_empty_cell..r)AssertionErrorrrrr]r_make_empty_cellsrocCsR|dkst|tri}t|d<|dkr.)r?rrpr!ranger@rX)rNZ cell_countrrrrrrsrcCs||||}t||S)aBuild dynamic class with an empty __dict__ to be filled once memoized If class_tracker_id is not None, try to lookup an existing class definition matching that id. If none is found, track a newly reconstructed class definition under that id so that other instances stemming from the same class id will also reuse this class definition. The "extra" variable is meant to be a dict (or None) that can be used for forward compatibility shall the need arise. )r)Ztype_constructorr"basesrrextraskeleton_classrrrrs rcCsPd}|D]"\}}|dkr"|}q t|||q |dk rL|D]}||q<|S)zwPut attributes from `class_dict` back on `skeleton_class`. See CloudPickler.save_dynamic_class for more info. Nr)r)setattrregister)rt class_dictrrattrsubclassrrrrs rc Csb|d}|j}|||} |D]\} } | | | <q"||||| } || _|dk rX|| _t|| S)a6Build dynamic enum with an empty __dict__ to be filled once memoized The creation of the enum class is inspired by the code of EnumMeta._create_. If class_tracker_id is not None, try to lookup an existing enum definition matching that id. If none is found, track a newly reconstructed enum definition under that id so that other instances stemming from the same class id will also reuse this enum definition. The "extra" variable is meant to be a dict (or None) that can be used for forward compatibility shall the need arise. rN)r  __prepare__r)__new__r$r.r) rrr"rrr,rrsZ enum_basemetacls classdict member_name member_value enum_classrrrr&s  rc Cst|drdSt|dr|jdk r&dS|jdd}|rxztj|}Wn&tk rnd}t||Yq|X|j }nd}t |j||dkSddl }zJd}|j dD]4}|dk r|g}| ||\}}} |dk r|qWntk rYdSXdSdS) z^ Return True if the module is special module that cannot be imported by its name. rF__spec__NrFrzparent {!r} not in sys.modulesT)rHrr/ rpartitionr'r(rr2formatrr imprL find_moduler_) r, parent_namer3rpkgpathrpathpartr descriptionrrrr0Gs6   r0)N)N)N)N)er __future__rr functoolsrr3rrErr"rplatformrSr' tracebackr@rBr threadingenumrr2HIGHEST_PROTOCOLrWeakKeyDictionaryrWeakValueDictionaryrLockr python_implementationrrrrOr{rarVr cStringIOr basestringrrrbrTr r rZimportlib._bootstrapr r;rrrrr-r4rBrRr\rorYopmaprprqrrr|rzr{rrr)rvrtr=rrrrrrbloadloadsrrr>r@rrhr'rfrrorrrrr0rrrrs*             &/A-        f A !