Exemplo n.º 1
0
def _closuredimport(func, alias='', builtin=False):
    """get import for closured objects; return a dict of 'name' and 'import'"""
    import re
    from dill.detect import freevars, outermost
    free_vars = freevars(func)
    func_vars = {}
    # split into 'funcs' and 'non-funcs'
    for name,obj in list(free_vars.items()):
        if not isfunction(obj): continue
        # get import for 'funcs'
        fobj = free_vars.pop(name)
        src = getsource(fobj)
        if src.lstrip().startswith('@'): # we have a decorator
            src = getimport(fobj, alias=alias, builtin=builtin)
        else: # we have to "hack" a bit... and maybe be lucky
            encl = outermost(func)
            # pattern: 'func = enclosing(fobj'
            pat = '.*[\w\s]=\s*'+getname(encl)+'\('+getname(fobj)
            mod = getname(getmodule(encl))
            #HACK: get file containing 'outer' function; is func there?
            lines,_ = findsource(encl)
            candidate = [line for line in lines if getname(encl) in line and \
                         re.match(pat, line)]
            if not candidate:
                mod = getname(getmodule(fobj))
                #HACK: get file containing 'inner' function; is func there? 
                lines,_ = findsource(fobj)
                candidate = [line for line in lines \
                             if getname(fobj) in line and re.match(pat, line)]
            if not len(candidate): raise TypeError('import could not be found')
            candidate = candidate[-1]
            name = candidate.split('=',1)[0].split()[-1].strip()
            src = _getimport(mod, name, alias=alias, builtin=builtin)
        func_vars[name] = src
    if not func_vars:
        name = outermost(func)
        mod = getname(getmodule(name))
        if not mod or name is func: # then it can be handled by getimport
            name = getname(func, force=True) #XXX: better key?
            src = getimport(func, alias=alias, builtin=builtin)
        else:
            lines,_ = findsource(name)
            # pattern: 'func = enclosing('
            candidate = [line for line in lines if getname(name) in line and \
                         re.match('.*[\w\s]=\s*'+getname(name)+'\(', line)]
            if not len(candidate): raise TypeError('import could not be found')
            candidate = candidate[-1]
            name = candidate.split('=',1)[0].split()[-1].strip()
            src = _getimport(mod, name, alias=alias, builtin=builtin)
        func_vars[name] = src
    return func_vars
Exemplo n.º 2
0
def _closuredimport(func, alias='', builtin=False):
    """get import for closured objects; return a dict of 'name' and 'import'"""
    import re
    from dill.detect import freevars, outermost
    free_vars = freevars(func)
    func_vars = {}
    # split into 'funcs' and 'non-funcs'
    for name,obj in list(free_vars.items()):
        if not isfunction(obj): continue
        # get import for 'funcs'
        fobj = free_vars.pop(name)
        src = getsource(fobj)
        if src.lstrip().startswith('@'): # we have a decorator
            src = getimport(fobj, alias=alias, builtin=builtin)
        else: # we have to "hack" a bit... and maybe be lucky
            encl = outermost(func)
            # pattern: 'func = enclosing(fobj'
            pat = '.*[\w\s]=\s*'+getname(encl)+'\('+getname(fobj)
            mod = getname(getmodule(encl))
            #HACK: get file containing 'outer' function; is func there?
            lines,_ = findsource(encl)
            candidate = [line for line in lines if getname(encl) in line and \
                         re.match(pat, line)]
            if not candidate:
                mod = getname(getmodule(fobj))
                #HACK: get file containing 'inner' function; is func there? 
                lines,_ = findsource(fobj)
                candidate = [line for line in lines \
                             if getname(fobj) in line and re.match(pat, line)]
            if not len(candidate): raise TypeError('import could not be found')
            candidate = candidate[-1]
            name = candidate.split('=',1)[0].split()[-1].strip()
            src = _getimport(mod, name, alias=alias, builtin=builtin)
        func_vars[name] = src
    if not func_vars:
        name = outermost(func)
        mod = getname(getmodule(name))
        if not mod or name is func: # then it can be handled by getimport
            name = getname(func, force=True) #XXX: better key?
            src = getimport(func, alias=alias, builtin=builtin)
        else:
            lines,_ = findsource(name)
            # pattern: 'func = enclosing('
            candidate = [line for line in lines if getname(name) in line and \
                         re.match('.*[\w\s]=\s*'+getname(name)+'\(', line)]
            if not len(candidate): raise TypeError('import could not be found')
            candidate = candidate[-1]
            name = candidate.split('=',1)[0].split()[-1].strip()
            src = _getimport(mod, name, alias=alias, builtin=builtin)
        func_vars[name] = src
    return func_vars
