示例#1
0
文件: core.py 项目: Erotemic/vimtk
    def current_module_info():
        """
        Returns information about current module

        Example:
            >>> from vimtk._demo import vimmock
            >>> import ubelt as ub
            >>> vim = vimmock.patch_vim()
            >>> vim.setup_text('', 'foo.py')
            >>> info = Python.current_module_info()
            >>> print(ub.repr2(info))
        """
        import ubelt as ub
        import vim

        modpath = vim.current.buffer.name
        modname = ub.modpath_to_modname(modpath, check=False)
        moddir, rel_modpath = ub.split_modpath(modpath, check=False)

        from ubelt.util_import import is_modname_importable
        importable = is_modname_importable(modname, exclude=['.'])
        info = {
            'modname': modname,
            'modpath': modpath,
            'importable': importable,
        }
        return info
示例#2
0
    def parse(ImportVisitor,
              source=None,
              modpath=None,
              modname=None,
              module=None):
        if module is not None:
            if source is None:
                source = inspect.getsource(module)
            if modpath is None:
                modname = module.__name__
            if modname is None:
                modpath = module.__file__

        if modpath is not None:
            if isdir(modpath):
                modpath = join(modpath, '__init__.py')
            if modname is None:
                modname = ub.modpath_to_modname(modpath)

        if modpath is not None:
            if source is None:
                if not modpath.endswith(('.py', '>')):
                    raise NotAPythonFile(
                        'can only parse python files, not {}'.format(modpath))
                source = open(modpath, 'r').read()

        if source is None:
            raise ValueError('unable to derive source code')

        source = ub.ensure_unicode(source)
        pt = ast.parse(source)
        visitor = ImportVisitor(modpath, modname, module, pt=pt)
        visitor.visit(pt)
        return visitor
示例#3
0
def get_current_modulename():
    """
    returns current module being edited

    buffer_name = ub.truepath('~/local/vim/rc/pyvim_funcs.py')
    """
    import vim
    import ubelt as ub
    buffer_name = vim.current.buffer.name
    modname = ub.modpath_to_modname(buffer_name)
    moddir, rel_modpath = ub.split_modpath(buffer_name)
    # moddir = dirname(buffer_name)
    return modname, moddir
示例#4
0
    def parse(ImportVisitor,
              source=None,
              modpath=None,
              modname=None,
              module=None):
        if module is not None:
            if source is None:
                source = inspect.getsource(module)
            if modpath is None:
                modname = module.__file__
            if modname is None:
                modname = module.__name__

        if modpath is not None:
            if modpath.endswith('.pyc'):
                modpath = modpath.replace('.pyc', '.py')  # python 2 hack

            if isdir(modpath):
                modpath = join(modpath, '__init__.py')
            if modname is None:
                modname = ub.modpath_to_modname(modpath)

        if modpath is not None:
            if source is None:
                if not modpath.endswith(('.py', '>')):
                    raise NotAPythonFile(
                        'can only parse python files, not {}'.format(modpath))
                source = open(modpath, 'r').read()

        if source is None:
            raise ValueError('unable to derive source code')

        source = ub.ensure_unicode(source)
        if six.PY2:
            try:
                pt = ast.parse(source)
            except SyntaxError as ex:
                if 'encoding declaration in Unicode string' in ex.args[0]:
                    pt = ast.parse(source.encode())
                else:
                    raise
        else:
            pt = ast.parse(source)
        visitor = ImportVisitor(modpath, modname, module, pt=pt)
        visitor.visit(pt)
        return visitor
