mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-07 22:44:27 +08:00
Merge branch 'master' into typeshed
This commit is contained in:
@@ -3,11 +3,19 @@
|
|||||||
Changelog
|
Changelog
|
||||||
---------
|
---------
|
||||||
|
|
||||||
0.13.0 ()
|
0.13.1 (2018-10-02)
|
||||||
+++++++++++++++++++
|
+++++++++++++++++++
|
||||||
|
|
||||||
|
- Bugfixes, because tensorflow completions were still slow.
|
||||||
|
|
||||||
|
0.13.0 (2018-10-02)
|
||||||
|
+++++++++++++++++++
|
||||||
|
|
||||||
|
- A small release. Some bug fixes.
|
||||||
- Remove Python 3.3 support. Python 3.3 support has been dropped by the Python
|
- Remove Python 3.3 support. Python 3.3 support has been dropped by the Python
|
||||||
foundation.
|
foundation.
|
||||||
|
- Default environments are now using the same Python version as the Python
|
||||||
|
process. In 0.12.x, we used to load the latest Python version on the system.
|
||||||
- Added ``include_builtins`` as a parameter to usages.
|
- Added ``include_builtins`` as a parameter to usages.
|
||||||
- ``goto_assignments`` has a new ``follow_builtin_imports`` parameter that
|
- ``goto_assignments`` has a new ``follow_builtin_imports`` parameter that
|
||||||
changes the previous behavior slightly.
|
changes the previous behavior slightly.
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ As you see Jedi is pretty simple and allows you to concentrate on writing a
|
|||||||
good text editor, while still having very good IDE features for Python.
|
good text editor, while still having very good IDE features for Python.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__version__ = '0.12.1'
|
__version__ = '0.13.1'
|
||||||
|
|
||||||
from jedi.api import Script, Interpreter, set_debug_function, \
|
from jedi.api import Script, Interpreter, set_debug_function, \
|
||||||
preload_module, names
|
preload_module, names
|
||||||
|
|||||||
@@ -179,6 +179,24 @@ class Script(object):
|
|||||||
self._pos, self.call_signatures
|
self._pos, self.call_signatures
|
||||||
)
|
)
|
||||||
completions = completion.completions()
|
completions = completion.completions()
|
||||||
|
|
||||||
|
def iter_import_completions():
|
||||||
|
for c in completions:
|
||||||
|
tree_name = c._name.tree_name
|
||||||
|
if tree_name is None:
|
||||||
|
continue
|
||||||
|
definition = tree_name.get_definition()
|
||||||
|
if definition is not None \
|
||||||
|
and definition.type in ('import_name', 'import_from'):
|
||||||
|
yield c
|
||||||
|
|
||||||
|
if len(list(iter_import_completions())) > 10:
|
||||||
|
# For now disable completions if there's a lot of imports that
|
||||||
|
# might potentially be resolved. This is the case for tensorflow
|
||||||
|
# and has been fixed for it. This is obviously temporary until we
|
||||||
|
# have a better solution.
|
||||||
|
self._evaluator.infer_enabled = False
|
||||||
|
|
||||||
debug.speed('completions end')
|
debug.speed('completions end')
|
||||||
return completions
|
return completions
|
||||||
|
|
||||||
|
|||||||
@@ -184,16 +184,21 @@ def get_default_environment():
|
|||||||
if virtual_env is not None:
|
if virtual_env is not None:
|
||||||
return virtual_env
|
return virtual_env
|
||||||
|
|
||||||
for environment in find_system_environments():
|
# If no VirtualEnv is found, use the environment we're already
|
||||||
return environment
|
|
||||||
|
|
||||||
# If no Python Environment is found, use the environment we're already
|
|
||||||
# using.
|
# using.
|
||||||
return SameEnvironment()
|
return SameEnvironment()
|
||||||
|
|
||||||
|
|
||||||
@time_cache(seconds=10 * 60) # 10 Minutes
|
|
||||||
def get_cached_default_environment():
|
def get_cached_default_environment():
|
||||||
|
environment = _get_cached_default_environment()
|
||||||
|
if environment.path != os.environ.get('VIRTUAL_ENV'):
|
||||||
|
_get_cached_default_environment.clear_cache()
|
||||||
|
return _get_cached_default_environment()
|
||||||
|
return environment
|
||||||
|
|
||||||
|
|
||||||
|
@time_cache(seconds=10 * 60) # 10 Minutes
|
||||||
|
def _get_cached_default_environment():
|
||||||
return get_default_environment()
|
return get_default_environment()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -105,14 +105,17 @@ def get_stack_at_position(grammar, code_lines, module_node, pos):
|
|||||||
# TODO This is for now not an official parso API that exists purely
|
# TODO This is for now not an official parso API that exists purely
|
||||||
# for Jedi.
|
# for Jedi.
|
||||||
tokens = grammar._tokenize(code)
|
tokens = grammar._tokenize(code)
|
||||||
for token_ in tokens:
|
for token in tokens:
|
||||||
if token_.string == safeword:
|
if token.string == safeword:
|
||||||
raise EndMarkerReached()
|
raise EndMarkerReached()
|
||||||
elif token_.prefix.endswith(safeword):
|
elif token.prefix.endswith(safeword):
|
||||||
# This happens with comments.
|
# This happens with comments.
|
||||||
raise EndMarkerReached()
|
raise EndMarkerReached()
|
||||||
|
elif token.string.endswith(safeword):
|
||||||
|
yield token # Probably an f-string literal that was not finished.
|
||||||
|
raise EndMarkerReached()
|
||||||
else:
|
else:
|
||||||
yield token_
|
yield token
|
||||||
|
|
||||||
# The code might be indedented, just remove it.
|
# The code might be indedented, just remove it.
|
||||||
code = dedent(_get_code_for_stack(code_lines, module_node, pos))
|
code = dedent(_get_code_for_stack(code_lines, module_node, pos))
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
"""
|
"""
|
||||||
To use Jedi completion in Python interpreter, add the following in your shell
|
To use Jedi completion in Python interpreter, add the following in your shell
|
||||||
setup (e.g., ``.bashrc``)::
|
setup (e.g., ``.bashrc``). This works only on Linux/Mac, because readline is
|
||||||
|
not available on Windows. If you still want Jedi autocompletion in your REPL,
|
||||||
|
just use IPython instead::
|
||||||
|
|
||||||
export PYTHONSTARTUP="$(python -m jedi repl)"
|
export PYTHONSTARTUP="$(python -m jedi repl)"
|
||||||
|
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ def time_cache(seconds):
|
|||||||
|
|
||||||
wrapper.clear_cache = lambda: cache.clear()
|
wrapper.clear_cache = lambda: cache.clear()
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -118,6 +118,9 @@ class Evaluator(object):
|
|||||||
self.is_analysis = False
|
self.is_analysis = False
|
||||||
self.project = project
|
self.project = project
|
||||||
self.access_cache = {}
|
self.access_cache = {}
|
||||||
|
# This setting is only temporary to limit the work we have to do with
|
||||||
|
# tensorflow and others.
|
||||||
|
self.infer_enabled = True
|
||||||
|
|
||||||
self.reset_recursion_limitations()
|
self.reset_recursion_limitations()
|
||||||
self.allow_different_encoding = True
|
self.allow_different_encoding = True
|
||||||
@@ -170,6 +173,9 @@ class Evaluator(object):
|
|||||||
return self.project._get_sys_path(self, environment=self.environment)
|
return self.project._get_sys_path(self, environment=self.environment)
|
||||||
|
|
||||||
def eval_element(self, context, element):
|
def eval_element(self, context, element):
|
||||||
|
if not self.infer_enabled:
|
||||||
|
return NO_CONTEXTS
|
||||||
|
|
||||||
if isinstance(context, CompForContext):
|
if isinstance(context, CompForContext):
|
||||||
return eval_node(context, element)
|
return eval_node(context, element)
|
||||||
|
|
||||||
|
|||||||
@@ -54,8 +54,12 @@ def get_string_context_set(evaluator):
|
|||||||
return execute_evaluated(builtin_from_name(evaluator, u'str'))
|
return execute_evaluated(builtin_from_name(evaluator, u'str'))
|
||||||
|
|
||||||
|
|
||||||
def load_module(evaluator, **kwargs):
|
def load_module(evaluator, dotted_name, **kwargs):
|
||||||
access_path = evaluator.compiled_subprocess.load_module(**kwargs)
|
# Temporary, some tensorflow builtins cannot be loaded, so it's tried again
|
||||||
|
# and again and it's really slow.
|
||||||
|
if dotted_name.startswith('tensorflow.'):
|
||||||
|
return None
|
||||||
|
access_path = evaluator.compiled_subprocess.load_module(dotted_name=dotted_name, **kwargs)
|
||||||
if access_path is None:
|
if access_path is None:
|
||||||
return None
|
return None
|
||||||
return create_from_access_path(evaluator, access_path)
|
return create_from_access_path(evaluator, access_path)
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ class Importer(object):
|
|||||||
return sys_path_mod
|
return sys_path_mod
|
||||||
|
|
||||||
def follow(self):
|
def follow(self):
|
||||||
if not self.import_path:
|
if not self.import_path or not self._evaluator.infer_enabled:
|
||||||
return NO_CONTEXTS
|
return NO_CONTEXTS
|
||||||
|
|
||||||
import_names = tuple(
|
import_names = tuple(
|
||||||
|
|||||||
@@ -154,6 +154,9 @@ def global_define():
|
|||||||
#? int()
|
#? int()
|
||||||
global_var_in_func
|
global_var_in_func
|
||||||
|
|
||||||
|
#? ['global_var_in_func']
|
||||||
|
global_var_in_f
|
||||||
|
|
||||||
|
|
||||||
def funct1():
|
def funct1():
|
||||||
# From issue #610
|
# From issue #610
|
||||||
@@ -175,6 +178,7 @@ def init_global_var_predefined():
|
|||||||
#? int() None
|
#? int() None
|
||||||
global_var_predefined
|
global_var_predefined
|
||||||
|
|
||||||
|
|
||||||
# -----------------
|
# -----------------
|
||||||
# within docstrs
|
# within docstrs
|
||||||
# -----------------
|
# -----------------
|
||||||
|
|||||||
@@ -28,3 +28,7 @@ Fr'''sasdf''' + ''
|
|||||||
|
|
||||||
#? ['upper']
|
#? ['upper']
|
||||||
f'xyz'.uppe
|
f'xyz'.uppe
|
||||||
|
|
||||||
|
|
||||||
|
#? 3 []
|
||||||
|
f'f'
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import jedi
|
|||||||
from jedi._compatibility import py_version
|
from jedi._compatibility import py_version
|
||||||
from jedi.api.environment import get_default_environment, find_virtualenvs, \
|
from jedi.api.environment import get_default_environment, find_virtualenvs, \
|
||||||
InvalidPythonEnvironment, find_system_environments, \
|
InvalidPythonEnvironment, find_system_environments, \
|
||||||
get_system_environment, create_environment
|
get_system_environment, create_environment, get_cached_default_environment
|
||||||
|
|
||||||
|
|
||||||
def test_sys_path():
|
def test_sys_path():
|
||||||
@@ -129,3 +129,10 @@ def test_get_default_environment_from_env_does_not_use_safe(tmpdir, monkeypatch)
|
|||||||
monkeypatch.setenv('VIRTUAL_ENV', fake_python)
|
monkeypatch.setenv('VIRTUAL_ENV', fake_python)
|
||||||
env = get_default_environment()
|
env = get_default_environment()
|
||||||
assert env.path == 'fake'
|
assert env.path == 'fake'
|
||||||
|
|
||||||
|
|
||||||
|
def test_changing_venv(venv_path, monkeypatch):
|
||||||
|
monkeypatch.setitem(os.environ, 'VIRTUAL_ENV', venv_path)
|
||||||
|
get_cached_default_environment()
|
||||||
|
monkeypatch.setitem(os.environ, 'VIRTUAL_ENV', sys.executable)
|
||||||
|
assert get_cached_default_environment().executable == sys.executable
|
||||||
|
|||||||
Reference in New Issue
Block a user