Exemplo n.º 3
0
def getimport(obj, alias='', verify=True, builtin=False, enclosing=False):
    """get the likely import string for the given object

    obj is the object to inspect
    If verify=True, then test the import string before returning it.
    If builtin=True, then force an import for builtins where possible.
    If enclosing=True, get the import for the outermost enclosing callable.
    If alias is provided, then rename the object on import.
    """
    if enclosing:
        from dill.detect import outermost
        _obj = outermost(obj)
        obj = _obj if _obj else obj
    # get the namespace
    qual = _namespace(obj)
    head = '.'.join(qual[:-1])
    tail = qual[-1]
    # for named things... with a nice repr #XXX: move into _namespace?
    try:  # look for '<...>' and be mindful it might be in lists, dicts, etc...
        name = repr(obj).split('<', 1)[1].split('>', 1)[1]
        name = None  # we have a 'object'-style repr
    except:  # it's probably something 'importable'
        if head in ['builtins', '__builtin__']:
            name = repr(obj)  #XXX: catch [1,2], (1,2), set([1,2])... others?
        else:
            name = repr(obj).split('(')[0]

#if not repr(obj).startswith('<'): name = repr(obj).split('(')[0]
#else: name = None
    if name:  # try using name instead of tail
        try:
            return _getimport(head, name, alias, verify, builtin)
        except ImportError:
            pass
        except SyntaxError:
            if head in ['builtins', '__builtin__']:
                _alias = '%s = ' % alias if alias else ''
                if alias == name: _alias = ''
                return _alias + '%s\n' % name
            else:
                pass
    try:
        #if type(obj) is type(abs): _builtin = builtin # BuiltinFunctionType
        #else: _builtin = False
        return _getimport(head, tail, alias, verify, builtin)
    except ImportError:
        raise  # could do some checking against obj
    except SyntaxError:
        if head in ['builtins', '__builtin__']:
            _alias = '%s = ' % alias if alias else ''
            if alias == tail: _alias = ''
            return _alias + '%s\n' % tail
        raise  # could do some checking against obj
Exemplo n.º 4
0
def getimport(obj, alias='', verify=True, builtin=False, enclosing=False):
    """get the likely import string for the given object

    obj is the object to inspect
    If verify=True, then test the import string before returning it.
    If builtin=True, then force an import for builtins where possible.
    If enclosing=True, get the import for the outermost enclosing callable.
    If alias is provided, then rename the object on import.
    """
    if enclosing:
        from dill.detect import outermost
        _obj = outermost(obj)
        obj = _obj if _obj else obj
    # get the namespace
    qual = _namespace(obj)
    head = '.'.join(qual[:-1])
    tail = qual[-1]
    # for named things... with a nice repr #XXX: move into _namespace?
    try: # look for '<...>' and be mindful it might be in lists, dicts, etc...
        name = repr(obj).split('<',1)[1].split('>',1)[1]
        name = None # we have a 'object'-style repr
    except: # it's probably something 'importable'
        if head in ['builtins','__builtin__']:
            name = repr(obj) #XXX: catch [1,2], (1,2), set([1,2])... others?
        else:
            name = repr(obj).split('(')[0]
   #if not repr(obj).startswith('<'): name = repr(obj).split('(')[0]
   #else: name = None
    if name: # try using name instead of tail
        try: return _getimport(head, name, alias, verify, builtin)
        except ImportError: pass
        except SyntaxError:
            if head in ['builtins','__builtin__']:
                _alias = '%s = ' % alias if alias else ''
                if alias == name: _alias = ''
                return _alias+'%s\n' % name
            else: pass
    try:
       #if type(obj) is type(abs): _builtin = builtin # BuiltinFunctionType
       #else: _builtin = False
        return _getimport(head, tail, alias, verify, builtin)
    except ImportError:
        raise # could do some checking against obj
    except SyntaxError:
        if head in ['builtins','__builtin__']:
            _alias = '%s = ' % alias if alias else ''
            if alias == tail: _alias = ''
            return _alias+'%s\n' % tail
        raise # could do some checking against obj