示例#5
0
def test_modpath_to_modname():
    """
    CommandLine:
        pytest testing/test_static.py::test_modpath_to_modname -s
        python testing/test_static.py test_modpath_to_modname
    """
    with ub.TempDir() as temp:
        dpath = temp.dpath

        # Create a dummy package heirachy
        root = ub.ensuredir((dpath, '_tmproot927'))
        sub1 = ub.ensuredir((root, 'sub1'))
        sub2 = ub.ensuredir((sub1, 'sub2'))

        root_init = ub.touch(join(root, '__init__.py'))
        sub1_init = ub.touch(join(sub1, '__init__.py'))
        sub2_init = ub.touch(join(sub2, '__init__.py'))

        mod0 = ub.touch(join(root, 'mod0.py'))
        mod1 = ub.touch(join(sub1, 'mod1.py'))
        mod2 = ub.touch(join(sub2, 'mod2.py'))

        root_main = ub.touch(join(root, '__main__.py'))
        sub2_main = ub.touch(join(sub2, '__main__.py'))

        bad1 = ub.ensuredir((root, 'bad1'))
        bad2 = ub.ensuredir((sub1, 'bad2'))
        b0 = ub.touch(join(bad1, 'b0.py'))
        b1 = ub.touch(join(bad2, 'b1.py'))

        import os
        ub.modpath_to_modname(root, relativeto=os.path.dirname(dpath))  # TODO: assert correct output

        with PythonPathContext(dpath):

            assert ub.modpath_to_modname(root) == '_tmproot927'
            assert ub.modpath_to_modname(sub1) == '_tmproot927.sub1'
            assert ub.modpath_to_modname(sub2) == '_tmproot927.sub1.sub2'

            assert ub.modpath_to_modname(mod0) == '_tmproot927.mod0'
            assert ub.modpath_to_modname(mod1) == '_tmproot927.sub1.mod1'
            assert ub.modpath_to_modname(mod2) == '_tmproot927.sub1.sub2.mod2'

            assert ub.modpath_to_modname(root_init) == '_tmproot927'
            assert ub.modpath_to_modname(sub1_init) == '_tmproot927.sub1'
            assert ub.modpath_to_modname(sub2_init) == '_tmproot927.sub1.sub2'

            assert ub.modpath_to_modname(root_init, hide_init=False) == '_tmproot927.__init__'
            assert ub.modpath_to_modname(sub1_init, hide_init=False) == '_tmproot927.sub1.__init__'
            assert ub.modpath_to_modname(sub2_init, hide_init=False) == '_tmproot927.sub1.sub2.__init__'

            assert ub.modpath_to_modname(root, hide_main=True, hide_init=False) == '_tmproot927.__init__'
            assert ub.modpath_to_modname(sub1, hide_main=True, hide_init=False) == '_tmproot927.sub1.__init__'
            assert ub.modpath_to_modname(sub2, hide_main=True, hide_init=False) == '_tmproot927.sub1.sub2.__init__'

            assert ub.modpath_to_modname(root, hide_main=False, hide_init=False) == '_tmproot927.__init__'
            assert ub.modpath_to_modname(sub1, hide_main=False, hide_init=False) == '_tmproot927.sub1.__init__'
            assert ub.modpath_to_modname(sub2, hide_main=False, hide_init=False) == '_tmproot927.sub1.sub2.__init__'

            assert ub.modpath_to_modname(root, hide_main=False, hide_init=True) == '_tmproot927'
            assert ub.modpath_to_modname(sub1, hide_main=False, hide_init=True) == '_tmproot927.sub1'
            assert ub.modpath_to_modname(sub2, hide_main=False, hide_init=True) == '_tmproot927.sub1.sub2'

            assert ub.modpath_to_modname(root_main, hide_main=False, hide_init=True) == '_tmproot927.__main__'
            assert ub.modpath_to_modname(sub2_main, hide_main=False, hide_init=True) == '_tmproot927.sub1.sub2.__main__'

            assert ub.modpath_to_modname(root_main, hide_main=False, hide_init=True) == '_tmproot927.__main__'
            assert ub.modpath_to_modname(sub2_main, hide_main=False, hide_init=True) == '_tmproot927.sub1.sub2.__main__'

            assert ub.modpath_to_modname(root_main, hide_main=True, hide_init=True) == '_tmproot927'
            assert ub.modpath_to_modname(sub2_main, hide_main=True, hide_init=True) == '_tmproot927.sub1.sub2'

            assert ub.modpath_to_modname(root_main, hide_main=True, hide_init=False) == '_tmproot927'
            assert ub.modpath_to_modname(sub2_main, hide_main=True, hide_init=False) == '_tmproot927.sub1.sub2'

            # Non-existant / invalid modules should always be None
            for a, b in it.product([True, False], [True, False]):
                with pytest.raises(ValueError):
                    ub.modpath_to_modname(join(sub1, '__main__.py'), hide_main=a, hide_init=b)
                assert ub.modpath_to_modname(b0, hide_main=a, hide_init=b) == 'b0'
                assert ub.modpath_to_modname(b1, hide_main=a, hide_init=b) == 'b1'
                with pytest.raises(ValueError):
                    ub.modpath_to_modname(bad1, hide_main=a, hide_init=b)
                with pytest.raises(ValueError):
                    ub.modpath_to_modname(bad2, hide_main=a, hide_init=b)

            assert '_tmproot927' not in sys.modules
            assert '_tmproot927.mod0' not in sys.modules
            assert '_tmproot927.sub1' not in sys.modules
            assert '_tmproot927.sub1.mod1' not in sys.modules
            assert '_tmproot927.sub1.sub2' not in sys.modules
            assert '_tmproot927.sub1.mod2.mod2' not in sys.modules
