def follow_str(ns_path, string): debug.dbg('follow_module', ns_path, string) path = None if ns_path: path = ns_path elif self.import_stmt.relative_count: path = self.get_relative_path() global imports_processed imports_processed += 1 importing = None if path is not None: importing = find_module(string, [path]) else: debug.dbg('search_module', string, self.file_path) # Override the sys.path. It works only good that way. # Injecting the path directly into `find_module` did not work. sys.path, temp = sys_path_mod, sys.path try: importing = find_module(string) except ImportError: sys.path = temp raise sys.path = temp return importing
def test_find_module_package_zipped(): if 'zipped_imports/pkg.zip' not in sys.path: sys.path.append( os.path.join(os.path.dirname(__file__), 'zipped_imports/pkg.zip')) file, path, is_package = find_module('pkg') assert file is not None assert path.endswith('pkg.zip') assert is_package is True assert len(jedi.Script('import pkg; pkg.mod', 1, 19).completions()) == 1
def test_find_module_package_zipped(): if 'zipped_imports/pkg.zip' not in sys.path: sys.path.append(os.path.join(os.path.dirname(__file__), 'zipped_imports/pkg.zip')) file, path, is_package = find_module('pkg') assert file is not None assert path.endswith('pkg.zip') assert is_package is True assert len(jedi.Script('import pkg; pkg.mod', 1, 19).completions()) == 1
def follow_str(ns_path, string): debug.dbg('follow_module %s in %s', string, ns_path) path = None if ns_path: path = ns_path elif self.level > 0: # is a relative import path = self.get_relative_path() if path is not None: importing = find_module(string, [path]) else: debug.dbg('search_module %s in %s', string, self.file_path) # Override the sys.path. It works only good that way. # Injecting the path directly into `find_module` did not work. sys.path, temp = sys_path, sys.path try: importing = find_module(string) finally: sys.path = temp return importing
def get_module_info(inference_state, sys_path=None, full_name=None, **kwargs): """ Returns Tuple[Union[NamespaceInfo, FileIO, None], Optional[bool]] """ if sys_path is not None: sys.path, temp = sys_path, sys.path try: return find_module(full_name=full_name, **kwargs) except ImportError: return None, None finally: if sys_path is not None: sys.path = temp
def get_module_info(evaluator, sys_path=None, full_name=None, **kwargs): if sys_path is not None: sys.path, temp = sys_path, sys.path try: module_file, module_path, is_pkg = find_module(full_name=full_name, **kwargs) except ImportError: return None, None, None finally: if sys_path is not None: sys.path = temp code = None if is_pkg: # In this case, we don't have a file yet. Search for the # __init__ file. if module_path.endswith(('.zip', '.egg')): code = module_file.loader.get_source(full_name) else: module_path = _get_init_path(module_path) elif module_file: if module_path.endswith(('.zip', '.egg')): # Unfortunately we are reading unicode here already, not byes. # It seems however hard to get bytes, because the zip importer # logic just unpacks the zip file and returns a file descriptor # that we cannot as easily access. Therefore we just read it as # a string. code = module_file.read() else: # Read the code with a binary file, because the binary file # might not be proper unicode. This is handled by the parser # wrapper. with open(module_path, 'rb') as f: code = f.read() module_file.close() return code, cast_path(module_path), is_pkg
def test_find_module_package(): file, path, is_package = find_module('json') assert file is None assert path.endswith('json') assert is_package is True
def _do_import(self, import_path, sys_path): """ This method is very similar to importlib's `_gcd_import`. """ import_parts = [ i.value if isinstance(i, tree.Name) else i for i in import_path ] # Handle "magic" Flask extension imports: # ``flask.ext.foo`` is really ``flask_foo`` or ``flaskext.foo``. if len(import_path) > 2 and import_parts[:2] == ['flask', 'ext']: # New style. ipath = ('flask_' + str(import_parts[2]), ) + import_path[3:] modules = self._do_import(ipath, sys_path) if modules: return modules else: # Old style return self._do_import(('flaskext', ) + import_path[2:], sys_path) module_name = '.'.join(import_parts) try: return ContextSet(self._evaluator.modules[module_name]) except KeyError: pass if len(import_path) > 1: # This is a recursive way of importing that works great with # the module cache. bases = self._do_import(import_path[:-1], sys_path) if not bases: return NO_CONTEXTS # We can take the first element, because only the os special # case yields multiple modules, which is not important for # further imports. parent_module = list(bases)[0] # This is a huge exception, we follow a nested import # ``os.path``, because it's a very important one in Python # that is being achieved by messing with ``sys.modules`` in # ``os``. if import_parts == ['os', 'path']: return parent_module.py__getattribute__('path') try: method = parent_module.py__path__ except AttributeError: # The module is not a package. _add_error(self.module_context, import_path[-1]) return NO_CONTEXTS else: paths = method() debug.dbg('search_module %s in paths %s', module_name, paths) for path in paths: # At the moment we are only using one path. So this is # not important to be correct. try: if not isinstance(path, list): path = [path] module_file, module_path, is_pkg = \ find_module(import_parts[-1], path, fullname=module_name) break except ImportError: module_path = None if module_path is None: _add_error(self.module_context, import_path[-1]) return NO_CONTEXTS else: parent_module = None try: debug.dbg('search_module %s in %s', import_parts[-1], self.file_path) # Override the sys.path. It works only good that way. # Injecting the path directly into `find_module` did not work. sys.path, temp = sys_path, sys.path try: module_file, module_path, is_pkg = \ find_module(import_parts[-1], fullname=module_name) finally: sys.path = temp except ImportError: # The module is not a package. _add_error(self.module_context, import_path[-1]) return NO_CONTEXTS code = None if is_pkg: # In this case, we don't have a file yet. Search for the # __init__ file. if module_path.endswith(('.zip', '.egg')): code = module_file.loader.get_source(module_name) else: module_path = get_init_path(module_path) elif module_file: if module_path.endswith(('.zip', '.egg')): # Unfortunately we are reading unicode here already, not byes. # It seems however hard to get bytes, because the zip importer # logic just unpacks the zip file and returns a file descriptor # that we cannot as easily access. Therefore we just read it as # a string. code = module_file.read() else: # Read the code with a binary file, because the binary file # might not be proper unicode. This is handled by the parser # wrapper. with open(module_path, 'rb') as f: code = f.read() module_file.close() if isinstance(module_path, ImplicitNSInfo): from jedi.evaluate.context.namespace import ImplicitNamespaceContext fullname, paths = module_path.name, module_path.paths module = ImplicitNamespaceContext(self._evaluator, fullname=fullname) module.paths = paths elif module_file is None and not module_path.endswith( ('.py', '.zip', '.egg')): module = compiled.load_module(self._evaluator, module_path) else: module = _load_module(self._evaluator, module_path, code, sys_path, parent_module) if module is None: # The file might raise an ImportError e.g. and therefore not be # importable. return NO_CONTEXTS self._evaluator.modules[module_name] = module return ContextSet(module)
def _do_import(self, import_path, sys_path): """ This method is very similar to importlib's `_gcd_import`. """ import_parts = [str(i) for i in import_path] # Handle "magic" Flask extension imports: # ``flask.ext.foo`` is really ``flask_foo`` or ``flaskext.foo``. if len(import_path) > 2 and import_parts[:2] == ['flask', 'ext']: # New style. ipath = ('flask_' + str(import_parts[2]), ) + import_path[3:] modules = self._do_import(ipath, sys_path) if modules: return modules else: # Old style return self._do_import(('flaskext', ) + import_path[2:], sys_path) module_name = '.'.join(import_parts) try: return set([self._evaluator.modules[module_name]]) except KeyError: pass if len(import_path) > 1: # This is a recursive way of importing that works great with # the module cache. bases = self._do_import(import_path[:-1], sys_path) if not bases: return set() # We can take the first element, because only the os special # case yields multiple modules, which is not important for # further imports. parent_module = list(bases)[0] # This is a huge exception, we follow a nested import # ``os.path``, because it's a very important one in Python # that is being achieved by messing with ``sys.modules`` in # ``os``. if [str(i) for i in import_path] == ['os', 'path']: return self._evaluator.find_types(parent_module, 'path') try: paths = parent_module.py__path__() except AttributeError: # The module is not a package. _add_error(self._evaluator, import_path[-1]) return set() else: debug.dbg('search_module %s in paths %s', module_name, paths) for path in paths: # At the moment we are only using one path. So this is # not important to be correct. try: module_file, module_path, is_pkg = \ find_module(import_parts[-1], [path]) break except ImportError: module_path = None if module_path is None: _add_error(self._evaluator, import_path[-1]) return set() else: parent_module = None try: debug.dbg('search_module %s in %s', import_parts[-1], self.file_path) # Override the sys.path. It works only good that way. # Injecting the path directly into `find_module` did not work. sys.path, temp = sys_path, sys.path try: module_file, module_path, is_pkg = \ find_module(import_parts[-1]) finally: sys.path = temp except ImportError: # The module is not a package. _add_error(self._evaluator, import_path[-1]) return set() source = None if is_pkg: # In this case, we don't have a file yet. Search for the # __init__ file. if module_path.endswith(('.zip', '.egg')): source = module_file.loader.get_source(module_name) else: module_path = get_init_path(module_path) elif module_file: source = module_file.read() module_file.close() if module_file is None and not module_path.endswith( ('.py', '.zip', '.egg')): module = compiled.load_module(self._evaluator, module_path) else: module = _load_module(self._evaluator, module_path, source, sys_path, parent_module) if module is None: # The file might raise an ImportError e.g. and therefore not be # importable. return set() self._evaluator.modules[module_name] = module return set([module])
def test_find_module_package(): file_io, is_package = find_module('json') assert file_io.path.endswith(os.path.join('json', '__init__.py')) assert is_package is True
def test_find_module_not_package(): file_io, is_package = find_module('io') assert file_io.path.endswith('io.py') assert is_package is False
def _do_import(self, import_path, sys_path): """ This method is very similar to importlib's `_gcd_import`. """ import_parts = [str(i) for i in import_path] # Handle "magic" Flask extension imports: # ``flask.ext.foo`` is really ``flask_foo`` or ``flaskext.foo``. if len(import_path) > 2 and import_parts[:2] == ['flask', 'ext']: # New style. ipath = ('flask_' + str(import_parts[2]),) + import_path[3:] modules = self._do_import(ipath, sys_path) if modules: return modules else: # Old style return self._do_import(('flaskext',) + import_path[2:], sys_path) module_name = '.'.join(import_parts) try: return set([self._evaluator.modules[module_name]]) except KeyError: pass if len(import_path) > 1: # This is a recursive way of importing that works great with # the module cache. bases = self._do_import(import_path[:-1], sys_path) if not bases: return set() # We can take the first element, because only the os special # case yields multiple modules, which is not important for # further imports. parent_module = list(bases)[0] # This is a huge exception, we follow a nested import # ``os.path``, because it's a very important one in Python # that is being achieved by messing with ``sys.modules`` in # ``os``. if [str(i) for i in import_path] == ['os', 'path']: return parent_module.py__getattribute__('path') try: method = parent_module.py__path__ except AttributeError: # The module is not a package. _add_error(parent_module, import_path[-1]) return set() else: paths = method() debug.dbg('search_module %s in paths %s', module_name, paths) for path in paths: # At the moment we are only using one path. So this is # not important to be correct. try: module_file, module_path, is_pkg = \ find_module(import_parts[-1], [path]) break except ImportError: module_path = None if module_path is None: _add_error(parent_module, import_path[-1]) return set() else: parent_module = None try: debug.dbg('search_module %s in %s', import_parts[-1], self.file_path) # Override the sys.path. It works only good that way. # Injecting the path directly into `find_module` did not work. sys.path, temp = sys_path, sys.path try: module_file, module_path, is_pkg = \ find_module(import_parts[-1]) finally: sys.path = temp except ImportError: # The module is not a package. _add_error(self.module_context, import_path[-1]) return set() source = None if is_pkg: # In this case, we don't have a file yet. Search for the # __init__ file. if module_path.endswith(('.zip', '.egg')): source = module_file.loader.get_source(module_name) else: module_path = get_init_path(module_path) elif module_file: source = module_file.read() module_file.close() if module_file is None and not module_path.endswith(('.py', '.zip', '.egg')): module = compiled.load_module(self._evaluator, module_path) else: module = _load_module(self._evaluator, module_path, source, sys_path, parent_module) if module is None: # The file might raise an ImportError e.g. and therefore not be # importable. return set() self._evaluator.modules[module_name] = module return set([module])
def test_find_module_not_package(): file, path, is_package = find_module('io') assert file is not None assert path.endswith('io.py') assert is_package is False
def _do_import(self, import_path, sys_path): """ This method is very similar to importlib's `_gcd_import`. """ import_parts = [str(i) for i in import_path] # Handle "magic" Flask extension imports: # ``flask.ext.foo`` is really ``flask_foo`` or ``flaskext.foo``. if len(import_path) > 2 and import_parts[:2] == ["flask", "ext"]: # New style. ipath = ("flask_" + str(import_parts[2]),) + import_path[3:] modules = self._do_import(ipath, sys_path) if modules: return modules else: # Old style return self._do_import(("flaskext",) + import_path[2:], sys_path) module_name = ".".join(import_parts) try: return [self._evaluator.modules[module_name]] except KeyError: pass if len(import_path) > 1: # This is a recursive way of importing that works great with # the module cache. bases = self._do_import(import_path[:-1], sys_path) if not bases: return [] # We can take the first element, because only the os special # case yields multiple modules, which is not important for # further imports. base = bases[0] # This is a huge exception, we follow a nested import # ``os.path``, because it's a very important one in Python # that is being achieved by messing with ``sys.modules`` in # ``os``. if [str(i) for i in import_path] == ["os", "path"]: return self._evaluator.find_types(base, "path") try: # It's possible that by giving it always the sys path (and not # the __path__ attribute of the parent, we get wrong results # and nested namespace packages don't work. But I'm not sure. paths = base.py__path__(sys_path) except AttributeError: # The module is not a package. _add_error(self._evaluator, import_path[-1]) return [] else: debug.dbg("search_module %s in paths %s", module_name, paths) for path in paths: # At the moment we are only using one path. So this is # not important to be correct. try: module_file, module_path, is_pkg = find_module(import_parts[-1], [path]) break except ImportError: module_path = None if module_path is None: _add_error(self._evaluator, import_path[-1]) return [] else: try: debug.dbg("search_module %s in %s", import_parts[-1], self.file_path) # Override the sys.path. It works only good that way. # Injecting the path directly into `find_module` did not work. sys.path, temp = sys_path, sys.path try: module_file, module_path, is_pkg = find_module(import_parts[-1]) finally: sys.path = temp except ImportError: # The module is not a package. _add_error(self._evaluator, import_path[-1]) return [] source = None if is_pkg: # In this case, we don't have a file yet. Search for the # __init__ file. module_path = get_init_path(module_path) elif module_file: source = module_file.read() module_file.close() if module_file is None and not module_path.endswith(".py"): module = compiled.load_module(module_path) else: module = _load_module(self._evaluator, module_path, source, sys_path) self._evaluator.modules[module_name] = module return [module]