forked from VimPlug/jedi
Start using the new virtualenv code
There used to be a lot of code to kind of understand virtualenvs. This can all be removed now, because this is done in a subprocess with the correct interpreter
This commit is contained in:
@@ -66,7 +66,7 @@ class InterpreterEnvironment(_BaseEnvironment):
|
||||
return EvaluatorSameProcess(evaluator)
|
||||
|
||||
def get_sys_path(self):
|
||||
return sys.sys_path
|
||||
return sys.path
|
||||
|
||||
|
||||
def get_default_environment():
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
from jedi.evaluate.sys_path import get_venv_path, detect_additional_paths
|
||||
from jedi.evaluate.sys_path import detect_additional_paths
|
||||
from jedi.cache import memoize_method
|
||||
|
||||
|
||||
@@ -9,24 +6,8 @@ class Project(object):
|
||||
def __init__(self, sys_path=None):
|
||||
self._script_path = None
|
||||
|
||||
if sys_path is not None:
|
||||
self._base_sys_path = sys_path
|
||||
|
||||
if sys_path is None:
|
||||
venv = os.getenv('VIRTUAL_ENV')
|
||||
if venv:
|
||||
sys_path = get_venv_path(venv)
|
||||
else:
|
||||
sys_path = sys.path
|
||||
|
||||
base_sys_path = list(sys_path)
|
||||
try:
|
||||
base_sys_path.remove('')
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
self._base_sys_path = base_sys_path
|
||||
|
||||
def add_script_path(self, script_path):
|
||||
self._script_path = script_path
|
||||
|
||||
@@ -36,7 +17,17 @@ class Project(object):
|
||||
@property
|
||||
@memoize_method
|
||||
def sys_path(self):
|
||||
if self._script_path is None:
|
||||
return self._base_sys_path
|
||||
sys_path = self._base_sys_path
|
||||
if sys_path is None:
|
||||
sys_path = self._evaluator.environment.get_sys_path()
|
||||
|
||||
return self._base_sys_path + detect_additional_paths(self._evaluator, self._script_path)
|
||||
sys_path = list(sys_path)
|
||||
try:
|
||||
sys_path.remove('')
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
if self._script_path is None:
|
||||
return sys_path
|
||||
|
||||
return sys_path + detect_additional_paths(self._evaluator, self._script_path)
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
"""An adapted copy of relevant site-packages functionality from Python stdlib.
|
||||
|
||||
This file contains some functions related to handling site-packages in Python
|
||||
with jedi-specific modifications:
|
||||
|
||||
- the functions operate on sys_path argument rather than global sys.path
|
||||
|
||||
- in .pth files "import ..." lines that allow execution of arbitrary code are
|
||||
skipped to prevent code injection into jedi interpreter
|
||||
|
||||
"""
|
||||
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
# 2011, 2012, 2013, 2014, 2015 Python Software Foundation; All Rights Reserved
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
||||
def makepath(*paths):
|
||||
dir = os.path.join(*paths)
|
||||
try:
|
||||
dir = os.path.abspath(dir)
|
||||
except OSError:
|
||||
pass
|
||||
return dir, os.path.normcase(dir)
|
||||
|
||||
|
||||
def _init_pathinfo(sys_path):
|
||||
"""Return a set containing all existing directory entries from sys_path"""
|
||||
d = set()
|
||||
for dir in sys_path:
|
||||
try:
|
||||
if os.path.isdir(dir):
|
||||
dir, dircase = makepath(dir)
|
||||
d.add(dircase)
|
||||
except TypeError:
|
||||
continue
|
||||
return d
|
||||
|
||||
|
||||
def addpackage(sys_path, sitedir, name, known_paths):
|
||||
"""Process a .pth file within the site-packages directory:
|
||||
For each line in the file, either combine it with sitedir to a path
|
||||
and add that to known_paths, or execute it if it starts with 'import '.
|
||||
"""
|
||||
if known_paths is None:
|
||||
known_paths = _init_pathinfo(sys_path)
|
||||
reset = 1
|
||||
else:
|
||||
reset = 0
|
||||
fullname = os.path.join(sitedir, name)
|
||||
try:
|
||||
f = open(fullname, "r")
|
||||
except OSError:
|
||||
return
|
||||
with f:
|
||||
for n, line in enumerate(f):
|
||||
if line.startswith("#"):
|
||||
continue
|
||||
try:
|
||||
if line.startswith(("import ", "import\t")):
|
||||
# Change by immerrr: don't evaluate import lines to prevent
|
||||
# code injection into jedi through pth files.
|
||||
#
|
||||
# exec(line)
|
||||
continue
|
||||
line = line.rstrip()
|
||||
dir, dircase = makepath(sitedir, line)
|
||||
if not dircase in known_paths and os.path.exists(dir):
|
||||
sys_path.append(dir)
|
||||
known_paths.add(dircase)
|
||||
except Exception:
|
||||
print("Error processing line {:d} of {}:\n".format(n+1, fullname),
|
||||
file=sys.stderr)
|
||||
import traceback
|
||||
for record in traceback.format_exception(*sys.exc_info()):
|
||||
for line in record.splitlines():
|
||||
print(' '+line, file=sys.stderr)
|
||||
print("\nRemainder of file ignored", file=sys.stderr)
|
||||
break
|
||||
if reset:
|
||||
known_paths = None
|
||||
return known_paths
|
||||
|
||||
|
||||
def addsitedir(sys_path, sitedir, known_paths=None):
|
||||
"""Add 'sitedir' argument to sys_path if missing and handle .pth files in
|
||||
'sitedir'"""
|
||||
if known_paths is None:
|
||||
known_paths = _init_pathinfo(sys_path)
|
||||
reset = 1
|
||||
else:
|
||||
reset = 0
|
||||
sitedir, sitedircase = makepath(sitedir)
|
||||
if not sitedircase in known_paths:
|
||||
sys_path.append(sitedir) # Add path component
|
||||
known_paths.add(sitedircase)
|
||||
try:
|
||||
names = os.listdir(sitedir)
|
||||
except OSError:
|
||||
return
|
||||
names = [name for name in names if name.endswith(".pth")]
|
||||
for name in sorted(names):
|
||||
addpackage(sys_path, sitedir, name, known_paths)
|
||||
if reset:
|
||||
known_paths = None
|
||||
return known_paths
|
||||
@@ -1,8 +1,5 @@
|
||||
import glob
|
||||
import os
|
||||
import sys
|
||||
import imp
|
||||
from jedi.evaluate.site import addsitedir
|
||||
|
||||
from jedi._compatibility import unicode
|
||||
from jedi.evaluate.cache import evaluator_method_cache
|
||||
@@ -13,62 +10,6 @@ from jedi import debug
|
||||
from jedi.evaluate.utils import ignored
|
||||
|
||||
|
||||
def get_venv_path(venv):
|
||||
"""Get sys.path for specified virtual environment."""
|
||||
sys_path = _get_venv_path_dirs(venv)
|
||||
with ignored(ValueError):
|
||||
sys_path.remove('')
|
||||
sys_path = _get_sys_path_with_egglinks(sys_path)
|
||||
# As of now, get_venv_path_dirs does not scan built-in pythonpath and
|
||||
# user-local site-packages, let's approximate them using path from Jedi
|
||||
# interpreter.
|
||||
return sys_path + sys.path
|
||||
|
||||
|
||||
def _get_sys_path_with_egglinks(sys_path):
|
||||
"""Find all paths including those referenced by egg-links.
|
||||
|
||||
Egg-link-referenced directories are inserted into path immediately before
|
||||
the directory on which their links were found. Such directories are not
|
||||
taken into consideration by normal import mechanism, but they are traversed
|
||||
when doing pkg_resources.require.
|
||||
"""
|
||||
result = []
|
||||
for p in sys_path:
|
||||
# pkg_resources does not define a specific order for egg-link files
|
||||
# using os.listdir to enumerate them, we're sorting them to have
|
||||
# reproducible tests.
|
||||
for egg_link in sorted(glob.glob(os.path.join(p, '*.egg-link'))):
|
||||
with open(egg_link) as fd:
|
||||
for line in fd:
|
||||
line = line.strip()
|
||||
if line:
|
||||
result.append(os.path.join(p, line))
|
||||
# pkg_resources package only interprets the first
|
||||
# non-empty line in egg-link files.
|
||||
break
|
||||
result.append(p)
|
||||
return result
|
||||
|
||||
|
||||
def _get_venv_path_dirs(venv):
|
||||
"""Get sys.path for venv without starting up the interpreter."""
|
||||
venv = os.path.abspath(venv)
|
||||
sitedir = _get_venv_sitepackages(venv)
|
||||
sys_path = []
|
||||
addsitedir(sys_path, sitedir)
|
||||
return sys_path
|
||||
|
||||
|
||||
def _get_venv_sitepackages(venv):
|
||||
if os.name == 'nt':
|
||||
p = os.path.join(venv, 'lib', 'site-packages')
|
||||
else:
|
||||
p = os.path.join(venv, 'lib', 'python%d.%d' % sys.version_info[:2],
|
||||
'site-packages')
|
||||
return p
|
||||
|
||||
|
||||
def _abs_path(module_context, path):
|
||||
module_path = module_context.py__file__()
|
||||
if os.path.isabs(path):
|
||||
@@ -87,7 +28,7 @@ def _paths_from_assignment(module_context, expr_stmt):
|
||||
"""
|
||||
Extracts the assigned strings from an assignment that looks as follows::
|
||||
|
||||
>>> sys.path[0:0] = ['module/path', 'another/module/path']
|
||||
sys.path[0:0] = ['module/path', 'another/module/path']
|
||||
|
||||
This function is in general pretty tolerant (and therefore 'buggy').
|
||||
However, it's not a big issue usually to add more paths to Jedi's sys_path,
|
||||
|
||||
Reference in New Issue
Block a user