Refactor environments a bit

This commit is contained in:
Dave Halter
2017-12-17 18:47:28 +01:00
parent 1c62db04ba
commit fe3e8a0867
5 changed files with 50 additions and 31 deletions

View File

@@ -41,4 +41,4 @@ __version__ = '0.11.0'
from jedi.api import Script, Interpreter, set_debug_function, \ from jedi.api import Script, Interpreter, set_debug_function, \
preload_module, names preload_module, names
from jedi import settings from jedi import settings
from jedi.api.environment import find_virtualenvs, create_environment from jedi.api.environment import find_virtualenvs, find_python_environments

View File

@@ -24,7 +24,7 @@ from jedi.api import classes
from jedi.api import interpreter from jedi.api import interpreter
from jedi.api import helpers from jedi.api import helpers
from jedi.api.completion import Completion from jedi.api.completion import Completion
from jedi.api.environment import get_default_environment from jedi.api.environment import InterpreterEnvironment
from jedi.evaluate import Evaluator from jedi.evaluate import Evaluator
from jedi.evaluate import imports from jedi.evaluate import imports
from jedi.evaluate import usages from jedi.evaluate import usages
@@ -115,14 +115,7 @@ class Script(object):
# Load the Python grammar of the current interpreter. # Load the Python grammar of the current interpreter.
self._grammar = parso.load_grammar() self._grammar = parso.load_grammar()
project = Project(sys_path=sys_path) project = Project(sys_path=sys_path)
if isinstance(self, Interpreter): self._evaluator = Evaluator(self._grammar, project, environment)
# It's not possible to use a subprocess for the interpreter.
compiled_subprocess = None
else:
if environment is None:
environment = get_default_environment()
compiled_subprocess = environment.get_subprocess()
self._evaluator = Evaluator(self._grammar, project, compiled_subprocess)
project.add_script_path(self.path) project.add_script_path(self.path)
debug.speed('init') debug.speed('init')
@@ -366,10 +359,14 @@ class Interpreter(Script):
except Exception: except Exception:
raise TypeError("namespaces must be a non-empty list of dicts.") raise TypeError("namespaces must be a non-empty list of dicts.")
if 'environment' in kwds: environment = kwds.get('environment', None)
raise TypeError("Environments are not allowed when using an interpreter.") if environment is None:
environment = InterpreterEnvironment()
else:
if not isinstance(environment, InterpreterEnvironment):
raise TypeError("The environment needs to be an InterpreterEnvironment subclass.")
super(Interpreter, self).__init__(source, **kwds) super(Interpreter, self).__init__(source, environment=environment, **kwds)
self.namespaces = namespaces self.namespaces = namespaces
def _get_module(self): def _get_module(self):

View File