示例#6
0
def reload_class(self, verbose=True, reload_module=True):
    """
    Reload a class for a specific instance.

    (populates any new methods that may have just been written)

    Ported from utool
    """
    verbose = verbose
    classname = self.__class__.__name__
    try:
        modname = self.__class__.__module__
        if verbose:
            print('[class] reloading ' + classname + ' from ' + modname)
        # --HACK--
        if hasattr(self, '_on_reload'):
            if verbose > 1:
                print('[class] calling _on_reload for ' + classname)
            self._on_reload()
        elif verbose > 1:
            print('[class] ' + classname +
                  ' does not have an _on_reload function')

        # Do for all inheriting classes
        def find_base_clases(_class, find_base_clases=None):
            class_list = []
            for _baseclass in _class.__bases__:
                parents = find_base_clases(_baseclass, find_base_clases)
                class_list.extend(parents)
            if _class is not object:
                class_list.append(_class)
            return class_list

        head_class = self.__class__
        # Determine if parents need reloading
        class_list = find_base_clases(head_class, find_base_clases)
        # HACK
        # ignore = {HashComparable2}
        ignore = {}
        class_list = [_class for _class in class_list if _class not in ignore]
        for _class in class_list:
            if verbose:
                print('[class] reloading parent ' + _class.__name__ +
                      ' from ' + _class.__module__)
            if _class.__module__ == '__main__':
                # Attempt to find the module that is the main module
                # This may be very hacky and potentially break
                main_module_ = sys.modules[_class.__module__]
                main_modname = ub.modpath_to_modname(main_module_.__file__)
                module_ = sys.modules[main_modname]
            else:
                module_ = sys.modules[_class.__module__]
            if reload_module:
                import imp
                if verbose:
                    print('[class] reloading ' + _class.__module__ +
                          ' with imp')
                try:
                    imp.reload(module_)
                except (ImportError, AttributeError):
                    print('[class] fallback reloading ' + _class.__module__ +
                          ' with imp')
                    # one last thing to try. probably used
                    # import_module_from_fpath when importing this module
                    imp.load_source(module_.__name__, module_.__file__)
            # Reset class attributes
            _newclass = getattr(module_, _class.__name__)
            _reload_class_methods(self, _newclass, verbose=verbose)

        # --HACK--
        # TODO: handle injected definitions
        if hasattr(self, '_initialize_self'):
            if verbose > 1:
                print('[class] calling _initialize_self for ' + classname)
            self._initialize_self()
        elif verbose > 1:
            print('[class] ' + classname +
                  ' does not have an _initialize_self function')
    except Exception as ex:
        raise