| 1 |  |  | from typing import Callable, Optional, Tuple | 
            
                                                        
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 3 |  |  | from jsons._common_impl import JSON_KEYS | 
            
                                                        
            
                                    
            
            
                | 4 |  |  | from jsons._load_impl import load | 
            
                                                        
            
                                    
            
            
                | 5 |  |  | from jsons.exceptions import DeserializationError | 
            
                                                        
            
                                    
            
            
                | 6 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 7 |  |  | from typish import get_args | 
            
                                                        
            
                                    
            
            
                | 8 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 9 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 10 |  |  | def default_dict_deserializer( | 
            
                                                        
            
                                    
            
            
                | 11 |  |  |         obj: dict, | 
            
                                                        
            
                                    
            
            
                | 12 |  |  |         cls: type, | 
            
                                                        
            
                                    
            
            
                | 13 |  |  |         *, | 
            
                                                        
            
                                    
            
            
                | 14 |  |  |         key_transformer: Optional[Callable[[str], str]] = None, | 
            
                                                        
            
                                    
            
            
                | 15 |  |  |         **kwargs) -> dict: | 
            
                                                        
            
                                    
            
            
                | 16 |  |  |     """ | 
            
                                                        
            
                                    
            
            
                | 17 |  |  |     Deserialize a dict by deserializing all instances of that dict. | 
            
                                                        
            
                                    
            
            
                | 18 |  |  |     :param obj: the dict that needs deserializing. | 
            
                                                        
            
                                    
            
            
                | 19 |  |  |     :param key_transformer: a function that transforms the keys to a different | 
            
                                                        
            
                                    
            
            
                | 20 |  |  |     style (e.g. PascalCase). | 
            
                                                        
            
                                    
            
            
                | 21 |  |  |     :param cls: not used. | 
            
                                                        
            
                                    
            
            
                | 22 |  |  |     :param kwargs: any keyword arguments. | 
            
                                                        
            
                                    
            
            
                | 23 |  |  |     :return: a deserialized dict instance. | 
            
                                                        
            
                                    
            
            
                | 24 |  |  |     """ | 
            
                                                        
            
                                    
            
            
                | 25 |  |  |     key_tfr = key_transformer or (lambda key: key) | 
            
                                                        
            
                                    
            
            
                | 26 |  |  |     cls_args = get_args(cls) | 
            
                                                        
            
                                    
            
            
                | 27 |  |  |     kwargs_ = {**kwargs, 'key_transformer': key_transformer} | 
            
                                                        
            
                                    
            
            
                | 28 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 29 |  |  |     (obj_, had_stored_keys) = _load_hashed_keys(obj, cls, cls_args, | 
            
                                                        
            
                                    
            
            
                | 30 |  |  |                                                 key_transformer=key_transformer, **kwargs) | 
            
                                                        
            
                                    
            
            
                | 31 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 32 |  |  |     if len(cls_args) == 2: | 
            
                                                        
            
                                    
            
            
                | 33 |  |  |         cls_k, cls_v = cls_args | 
            
                                                        
            
                                    
            
            
                | 34 |  |  |         kwargs_k = {**kwargs_, 'cls': cls_k} | 
            
                                                        
            
                                    
            
            
                | 35 |  |  |         kwargs_v = {**kwargs_, 'cls': cls_v} | 
            
                                                        
            
                                    
            
            
                | 36 |  |  |         if (had_stored_keys and | 
            
                                                        
            
                                    
            
            
                | 37 |  |  |                 not any(issubclass(type(cls_k), json_key) for json_key in JSON_KEYS)): | 
            
                                                        
            
                                    
            
            
                | 38 |  |  |             # There were hashed keys and the key is not a json key, therefore | 
            
                                                        
            
                                    
            
            
                | 39 |  |  |             # the key must have been hashed and therefore loaded already during _load_hashed_keys | 
            
                                                        
            
                                    
            
            
                | 40 |  |  |             # double deserializing under strict will fail, so avoid doing so. | 
            
                                                        
            
                                    
            
            
                | 41 |  |  |             res = {key_tfr(k): load(obj_[k], **kwargs_v) | 
            
                                                        
            
                                    
            
            
                | 42 |  |  |                    for k in obj_} | 
            
                                                        
            
                                    
            
            
                | 43 |  |  |         else: | 
            
                                                        
            
                                    
            
            
                | 44 |  |  |             # The key was either inherently json compatible or serialized to be so, thus | 
            
                                                        
            
                                    
            
            
                | 45 |  |  |             # avoiding hashed keys | 
            
                                                        
            
                                    
            
            
                | 46 |  |  |             res = {load(key_tfr(k), **kwargs_k): load(obj_[k], **kwargs_v) | 
            
                                                        
            
                                    
            
            
                | 47 |  |  |                    for k in obj_} | 
            
                                                        
            
                                    
            
            
                | 48 |  |  |     else: | 
            
                                                        
            
                                    
            
            
                | 49 |  |  |         res = {key_tfr(key): load(obj_[key], **kwargs_) | 
            
                                                        
            
                                    
            
            
                | 50 |  |  |                for key in obj_} | 
            
                                                        
            
                                    
            
            
                | 51 |  |  |     return res | 
            
                                                        
            
                                    
            
            
                | 52 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 53 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 54 |  |  | def _load_hashed_keys(obj: dict, cls: type, cls_args: tuple, **kwargs) -> Tuple[dict, bool]: | 
            
                                                        
            
                                    
            
            
                | 55 |  |  |     # Load any hashed keys and return a copy of the given obj if any hashed | 
            
                                                        
            
                                    
            
            
                | 56 |  |  |     # keys are unpacked. | 
            
                                                        
            
                                    
            
            
                | 57 |  |  |     result = obj | 
            
                                                        
            
                                    
            
            
                | 58 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 59 |  |  |     stored_keys = set(obj.get('-keys', set())) | 
            
                                                        
            
                                    
            
            
                | 60 |  |  |     if stored_keys: | 
            
                                                        
            
                                    
            
            
                | 61 |  |  |         # Apparently, there are stored hashed keys, we need to unpack them. | 
            
                                                        
            
                                    
            
            
                | 62 |  |  |         if len(cls_args) != 2: | 
            
                                                        
            
                                    
            
            
                | 63 |  |  |             raise DeserializationError('A detailed type is needed for cls of ' | 
            
                                                        
            
                                    
            
            
                | 64 |  |  |                                        'the form Dict[<type>, <type>] to ' | 
            
                                                        
            
                                    
            
            
                | 65 |  |  |                                        'deserialize a dict with hashed keys.', | 
            
                                                        
            
                                    
            
            
                | 66 |  |  |                                        obj, cls) | 
            
                                                        
            
                                    
            
            
                | 67 |  |  |         result = {**obj} | 
            
                                                        
            
                                    
            
            
                | 68 |  |  |         key_type = cls_args[0] | 
            
                                                        
            
                                    
            
            
                | 69 |  |  |         for key in stored_keys: | 
            
                                                        
            
                                    
            
            
                | 70 |  |  |             # Get the original (unhashed) key and load it. | 
            
                                                        
            
                                    
            
            
                | 71 |  |  |             original_key = result['-keys'][key] | 
            
                                                        
            
                                    
            
            
                | 72 |  |  |             loaded_key = load(original_key, cls=key_type, **kwargs) | 
            
                                                        
            
                                    
            
            
                | 73 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 74 |  |  |             # Replace the hashed key by the loaded key entirely. | 
            
                                                        
            
                                    
            
            
                | 75 |  |  |             result[loaded_key] = result[key] | 
            
                                                        
            
                                    
            
            
                | 76 |  |  |             del result['-keys'][key] | 
            
                                                        
            
                                    
            
            
                | 77 |  |  |             del result[key] | 
            
                                                        
            
                                    
            
            
                | 78 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 79 |  |  |         del result['-keys'] | 
            
                                                        
            
                                    
            
            
                | 80 |  |  |     return (result, len(stored_keys) > 0) | 
            
                                                        
            
                                    
            
            
                | 81 |  |  |  |