@@ -9,7 +9,8 @@ from distutils.spawn import find_executable
from jedi.evaluate.project import Project from jedi.evaluate.project import Project
from jedi.cache import memoize_method from jedi.cache import memoize_method
from jedi.evaluate.compiled.subprocess import get_subprocess from jedi.evaluate.compiled.subprocess import get_subprocess, \
EvaluatorSameProcess, EvaluatorSubprocess
import parso import parso
@@ -22,7 +23,17 @@ class InvalidPythonEnvironment(Exception):
pass pass
class Environment(object): class _BaseEnvironment(object):
def get_project(self):
return Project(self.get_sys_path())
@memoize_method
def get_parser(self):
version_string = '%s.%s' % (self.version_info.major, self.version_info.minor)
return parso.load_grammar(version=version_string)
class Environment(_BaseEnvironment):
def __init__(self, path, executable): def __init__(self, path, executable):
self._base_path = path self._base_path = path
self._executable = executable self._executable = executable
@@ -31,17 +42,12 @@ class Environment(object):
def __repr__(self): def __repr__(self):
return '<%s: %s>' % (self.__class__.__name__, self._base_path) return '<%s: %s>' % (self.__class__.__name__, self._base_path)
def get_project(self): def get_evaluator_subprocess(self, evaluator):
return Project(self.get_sys_path()) return EvaluatorSubprocess(evaluator, self._get_subprocess())
def get_subprocess(self): def _get_subprocess(self):
return get_subprocess(self._executable) return get_subprocess(self._executable)
@memoize_method
def get_parser(self):
version_string = '%s.%s' % (self.version_info.major, self.version_info.minor)
return parso.load_grammar(version=version_string)
@memoize_method @memoize_method
def get_sys_path(self): def get_sys_path(self):
# It's pretty much impossible to generate the sys path without actually # It's pretty much impossible to generate the sys path without actually
@@ -49,7 +55,18 @@ class Environment(object):
# on how the Python version was compiled (ENV variables). # on how the Python version was compiled (ENV variables).
# If you omit -S when starting Python (normal case), additionally # If you omit -S when starting Python (normal case), additionally
# site.py gets executed. # site.py gets executed.
return self.get_subprocess().get_sys_path() return self._get_subprocess().get_sys_path()
class InterpreterEnvironment(_BaseEnvironment):
def __init__(self):
self.version_info = _VersionInfo(*sys.version_info[:3])
def get_evaluator_subprocess(self, evaluator):
return EvaluatorSameProcess(evaluator)
def get_sys_path(self):
return sys.sys_path
def get_default_environment(): def get_default_environment():

View File

@@ -69,6 +69,7 @@ import parso
from jedi import debug from jedi import debug
from jedi import parser_utils from jedi import parser_utils
from jedi.api.environment import get_default_environment
from jedi.evaluate.utils import unite from jedi.evaluate.utils import unite
from jedi.evaluate import imports from jedi.evaluate import imports
from jedi.evaluate import recursion from jedi.evaluate import recursion
@@ -83,11 +84,10 @@ from jedi.evaluate.context import ClassContext, FunctionContext, \
from jedi.evaluate.context.iterable import CompForContext from jedi.evaluate.context.iterable import CompForContext
from jedi.evaluate.syntax_tree import eval_trailer, eval_expr_stmt, \ from jedi.evaluate.syntax_tree import eval_trailer, eval_expr_stmt, \
eval_node, check_tuple_assignments eval_node, check_tuple_assignments
from jedi.evaluate.compiled.subprocess import EvaluatorSubprocess, EvaluatorSameProcess
class Evaluator(object): class Evaluator(object):
def __init__(self, grammar, project, compiled_sub_process=None): def __init__(self, grammar, project, environment=None):
self.grammar = grammar self.grammar = grammar
self.latest_grammar = parso.load_grammar(version='3.6') self.latest_grammar = parso.load_grammar(version='3.6')
self.memoize_cache = {} # for memoize decorators self.memoize_cache = {} # for memoize decorators
@@ -104,10 +104,10 @@ class Evaluator(object):
self.access_cache = {} self.access_cache = {}
project.add_evaluator(self) project.add_evaluator(self)
if compiled_sub_process is None: if environment is None:
self.compiled_subprocess = EvaluatorSameProcess(self) environment = get_default_environment()
else: self.environment = environment
self.compiled_subprocess = EvaluatorSubprocess(self, compiled_sub_process) self.compiled_subprocess = environment.get_evaluator_subprocess(self)
self.reset_recursion_limitations() self.reset_recursion_limitations()

View File

@@ -201,7 +201,12 @@ class Listener(object):
try: try:
evaluator = self._evaluators[evaluator_id] evaluator = self._evaluators[evaluator_id]
except KeyError: except KeyError:
evaluator = Evaluator(None, project=project.Project()) from jedi.api.environment import InterpreterEnvironment
evaluator = Evaluator(
grammar=None,
project=project.Project(),
environment=InterpreterEnvironment()
)
self._evaluators[evaluator_id] = evaluator self._evaluators[evaluator_id] = evaluator
return evaluator return evaluator