def load_module(path, name): if not name: name = os.path.basename(path) name = name.rpartition('.')[0] # cut file type (normally .so) # sometimes there are endings like `_sqlite3.cpython-32mu` name = re.sub(r'\..*', '', name) dot_path = [] if path: p = path # if path is not in sys.path, we need to make a well defined import # like `from numpy.core import umath.` while p and p not in sys.path: p, sep, mod = p.rpartition(os.path.sep) dot_path.insert(0, mod.partition('.')[0]) if p: name = ".".join(dot_path) path = p else: path = os.path.dirname(path) sys_path = get_sys_path() if path: sys_path.insert(0, path) temp, sys.path = sys.path, sys_path try: module = __import__(name, {}, {}, dot_path[:-1]) except AttributeError: # use sys.modules, because you cannot access some modules # directly. -> github issue #59 module = sys.modules[name] sys.path = temp return CompiledObject(module)
def dotted_from_fs_path(fs_path, sys_path=None): """ Changes `/usr/lib/python3.4/email/utils.py` to `email.utils`. I.e. compares the path with sys.path and then returns the dotted_path. If the path is not in the sys.path, just returns None. """ if sys_path is None: sys_path = get_sys_path() # prefer # - UNIX # /path/to/pythonX.Y/lib-dynload # /path/to/pythonX.Y/site-packages # - Windows # C:\path\to\DLLs # C:\path\to\Lib\site-packages # over # - UNIX # /path/to/pythonX.Y # - Windows # C:\path\to\Lib path = '' for s in sys_path: if (fs_path.startswith(s) and len(path) < len(s)): path = s return _path_re.sub('', fs_path[len(path):].lstrip(os.path.sep)).replace( os.path.sep, '.')
def load_module(path=None, name=None): if path is not None: dotted_path = dotted_from_fs_path(path) else: dotted_path = name sys_path = get_sys_path() if dotted_path is None: p, _, dotted_path = path.partition(os.path.sep) sys_path.insert(0, p) temp, sys.path = sys.path, sys_path try: __import__(dotted_path) except RuntimeError: if 'PySide' in dotted_path or 'PyQt' in dotted_path: # RuntimeError: the PyQt4.QtCore and PyQt5.QtCore modules both wrap # the QObject class. # See https://github.com/davidhalter/jedi/pull/483 return None raise except ImportError: # If a module is "corrupt" or not really a Python module or whatever. debug.warning('Module %s not importable.', path) return None finally: sys.path = temp # Just access the cache after import, because of #59 as well as the very # complicated import structure of Python. module = sys.modules[dotted_path] return CompiledObject(module)
def dotted_from_fs_path(fs_path, sys_path=None): """ Changes `/usr/lib/python3.4/email/utils.py` to `email.utils`. I.e. compares the path with sys.path and then returns the dotted_path. If the path is not in the sys.path, just returns None. """ if sys_path is None: sys_path = get_sys_path() # prefer # - UNIX # /path/to/pythonX.Y/lib-dynload # /path/to/pythonX.Y/site-packages # - Windows # C:\path\to\DLLs # C:\path\to\Lib\site-packages # over # - UNIX # /path/to/pythonX.Y # - Windows # C:\path\to\Lib path = "" for s in sys_path: if fs_path.startswith(s) and len(path) < len(s): path = s return _path_re.sub("", fs_path[len(path) :].lstrip(os.path.sep)).replace(os.path.sep, ".")
def _real_follow_file_system(self): if self.file_path: sys_path_mod = list(self.sys_path_with_modifications()) if not self.module.has_explicit_absolute_import: # If the module explicitly asks for absolute imports, # there's probably a bogus local one. sys_path_mod.insert(0, self.file_path) # First the sys path is searched normally and if that doesn't # succeed, try to search the parent directories, because sometimes # Jedi doesn't recognize sys.path modifications (like py.test # stuff). old_path, temp_path = self.file_path, os.path.dirname( self.file_path) while old_path != temp_path: sys_path_mod.append(temp_path) old_path, temp_path = temp_path, os.path.dirname(temp_path) else: sys_path_mod = list(get_sys_path()) from jedi.evaluate.representation import ModuleWrapper module, rest = self._follow_sys_path(sys_path_mod) if isinstance(module, pr.Module): return ModuleWrapper(self._evaluator, module), rest return module, rest
def dotted_from_fs_path(fs_path, sys_path=None): """ Changes `/usr/lib/python3.4/email/utils.py` to `email.utils`. I.e. compares the path with sys.path and then returns the dotted_path. If the path is not in the sys.path, just returns None. """ if sys_path is None: sys_path = get_sys_path() if os.path.basename(fs_path).startswith('__init__.'): # We are calculating the path. __init__ files are not interesting. fs_path = os.path.dirname(fs_path) # prefer # - UNIX # /path/to/pythonX.Y/lib-dynload # /path/to/pythonX.Y/site-packages # - Windows # C:\path\to\DLLs # C:\path\to\Lib\site-packages # over # - UNIX # /path/to/pythonX.Y # - Windows # C:\path\to\Lib path = '' for s in sys_path: if (fs_path.startswith(s) and len(path) < len(s)): path = s return _path_re.sub('', fs_path[len(path):].lstrip(os.path.sep)).replace(os.path.sep, '.')
def test_get_sys_path(monkeypatch): monkeypatch.setenv('VIRTUAL_ENV', os.path.join(os.path.dirname(__file__), 'egg-link', 'venv')) def sitepackages_dir(venv): return os.path.join(venv, 'lib', 'python3.4', 'site-packages') monkeypatch.setattr('jedi.evaluate.sys_path._get_venv_sitepackages', sitepackages_dir) assert '/path/from/egg-link' in sys_path.get_sys_path()
def load_module(path, name): """ if not name: name = os.path.basename(path) name = name.rpartition('.')[0] # cut file type (normally .so) # sometimes there are endings like `_sqlite3.cpython-32mu` name = re.sub(r'\..*', '', name) dot_path = [] if path: p = path # if path is not in sys.path, we need to make a well defined import # like `from numpy.core import umath.` while p and p not in sys.path: p, sep, mod = p.rpartition(os.path.sep) dot_path.insert(0, mod.partition('.')[0]) if p: name = ".".join(dot_path) path = p else: path = os.path.dirname(path) """ if path is not None: dotted_path = dotted_from_fs_path(path) else: dotted_path = name sys_path = get_sys_path() if dotted_path is None: p, _, dotted_path = path.partition(os.path.sep) sys_path.insert(0, p) temp, sys.path = sys.path, sys_path try: __import__(dotted_path) except RuntimeError: if 'PySide' in dotted_path or 'PyQt' in dotted_path: # RuntimeError: the PyQt4.QtCore and PyQt5.QtCore modules both wrap # the QObject class. # See https://github.com/davidhalter/jedi/pull/483 return None # Just access the cache after import, because of #59 as well as the very # complicated import structure of Python. module = sys.modules[dotted_path] sys.path = temp return CompiledObject(module)
def follow_file_system(self): if self.file_path: sys_path_mod = list(self.sys_path_with_modifications()) if not self.module.has_explicit_absolute_import: # If the module explicitly asks for absolute imports, # there's probably a bogus local one. sys_path_mod.insert(0, self.file_path) # First the sys path is searched normally and if that doesn't # succeed, try to search the parent directories, because sometimes # Jedi doesn't recognize sys.path modifications (like py.test # stuff). old_path, temp_path = self.file_path, os.path.dirname(self.file_path) while old_path != temp_path: sys_path_mod.append(temp_path) old_path, temp_path = temp_path, os.path.dirname(temp_path) else: sys_path_mod = list(sys_path.get_sys_path()) return self._follow_sys_path(sys_path_mod)
def load_module(path, name): """ if not name: name = os.path.basename(path) name = name.rpartition('.')[0] # cut file type (normally .so) # sometimes there are endings like `_sqlite3.cpython-32mu` name = re.sub(r'\..*', '', name) dot_path = [] if path: p = path # if path is not in sys.path, we need to make a well defined import # like `from numpy.core import umath.` while p and p not in sys.path: p, sep, mod = p.rpartition(os.path.sep) dot_path.insert(0, mod.partition('.')[0]) if p: name = ".".join(dot_path) path = p else: path = os.path.dirname(path) """ if path is not None: dotted_path = dotted_from_fs_path(path) else: dotted_path = name sys_path = get_sys_path() if dotted_path is None: p, _, dotted_path = path.partition(os.path.sep) sys_path.insert(0, p) temp, sys.path = sys.path, sys_path __import__(dotted_path) # Just access the cache after import, because of #59 as well as the very # complicated import structure of Python. module = sys.modules[dotted_path] sys.path = temp return CompiledObject(module)
def load_module(path, name): """ if not name: name = os.path.basename(path) name = name.rpartition('.')[0] # cut file type (normally .so) # sometimes there are endings like `_sqlite3.cpython-32mu` name = re.sub(r'\..*', '', name) dot_path = [] if path: p = path # if path is not in sys.path, we need to make a well defined import # like `from numpy.base import umath.` while p and p not in sys.path: p, sep, mod = p.rpartition(os.path.sep) dot_path.insert(0, mod.partition('.')[0]) if p: name = ".".join(dot_path) path = p else: path = os.path.dirname(path) """ if path is not None: dotted_path = dotted_from_fs_path(path) else: dotted_path = name sys_path = get_sys_path() if dotted_path is None: p, _, dotted_path = path.partition(os.path.sep) sys_path.insert(0, p) temp, sys.path = sys.path, sys_path __import__(dotted_path) # Just access the cache after import, because of #59 as well as the very # complicated import structure of Python. module = sys.modules[dotted_path] sys.path = temp return CompiledObject(module)
def _follow_file_system(self): if self.file_path: sys_path_mod = list(self._sys_path_with_modifications()) module = self.import_stmt.get_parent_until() if not module.has_explicit_absolute_import: # If the module explicitly asks for absolute imports, # there's probably a bogus local one. sys_path_mod.insert(0, self.file_path) # First the sys path is searched normally and if that doesn't # succeed, try to search the parent directories, because sometimes # Jedi doesn't recognize sys.path modifications (like py.test # stuff). old_path, temp_path = self.file_path, os.path.dirname( self.file_path) while old_path != temp_path: sys_path_mod.append(temp_path) old_path, temp_path = temp_path, os.path.dirname(temp_path) else: sys_path_mod = list(sys_path.get_sys_path()) return self._follow_sys_path(sys_path_mod)