forked from VimPlug/jedi
Merge branch 'master' into deprecations
This commit is contained in:
@@ -49,7 +49,7 @@ from jedi.inference.utils import to_list
|
||||
sys.setrecursionlimit(3000)
|
||||
|
||||
|
||||
class Script(object):
|
||||
class Script:
|
||||
"""
|
||||
A Script is the base for completions, goto or whatever you want to do with
|
||||
Jedi. The counter part of this class is :class:`Interpreter`, which works
|
||||
@@ -122,7 +122,7 @@ class Script(object):
|
||||
self._module_node, code = self._inference_state.parse_and_get_code(
|
||||
code=code,
|
||||
path=self.path,
|
||||
use_latest_grammar=path and path.suffix == 'pyi',
|
||||
use_latest_grammar=path and path.suffix == '.pyi',
|
||||
cache=False, # No disk cache, because the current script often changes.
|
||||
diff_cache=settings.fast_parser,
|
||||
cache_path=settings.cache_directory,
|
||||
@@ -157,6 +157,7 @@ class Script(object):
|
||||
# We are in a stub file. Try to load the stub properly.
|
||||
stub_module = load_proper_stub_module(
|
||||
self._inference_state,
|
||||
self._inference_state.latest_grammar,
|
||||
file_io,
|
||||
names,
|
||||
self._module_node
|
||||
@@ -234,6 +235,11 @@ class Script(object):
|
||||
leaf = self._module_node.get_leaf_for_position(pos)
|
||||
if leaf is None or leaf.type == 'string':
|
||||
return []
|
||||
if leaf.end_pos == (line, column) and leaf.type == 'operator':
|
||||
next_ = leaf.get_next_leaf()
|
||||
if next_.start_pos == leaf.end_pos \
|
||||
and next_.type in ('number', 'string', 'keyword'):
|
||||
leaf = next_
|
||||
|
||||
context = self._get_module_context().create_context(leaf)
|
||||
|
||||
|
||||
@@ -14,18 +14,18 @@ These classes are the much biggest part of the API, because they contain
|
||||
the interesting information about all operations.
|
||||
"""
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from parso.python.tree import search_ancestor
|
||||
from parso.tree import search_ancestor
|
||||
|
||||
from jedi import settings
|
||||
from jedi import debug
|
||||
from jedi.inference.utils import unite
|
||||
from jedi.cache import memoize_method
|
||||
from jedi.inference import imports
|
||||
from jedi.inference.imports import ImportName
|
||||
from jedi.inference.compiled.mixed import MixedName
|
||||
from jedi.inference.gradual.typeshed import StubModuleValue
|
||||
from jedi.inference.names import ImportName, SubModuleName
|
||||
from jedi.inference.gradual.stub_value import StubModuleValue
|
||||
from jedi.inference.gradual.conversion import convert_names, convert_values
|
||||
from jedi.inference.base_value import ValueSet
|
||||
from jedi.api.keywords import KeywordName
|
||||
@@ -53,7 +53,7 @@ def _values_to_definitions(values):
|
||||
return [Name(c.inference_state, c.name) for c in values]
|
||||
|
||||
|
||||
class BaseName(object):
|
||||
class BaseName:
|
||||
"""
|
||||
The base class for all definitions, completions and signatures.
|
||||
"""
|
||||
@@ -92,17 +92,15 @@ class BaseName(object):
|
||||
return self._name.get_root_context()
|
||||
|
||||
@property
|
||||
def module_path(self) -> Optional[str]:
|
||||
def module_path(self) -> Optional[Path]:
|
||||
"""
|
||||
Shows the file path of a module. e.g. ``/usr/lib/python3.9/os.py``
|
||||
|
||||
:rtype: str or None
|
||||
"""
|
||||
module = self._get_module_context()
|
||||
if module.is_stub() or not module.is_compiled():
|
||||
# Compiled modules should not return a module path even if they
|
||||
# have one.
|
||||
path = self._get_module_context().py__file__()
|
||||
path: Optional[Path] = self._get_module_context().py__file__()
|
||||
if path is not None:
|
||||
return path
|
||||
|
||||
@@ -185,7 +183,7 @@ class BaseName(object):
|
||||
tree_name.is_definition():
|
||||
resolve = True
|
||||
|
||||
if isinstance(self._name, imports.SubModuleName) or resolve:
|
||||
if isinstance(self._name, SubModuleName) or resolve:
|
||||
for value in self._name.infer():
|
||||
return value.api_type
|
||||
return self._name.api_type
|
||||
@@ -720,6 +718,24 @@ class Completion(BaseName):
|
||||
|
||||
return super().type
|
||||
|
||||
def get_completion_prefix_length(self):
|
||||
"""
|
||||
Returns the length of the prefix being completed.
|
||||
For example, completing ``isinstance``::
|
||||
|
||||
isinstan# <-- Cursor is here
|
||||
|
||||
would return 8, because len('isinstan') == 8.
|
||||
|
||||
Assuming the following function definition::
|
||||
|
||||
def foo(param=0):
|
||||
pass
|
||||
|
||||
completing ``foo(par`` would return 3.
|
||||
"""
|
||||
return self._like_name_length
|
||||
|
||||
def __repr__(self):
|
||||
return '<%s: %s>' % (type(self).__name__, self._name.get_public_name())
|
||||
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
_cache = {}
|
||||
from typing import Dict, Tuple, Callable
|
||||
|
||||
CacheValues = Tuple[str, str, str]
|
||||
CacheValuesCallback = Callable[[], CacheValues]
|
||||
|
||||
|
||||
def save_entry(module_name, name, cache):
|
||||
_cache: Dict[str, Dict[str, CacheValues]] = {}
|
||||
|
||||
|
||||
def save_entry(module_name: str, name: str, cache: CacheValues) -> None:
|
||||
try:
|
||||
module_cache = _cache[module_name]
|
||||
except KeyError:
|
||||
@@ -9,8 +15,8 @@ def save_entry(module_name, name, cache):
|
||||
module_cache[name] = cache
|
||||
|
||||
|
||||
def _create_get_from_cache(number):
|
||||
def _get_from_cache(module_name, name, get_cache_values):
|
||||
def _create_get_from_cache(number: int) -> Callable[[str, str, CacheValuesCallback], str]:
|
||||
def _get_from_cache(module_name: str, name: str, get_cache_values: CacheValuesCallback) -> str:
|
||||
try:
|
||||
return _cache[module_name][name][number]
|
||||
except KeyError:
|
||||
|
||||
@@ -30,7 +30,7 @@ class InvalidPythonEnvironment(Exception):
|
||||
"""
|
||||
|
||||
|
||||
class _BaseEnvironment(object):
|
||||
class _BaseEnvironment:
|
||||
@memoize_method
|
||||
def get_grammar(self):
|
||||
version_string = '%s.%s' % (self.version_info.major, self.version_info.minor)
|
||||
@@ -121,7 +121,7 @@ class Environment(_BaseEnvironment):
|
||||
return self._get_subprocess().get_sys_path()
|
||||
|
||||
|
||||
class _SameEnvironmentMixin(object):
|
||||
class _SameEnvironmentMixin:
|
||||
def __init__(self):
|
||||
self._start_executable = self.executable = sys.executable
|
||||
self.path = sys.prefix
|
||||
@@ -384,7 +384,8 @@ def _get_executable_path(path, safe=True):
|
||||
|
||||
|
||||
def _get_executables_from_windows_registry(version):
|
||||
import winreg
|
||||
# https://github.com/python/typeshed/pull/3794 adds winreg
|
||||
import winreg # type: ignore[import]
|
||||
|
||||
# TODO: support Python Anaconda.
|
||||
sub_keys = [
|
||||
|
||||
@@ -8,7 +8,7 @@ def parso_to_jedi_errors(grammar, module_node):
|
||||
return [SyntaxError(e) for e in grammar.iter_errors(module_node)]
|
||||
|
||||
|
||||
class SyntaxError(object):
|
||||
class SyntaxError:
|
||||
"""
|
||||
Syntax errors are generated by :meth:`.Script.get_syntax_errors`.
|
||||
"""
|
||||
|
||||
@@ -203,7 +203,7 @@ def filter_follow_imports(names, follow_builtin_imports=False):
|
||||
yield name
|
||||
|
||||
|
||||
class CallDetails(object):
|
||||
class CallDetails:
|
||||
def __init__(self, bracket_leaf, children, position):
|
||||
['bracket_leaf', 'call_index', 'keyword_name_str']
|
||||
self.bracket_leaf = bracket_leaf
|
||||
|
||||
@@ -17,7 +17,7 @@ def _create(inference_state, obj):
|
||||
)
|
||||
|
||||
|
||||
class NamespaceObject(object):
|
||||
class NamespaceObject:
|
||||
def __init__(self, dct):
|
||||
self.__dict__ = dct
|
||||
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
import pydoc
|
||||
from contextlib import suppress
|
||||
from typing import Dict, Optional
|
||||
|
||||
from jedi.inference.names import AbstractArbitraryName
|
||||
|
||||
from pydoc_data import topics as pydoc_topics
|
||||
try:
|
||||
# https://github.com/python/typeshed/pull/4351 adds pydoc_data
|
||||
from pydoc_data import topics # type: ignore[import]
|
||||
pydoc_topics: Optional[Dict[str, str]] = topics.topics
|
||||
except ImportError:
|
||||
# Python 3.6.8 embeddable does not have pydoc_data.
|
||||
pydoc_topics = None
|
||||
|
||||
|
||||
class KeywordName(AbstractArbitraryName):
|
||||
@@ -40,6 +47,6 @@ def imitate_pydoc(string):
|
||||
return ''
|
||||
|
||||
try:
|
||||
return pydoc_topics.topics[label].strip() if pydoc_topics else ''
|
||||
return pydoc_topics[label].strip() if pydoc_topics else ''
|
||||
except KeyError:
|
||||
return ''
|
||||
|
||||
@@ -56,7 +56,7 @@ def _remove_duplicates_from_path(path):
|
||||
yield p
|
||||
|
||||
|
||||
class Project(object):
|
||||
class Project:
|
||||
"""
|
||||
Projects are a simple way to manage Python folders and define how Jedi does
|
||||
import resolution. It is mostly used as a parameter to :class:`.Script`.
|
||||
@@ -152,6 +152,29 @@ class Project(object):
|
||||
"""
|
||||
return self._path
|
||||
|
||||
@property
|
||||
def sys_path(self):
|
||||
"""
|
||||
The sys path provided to this project. This can be None and in that
|
||||
case will be auto generated.
|
||||
"""
|
||||
return self._sys_path
|
||||
|
||||
@property
|
||||
def smart_sys_path(self):
|
||||
"""
|
||||
If the sys path is going to be calculated in a smart way, where
|
||||
additional paths are added.
|
||||
"""
|
||||
return self._smart_sys_path
|
||||
|
||||
@property
|
||||
def load_unsafe_extensions(self):
|
||||
"""
|
||||
Wheter the project loads unsafe extensions.
|
||||
"""
|
||||
return self._load_unsafe_extensions
|
||||
|
||||
@inference_state_as_method_param_cache()
|
||||
def _get_base_sys_path(self, inference_state):
|
||||
# The sys path has not been set explicitly.
|
||||
@@ -343,8 +366,11 @@ class Project(object):
|
||||
|
||||
def _is_potential_project(path):
|
||||
for name in _CONTAINS_POTENTIAL_PROJECT:
|
||||
if path.joinpath(name).exists():
|
||||
return True
|
||||
try:
|
||||
if path.joinpath(name).exists():
|
||||
return True
|
||||
except OSError:
|
||||
continue
|
||||
return False
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ EXPRESSION_PARTS = (
|
||||
).split()
|
||||
|
||||
|
||||
class ChangedFile(object):
|
||||
class ChangedFile:
|
||||
def __init__(self, inference_state, from_path, to_path,
|
||||
module_node, node_to_str_map):
|
||||
self._inference_state = inference_state
|
||||
@@ -72,7 +72,7 @@ class ChangedFile(object):
|
||||
return '<%s: %s>' % (self.__class__.__name__, self._from_path)
|
||||
|
||||
|
||||
class Refactoring(object):
|
||||
class Refactoring:
|
||||
def __init__(self, inference_state, file_to_node_changes, renames=()):
|
||||
self._inference_state = inference_state
|
||||
self._renames = renames
|
||||
|
||||
Reference in New Issue
Block a user