Esempio n. 1
0
def auto_converter(tt):
    '''Auto convert attempt a number of ways of finding appropriate converters 
    to a unhandled type.
    
    The first strategy is to check if the type is supported in the 
    mod:`pyson.jsonfy_extras` module.
    
    If that is not the case, it searches for converters for the superclasses
    of `tt`.
    
    Finally, if that fails an error is raised.
    '''

    # Tries to import a converter from jsonfy_ext.* modules
    name = type2name(tt)
    try:
        load_modules('pyson.jsonfy_extras.ext_' + name)
    except AttributeError:
        pass
    try:
        return CONVERTERS[tt]
    except KeyError:
        pass

    # Tries to use a converter for a base class (hint: this often fails!)
    for base_t in tt.mro()[:-1]:
        try:
            return CONVERTERS[base_t]
        except KeyError:
            pass
    else:
        raise TypeError('object of type %s is not supported' % tt)
        def not_supported(obj):
            raise TypeError('object of type %s is not supported' % tt)
        return not_supported
Esempio n. 2
0
def jsonfy(obj, json_level=None, print_type=True, invertible=False, recursive=True):
    '''Return a JSON representation of object.
    
    Parameters
    ----------
    obj : anything
        Object to be converted to JSON
    json_level : int
        Maximum JSON level allowed for the given type.
    print_type : bool
        Set to False to prevent adding the ('@type': value) pair to the 
        resulting object. This key is used to convert the JSON object to 
        the appropriate Python type.
    invertible : bool
        If True, the output can be converted back to an identical Python object.
        The default behavior is to allow approximate types, e.g., ``str``
        can be converted to ``unicode``, ``tuple`` to ``list`` and so on.
    recursive : bool
        If False and json_level is respected or not set, it prevents recursive
        application of func:`jsonfy` to child nodes of the JSON result.  
    '''

    tt = type(obj)
    if json_level is not None or invertible:
        raise NotImplementedError

    # Compute the result from the converter function
    try:
        function = CONVERTERS[tt]
    except KeyError:
        function = auto_converter(tt)
    try:
        result = function(obj)
    except Exception as ex:
        msg = 'unhandled exception raised when jsonfy-ing %s object\n    %s: %s'
        msg = msg % (type(obj), type(ex).__name__, ex)
        raise RuntimeError(msg)

    # Print type
    if print_type and not is_object_t(tt):
        try:
            result[u'@type'] = type2name(tt)
        except:
            pass

    #TODO: move recursive to converter function
    if recursive:
        if isinstance(result, dict):
            for k, v in result.items():
                result[k] = jsonfy(v, json_level=json_level, print_type=print_type,
                                      invertible=invertible, recursive=recursive)
        elif isinstance(result, list):
            for idx, v in enumerate(result):
                result[idx] = jsonfy(v, json_level=json_level, print_type=print_type,
                                        invertible=invertible, recursive=recursive)

    return result
Esempio n. 3
0
def unjsonfy(json, tt=None, recursive=True, inplace=False, lazy=True):
    """Create object from its JSON representation
    
    Parameters
    ----------
    json : JSON-like
        JSON-like structure to be converted to a Python object.
    tt (optional): type
        Type of the output object (can be inferred from the '@type' key, if 
        ``json`` has it. 
    recursive : bool
        If False, prevents recursive application of func:`jsonfy` to child nodes 
        of the JSON input.
    """

    if tt is None:
        try:
            tt = json[u"@type"]
        except:
            if not lazy:
                raise ValueError("'tt' must be set explicity if 'json' does not have a '@type' key")
            else:
                tt = None
        else:
            tt = name2type(tt)

    # TODO: move 'inplace' and 'recursive' to the converter function
    if not inplace:
        json = deepcopy(json)
    if recursive:
        if isinstance(json, dict):
            for k, v in json.items():
                json[k] = unjsonfy(v, recursive=True, inplace=True)
        elif isinstance(json, list):
            for idx, v in enumerate(json):
                json[idx] = unjsonfy(v, recursive=True, inplace=True)

    # Compute the result from the converter function
    try:
        converter = CONVERTERS[tt]
    except KeyError:
        # Tries to load converters from unjsonfy_extras
        try:
            load_modules("pyson.unjsonfy_extras.ext_" + type2name(tt))
        except AttributeError:
            pass

        try:
            converter = CONVERTERS[tt]
        except KeyError:
            if tt is None:
                return json
            raise ValueError("there is no known converter to type %s" % tt)

    return converter(json)
