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
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
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
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
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
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