B t1`d@sddlmZmZmZddlZddlZddlmZddlmZddlm Z ddlm Z ddlm Z dd l m Z d(d d ZddZddZGdddeZGdddeZddZddZGdddeZd)ddZd*ddZGd d!d!Zd"d#Zd$d%Zd&d'ZdS)+)absolute_importdivisionunicode_literalsN)compat)util)tags)handlers) numeric_types)jsonFTcCs4|pt}|pt|||d}||}|j|||dS)aConvert a JSON string into a Python object. The keyword argument 'keys' defaults to False. If set to True then jsonpickle will decode non-string dictionary keys into python objects via the jsonpickle protocol. The keyword argument 'classes' defaults to None. If set to a single class, or a sequence (list, set, tuple) of classes, then the classes will be made available when constructing objects. This can be used to give jsonpickle access to local classes that are not available through the global module import scope. The keyword argument 'safe' defaults to False. If set to True, eval() is avoided, but backwards-compatible (pre-0.7.0) deserialization of repr-serialized objects is disabled. The keyword argument 'backend' defaults to None. If set to an instance of jsonpickle.backend.JSONBackend, jsonpickle will use that backend for deserialization. >>> decode('"my string"') == 'my string' True >>> decode('36') 36 )keysbackendsafe)resetclasses)r Unpicklerdecoderestore)stringr contextr rrrdatar8/tmp/pip-unpacked-wheel-wy5q9vwy/jsonpickle/unpickler.pyrs rcCs*yt||dStk r$dSXdS)zBWorkaround unreliable hasattr() availability on sqlalchemy objectsTFN)object__getattribute__AttributeError)objattrrrr _safe_hasattr5s  rcCst|tjo|tjS)zsr$c@s(eZdZdZddZddZddZdS) _ProxyaProxies are dummy objects that are later replaced by real instances The `restore()` function has to solve a tricky problem when pickling objects with cyclical references -- the parent instance does not yet exist. The problem is that `__getnewargs__()`, `__getstate__()`, custom handlers, and cyclical objects graphs are allowed to reference the yet-to-be-created object via the referencing machinery. In other words, objects are allowed to depend on themselves for construction! We solve this problem by placing dummy Proxy objects into the referencing machinery so that we can construct the child objects before constructing the parent. Objects are initially created with Proxy attribute values instead of real references. We collect all objects that contain references to proxies and run a final sweep over them to swap in the real instance. This is done at the very end of the top-level `restore()`. The `instance` attribute below is replaced with the real instance after `__new__()` has been used to construct the object and is used when swapping proxies with real instances. cCs d|_dS)N)instance)selfrrr__init__`sz_Proxy.__init__cCs|jS)N)r&)r'rrrgetcsz _Proxy.getcCs ||_dS)N)r&)r'r&rrrrfsz _Proxy.resetN)__name__ __module__ __qualname____doc__r(r)rrrrrr%Csr%c@seZdZddZddZdS)_IDProxycCs||_||_dS)N)_index_objs)r'objsindexrrrr(ksz_IDProxy.__init__cCs |j|jS)N)r0r/)r'rrrr)osz _IDProxy.getN)r*r+r,r(r)rrrrr.jsr.cCst|||dS)N)setattrr))rrproxyrrr _obj_setattrssr5cCs|||<dS)N)r))ridxr4rrr _obj_setvaluewsr7c@seZdZdDddZddZdEdd Zd d Zd d ZddZddZ ddZ ddZ ddZ ddZ ddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+ZdFd,d-Zd.d/Zd0d1Zd2d3Zd4d5Zd6d7Zd8d9Zd:d;Zdd?Z d@dAZ!dBdCZ"dS)GrNFcCs"|pt|_||_||_|dS)N)r r r rr)r'r r rrrrr(|s zUnpickler.__init__cCs(i|_g|_i|_g|_g|_i|_dS)z#Resets the object's internal state.N) _namedict _namestack _obj_to_idxr0_proxies_classes)r'rrrrs zUnpickler.resetTcCs4|r ||r||||}|r0||S)a#Restores a flattened object to its original python state. Simply returns any of the basic builtin types >>> u = Unpickler() >>> u.restore('hello world') == 'hello world' True >>> u.restore({'key': 'value'}) == {'key': 'value'} True )rregister_classes_restore _swap_proxies)r'rrrvaluerrrrs   zUnpickler.restorecCs>t|tttfr*x(|D]}||qWn||jt|<dS)zqRegister one or more classes :param classes: sequence of classes or a single class to register N)rlisttuplesetr=r<rZimportable_name)r'rclsrrrr=s zUnpickler.register_classescCs.x"|jD]\}}}}||||qWg|_dS)z2Replace proxies with their corresponding instancesN)r;)r'rrr4methodrrrr?szUnpickler._swap_proxiescCs0t|tttttfsdd}n ||}||S)NcSs|S)Nr)xrrrrsz#Unpickler._restore..restore)rstrrAdictrCrB _restore_tags)r'rrrrrr>s  zUnpickler._restorecCsy.tjt|ks,t|ttfkr,dd}|SWntk rBYnXt|tjrZ|j }n,t|tj rp|j }nt|tj r|j }nt|tjr|j}nt|tjr|j}nt|tjr|j}nt|tjr|j}nt|tjr|j}nt|tjr|j}nt|tjr|j}nrt|tjr*|j}n\t|r>|j }nHt|tj!rT|j"}n2t|tj#rj|j$}nt%|r~|j&}ndd}|S)NcSs|S)Nr)rFrrrrsz(Unpickler._restore_tags..restorecSs|S)Nr)rFrrrrs)'rRESERVEDrCtyperArH TypeErrorhas_tagB64_restore_base64B85_restore_base85ID _restore_idITERATOR_restore_iteratorTYPE _restore_typeREDUCE_restore_reduceOBJECT_restore_objectFUNCTION_restore_functionBYTES_restore_quopriREF _restore_refREPR _restore_reprrZis_list _restore_listTUPLE_restore_tupleSET _restore_setZ is_dictionary _restore_dict)r'rrrrrrIsL              zUnpickler._restore_tagscCst|tjdS)Nzutf-8)r b64decoderrNencode)r'rrrrrOszUnpickler._restore_base64cCst|tjdS)Nzutf-8)r b85decoderrPrk)r'rrrrrQszUnpickler._restore_base85cCst|tjdS)Nzutf-8)quopri decodestringrr^rk)r'rrrrr_szUnpickler._restore_quopricCst||tjS)N)iterrdrrT)r'rrrrrUszUnpickler._restore_iteratorcCs,t}||tt|j|tj}t|dkrJ|dgdt||\}}}}}|tj ksrt |dddkr|d} t | t s|| } | j | f|dd} n||} |ry| |Wntk ry.x"| jD]\} } || | qW|| _Wntk ry(x"|D]\} } t| | | q"WWnZtk r|\} }| rj| j| |rx"|D]\} } t| | | qzWYnXYnXYnX|ry| |Wn0tk rx|D]}| |qWYnX|rx|D]\} } | | | qW|| ||| | S)z Supports restoring with all elements of __reduce__ as per pep 307. Assumes that iterator items (the last two) are represented as lists as per pickler implementation. Nr* __newobj__rr)r%_mkrefrAmapr>rrXlenextendNEWOBJgetattrrrK__new__ __setstate__r__dict__items setdefaultr3 Exceptionupdateappend __setitem__r_swapref)r'rr4Z reduce_valfargsstate listitems dictitemsrDZstage1kvZ dict_stateZ slots_staterFrrrrYsV      $   zUnpickler._restore_reducecCs6y|tj}|j|Stk r0t|j|SXdS)N)rrRr0 IndexErrorr.)r'rr6rrrrSAs   zUnpickler._restore_idcCs|j|tjS)N)r8r)rr`)r'rrrrraHszUnpickler._restore_refcCs$t|tj|jd}|dkr |S|S)N)r) loadclassrrVr<)r'rtyperefrrrrWKszUnpickler._restore_typecCs"|jr dSt|tj}||S)N)rloadreprrrbrs)r'rrrrrcQszUnpickler._restore_reprcCs|tj}t||jd}t|t|}|dk rjt}|||||}| || |||S|dkr|||S| ||S)N)r) rrZrr<r r)r%rsrrr_restore_object_instance)r'r class_namerDhandlerr4r&rrrr[Xs     zUnpickler._restore_objectcCst|tj|jdS)N)r)rrr\r<)r'rrrrr]iszUnpickler._restore_functioncCs2y |d}Wntk r dSX|d=||S)Ndefault_factory)KeyErrorr>)r'rrrrr _loadfactoryls  zUnpickler._loadfactoryc Cst}||||}t|tjr6|tj\}}nt||jd}i}|rV||}|rd||}t |t pxt |dd }yP|st |dr|r|j ||f||}||_q|j |f||}n t |}Wntk rd}YnX|r:y ||}Wn@tk r8y t|}Wntk r2||SXYnX|||||t |tr`|S|||}t|drt |jtr|j|_|S)N)rZ__meta__ryTr)r%rsrrMr NEWARGSEXgetargsr<r>rrKrxhasattrryrrrLmake_blank_classicr~rrrB"_restore_object_instance_variablesrr)) r'rrDr4factoryrkwargsZ is_oldstyler&rrrrtsL              z"Unpickler._restore_object_instancec Cs |}t}i}xt|D]\}}|r4|tjkr4qt|trH|} n|} |j | ||}| |} t |s~t |ry"|dkrt||| n| ||<Wqtk r|dkr| ||<|j wYqXn t||| t| tr|j ||| |f|j qW|r||}|S)Nr{)_restore_key_fnr5rr|rrJrr __str__r9rr>Z is_noncomplexZis_dictionary_subclassr3rLpopr%r; __class__) r'rr&ignorereserved restore_keyrEdeferredrrstr_kr@rrr_restore_from_dicts:          zUnpickler._restore_from_dictcCs|||}t|tjrvt|drHxR|tjD]}|||q.Wn.t|drvx"|tjD]}|||q^Wt|tjr| ||}|S)Nradd) rrMrSEQrrr>rSTATE_restore_state)r'rr&rrrrrs      z,Unpickler._restore_object_instance_variablescCs||tj}t|to2t|dko2t|dt}|oDt|dt}t|dr\||nft|trx|j ||dd}nJ|r|j |d|dd}|r|j |d|dd}nt|dst|ds|}|S) NrrrzF)r__getnewargs____getnewargs_ex__) r>rrrrBrurHrrzr)r'rr&rZ has_slotsZhas_slots_and_dictrrrrs $    zUnpickler._restore_statecsVgfdd|D}|tfddtD}j|S)Ncsg|]}|qSr)r>).0r)r'rr sz+Unpickler._restore_list..cs&g|]\}}t|tr||fqSr)rr%)rr6r@)rEparentrrrs)rsrvr7 enumerater;)r'rchildrenproxiesr)rErr'rrd s     zUnpickler._restore_listcstfdd|tjDS)Ncsg|]}|qSr)r>)rr)r'rrrsz,Unpickler._restore_tuple..)rBrre)r'rr)r'rrfszUnpickler._restore_tuplecsfdd|tjDS)Ncsh|]}|qSr)r>)rr)r'rr sz)Unpickler._restore_set..)rrg)r'rr)r'rrhszUnpickler._restore_setcCs@i}|||jrx\t|D]N\}}t|r2q t|trF|}n|}|j || |||<|j q Wxt|D]b\}}t|sq~|j || |}| |||<}t|t r|j |||tf|j q~WnVxTt|D]F\}}t|tr|}n|}|j || |||<|j qW|S)N)rsr rr|r$rr rr9rr>r_restore_pickled_keyr%r;r7)r'rrrrrresultrrrris:          zUnpickler._restore_dictcCs|jr|j}ndd}|S)zReturn a callable that restores keys This function is responsible for restoring non-string keys when we are decoding with `keys=True`. cSs|S)Nr)r#rrrr]sz.Unpickler._restore_key_fn..restore_key)r r)r'rrrrrMs zUnpickler._restore_key_fncCs.t|r*t|ttjd|j|ddd}|S)zRestore a possibly pickled keyNTF)r rr r)r$rrurr"r )r'r#rrrrbszUnpickler._restore_pickled_keycCsdd|jS)aCalculates the name of the current location in the JSON stack. This is called as jsonpickle traverses the object structure to create references to previously-traversed objects. This allows cyclical data structures such as doubly-linked lists. jsonpickle ensures that duplicate python references to the same object results in only a single JSON object definition and special reference tags to represent each reference. >>> u = Unpickler() >>> u._namestack = [] >>> u._refname() == '/' True >>> u._namestack = ['a'] >>> u._refname() == '/a' True >>> u._namestack = ['a', 'b'] >>> u._refname() == '/a/b' True /)joinr9)r'rrr_refnamenszUnpickler._refnamecCsZt|}y|j|Wn>tk rTt|j|j|<|j|||j|<YnX|S)N)idr:rrur0rr8r)r'rZobj_idrrrrss zUnpickler._mkrefcCsHt|}t|}|j|}||j|<|j|=||j|<||j|<dS)N)rr:r0r8r)r'r4r&Zproxy_idZ instance_idZinstance_indexrrrrs   zUnpickler._swapref)NFF)TN)T)#r*r+r,r(rrr=r?r>rIrOrQr_rUrYrSrarWrcr[r]rrrrrrdrfrhrirrrrsrrrrrr{s@    /?: ./  rc Cs|r"y||Stk r YnX|d}xtt|dddD]p}td|d|}y6t|tj |}x||dD]}t ||}qW|St t t fk rwBYqBXqBWdS)zLoads the module and returns the class. >>> cls = loadclass('datetime.datetime') >>> cls.__name__ 'datetime' >>> loadclass('does.not.exist') >>> loadclass('builtins.int')() 0 .rrN)rsplitrangerurZuntranslate_module_namer __import__sysmodulesrxr ImportError ValueError)Zmodule_and_namernamesZup_tomodulerrrrrrs"   rcCst|tjrtdt|tjr*|tjSt|tjr@|tjSy|tj}|tj}Wntk rlgSXt ||d}|sgSt |drt |j t |kr|SgS)z'Return arguments suitable for __new__()z+__newargs_ex__ returns both args and kwargs)r_fields) rMrrrZNEWARGSZINITARGSrrZrrrrur)rrZseq_listZobj_dictrrrrrs$        rc@seZdZdZdS)_trivialclassicz? A trivial class that can be instantiated with no args N)r*r+r,r-rrrrrsrcCst}||_|S)z Implement the mandated strategy for dealing with classic classes which cannot be instantiated without __getinitargs__ because they take parameters )rr)rDr&rrrrsrcCsD|d\}}t}|}d|kr0|ddd}t|||<t|S)zReturns an instance of the object from the object's repr() string. It involves the dynamic specification of code. >>> obj = loadrepr('datetime/datetime.datetime.now()') >>> obj.__class__.__name__ 'datetime' rrrr)rlocalsreval)ZreprstrrZevalstrZmylocals localnamerrrrs  rcCst|tko||kS)zHelper class that tests to see if the obj is a dictionary and contains a particular key/tag. >>> obj = {'test': 1} >>> has_tag(obj, 'test') True >>> has_tag(obj, 'fail') False >>> has_tag(42, 'fail') False )rKrH)rtagrrrrMsrM)NNFTFN)N)N) __future__rrrrmrrqrrrr r r r rrr$rr%r.r5r7rrrrrrrMrrrrs4       ! ' ' %