Esempio n. 4
0
def unjsonfy(json, tt=None, recursive=True, inplace=False, lazy=True):
    '''Create object from its JSON representation
    
    Parameters
    ----------
    json : JSON-like
        JSON-like structure to be converted to a Python object.
    tt (optional): type
        Type of the output object (can be inferred from the '@type' key, if 
        ``json`` has it. 
    recursive : bool
        If False, prevents recursive application of func:`jsonfy` to child nodes 
        of the JSON input.
    '''

    if tt is None:
        try:
            tt = json[u'@type']
        except:
            if not lazy:
                raise ValueError("'tt' must be set explicity if 'json' does not have a '@type' key")
            else:
                tt = None
        else:
            tt = name2type(tt)

    #TODO: move 'inplace' and 'recursive' to the converter function 
    if not inplace:
        json = deepcopy(json)
    if recursive:
        if isinstance(json, dict):
            for k, v in json.items():
                json[k] = unjsonfy(v, recursive=True, inplace=True)
        elif isinstance(json, list):
            for idx, v in enumerate(json):
                json[idx] = unjsonfy(v, recursive=True, inplace=True)

    # Compute the result from the converter function
    try:
        converter = CONVERTERS[tt]
    except KeyError:
        # Tries to load converters from unjsonfy_extras
        try: load_modules('pyson.unjsonfy_extras.ext_' + type2name(tt))
        except AttributeError: pass

        try:
            converter = CONVERTERS[tt]
        except KeyError:
            if tt is None:
                return json
            raise ValueError('there is no known converter to type %s' % tt)

    return converter(json)
Esempio n. 5
0
def auto_converter(tt):
    '''Auto convert attempt a number of ways of finding appropriate converters 
    to a unhandled type.
    
    The first strategy is to check if the type is supported in the 
    mod:`pyson.jsonfy_extras` module.
    
    If that is not the case, it searches for converters for the superclasses
    of `tt`.
    
    Finally, if that fails an error is raised.
    '''

    # Tries to import a converter from jsonfy_ext.* modules
    name = type2name(tt)
    try:
        load_modules('pyson.jsonfy_extras.ext_' + name)
    except AttributeError:
        pass
    try:
        return CONVERTERS[tt]
    except KeyError:
        pass

    # Tries to use a converter for a base class (hint: this often fails!)
    for base_t in tt.mro()[:-1]:
        try:
            return CONVERTERS[base_t]
        except KeyError:
            pass
    else:
        raise TypeError('object of type %s is not supported' % tt)

        def not_supported(obj):
            raise TypeError('object of type %s is not supported' % tt)

        return not_supported
Esempio n. 6
0
def jsonfy(obj,
           json_level=None,
           print_type=True,
           invertible=False,
           recursive=True):
    '''Return a JSON representation of object.
    
    Parameters
    ----------
    obj : anything
        Object to be converted to JSON
    json_level : int
        Maximum JSON level allowed for the given type.
    print_type : bool
        Set to False to prevent adding the ('@type': value) pair to the 
        resulting object. This key is used to convert the JSON object to 
        the appropriate Python type.
    invertible : bool
        If True, the output can be converted back to an identical Python object.
        The default behavior is to allow approximate types, e.g., ``str``
        can be converted to ``unicode``, ``tuple`` to ``list`` and so on.
    recursive : bool
        If False and json_level is respected or not set, it prevents recursive
        application of func:`jsonfy` to child nodes of the JSON result.  
    '''

    tt = type(obj)
    if json_level is not None or invertible:
        raise NotImplementedError

    # Compute the result from the converter function
    try:
        function = CONVERTERS[tt]
    except KeyError:
        function = auto_converter(tt)
    try:
        result = function(obj)
    except Exception as ex:
        msg = 'unhandled exception raised when jsonfy-ing %s object\n    %s: %s'
        msg = msg % (type(obj), type(ex).__name__, ex)
        raise RuntimeError(msg)

    # Print type
    if print_type and not is_object_t(tt):
        try:
            result[u'@type'] = type2name(tt)
        except:
            pass

    #TODO: move recursive to converter function
    if recursive:
        if isinstance(result, dict):
            for k, v in result.items():
                result[k] = jsonfy(v,
                                   json_level=json_level,
                                   print_type=print_type,
                                   invertible=invertible,
                                   recursive=recursive)
        elif isinstance(result, list):
            for idx, v in enumerate(result):
                result[idx] = jsonfy(v,
                                     json_level=json_level,
                                     print_type=print_type,
                                     invertible=invertible,
                                     recursive=recursive)

    return result