forked from VimPlug/jedi
Introduce some stricter typing
This commit is contained in:
+27
-23
@@ -8,7 +8,7 @@ import hashlib
|
|||||||
import filecmp
|
import filecmp
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from shutil import which
|
from shutil import which
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
from jedi.cache import memoize_method, time_cache
|
from jedi.cache import memoize_method, time_cache
|
||||||
from jedi.inference.compiled.subprocess import CompiledSubprocess, \
|
from jedi.inference.compiled.subprocess import CompiledSubprocess, \
|
||||||
@@ -36,6 +36,9 @@ class InvalidPythonEnvironment(Exception):
|
|||||||
|
|
||||||
|
|
||||||
class _BaseEnvironment:
|
class _BaseEnvironment:
|
||||||
|
version_info: Any
|
||||||
|
executable: Any
|
||||||
|
|
||||||
@memoize_method
|
@memoize_method
|
||||||
def get_grammar(self):
|
def get_grammar(self):
|
||||||
version_string = '%s.%s' % (self.version_info.major, self.version_info.minor)
|
version_string = '%s.%s' % (self.version_info.major, self.version_info.minor)
|
||||||
@@ -355,7 +358,7 @@ def get_system_environment(version, *, env_vars=None):
|
|||||||
return SameEnvironment()
|
return SameEnvironment()
|
||||||
return Environment(exe)
|
return Environment(exe)
|
||||||
|
|
||||||
if os.name == 'nt':
|
if sys.platform == "win32":
|
||||||
for exe in _get_executables_from_windows_registry(version):
|
for exe in _get_executables_from_windows_registry(version):
|
||||||
try:
|
try:
|
||||||
return Environment(exe, env_vars=env_vars)
|
return Environment(exe, env_vars=env_vars)
|
||||||
@@ -383,7 +386,7 @@ def _get_executable_path(path, safe=True):
|
|||||||
Returns None if it's not actually a virtual env.
|
Returns None if it's not actually a virtual env.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if os.name == 'nt':
|
if sys.platform == "win32":
|
||||||
pythons = [os.path.join(path, 'Scripts', 'python.exe'), os.path.join(path, 'python.exe')]
|
pythons = [os.path.join(path, 'Scripts', 'python.exe'), os.path.join(path, 'python.exe')]
|
||||||
else:
|
else:
|
||||||
pythons = [os.path.join(path, 'bin', 'python')]
|
pythons = [os.path.join(path, 'bin', 'python')]
|
||||||
@@ -397,27 +400,28 @@ def _get_executable_path(path, safe=True):
|
|||||||
return python
|
return python
|
||||||
|
|
||||||
|
|
||||||
def _get_executables_from_windows_registry(version):
|
if sys.platform == "win32":
|
||||||
import winreg
|
def _get_executables_from_windows_registry(version):
|
||||||
|
import winreg
|
||||||
|
|
||||||
# TODO: support Python Anaconda.
|
# TODO: support Python Anaconda.
|
||||||
sub_keys = [
|
sub_keys = [
|
||||||
r'SOFTWARE\Python\PythonCore\{version}\InstallPath',
|
r'SOFTWARE\Python\PythonCore\{version}\InstallPath',
|
||||||
r'SOFTWARE\Wow6432Node\Python\PythonCore\{version}\InstallPath',
|
r'SOFTWARE\Wow6432Node\Python\PythonCore\{version}\InstallPath',
|
||||||
r'SOFTWARE\Python\PythonCore\{version}-32\InstallPath',
|
r'SOFTWARE\Python\PythonCore\{version}-32\InstallPath',
|
||||||
r'SOFTWARE\Wow6432Node\Python\PythonCore\{version}-32\InstallPath'
|
r'SOFTWARE\Wow6432Node\Python\PythonCore\{version}-32\InstallPath'
|
||||||
]
|
]
|
||||||
for root_key in [winreg.HKEY_CURRENT_USER, winreg.HKEY_LOCAL_MACHINE]:
|
for root_key in [winreg.HKEY_CURRENT_USER, winreg.HKEY_LOCAL_MACHINE]:
|
||||||
for sub_key in sub_keys:
|
for sub_key in sub_keys:
|
||||||
sub_key = sub_key.format(version=version)
|
sub_key = sub_key.format(version=version)
|
||||||
try:
|
try:
|
||||||
with winreg.OpenKey(root_key, sub_key) as key:
|
with winreg.OpenKey(root_key, sub_key) as key:
|
||||||
prefix = winreg.QueryValueEx(key, '')[0]
|
prefix = winreg.QueryValueEx(key, '')[0]
|
||||||
exe = os.path.join(prefix, 'python.exe')
|
exe = os.path.join(prefix, 'python.exe')
|
||||||
if os.path.isfile(exe):
|
if os.path.isfile(exe):
|
||||||
yield exe
|
yield exe
|
||||||
except WindowsError:
|
except WindowsError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def _assert_safe(executable_path, safe):
|
def _assert_safe(executable_path, safe):
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ def imitate_pydoc(string):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
# is a tuple now
|
# is a tuple now
|
||||||
label, related = string
|
label, related = string # type: ignore[misc]
|
||||||
except TypeError:
|
except TypeError:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from parso import file_io
|
from parso import file_io
|
||||||
|
|
||||||
@@ -58,6 +59,8 @@ class FolderIO(AbstractFolderIO):
|
|||||||
|
|
||||||
|
|
||||||
class FileIOFolderMixin:
|
class FileIOFolderMixin:
|
||||||
|
path: Any
|
||||||
|
|
||||||
def get_parent_folder(self):
|
def get_parent_folder(self):
|
||||||
return FolderIO(os.path.dirname(self.path))
|
return FolderIO(os.path.dirname(self.path))
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,8 @@ I need to mention now that lazy type inference is really good because it
|
|||||||
only *inferes* what needs to be *inferred*. All the statements and modules
|
only *inferes* what needs to be *inferred*. All the statements and modules
|
||||||
that are not used are just being ignored.
|
that are not used are just being ignored.
|
||||||
"""
|
"""
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import parso
|
import parso
|
||||||
from jedi.file_io import FileIO
|
from jedi.file_io import FileIO
|
||||||
|
|
||||||
@@ -82,6 +84,7 @@ from jedi.plugins import plugin_manager
|
|||||||
|
|
||||||
|
|
||||||
class InferenceState:
|
class InferenceState:
|
||||||
|
analysis_modules: list[Any]
|
||||||
def __init__(self, project, environment=None, script_path=None):
|
def __init__(self, project, environment=None, script_path=None):
|
||||||
if environment is None:
|
if environment is None:
|
||||||
environment = project.get_environment()
|
environment = project.get_environment()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import re
|
import re
|
||||||
from itertools import zip_longest
|
from itertools import zip_longest
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from parso.python import tree
|
from parso.python import tree
|
||||||
|
|
||||||
@@ -164,6 +165,8 @@ def unpack_arglist(arglist):
|
|||||||
|
|
||||||
|
|
||||||
class TreeArguments(AbstractArguments):
|
class TreeArguments(AbstractArguments):
|
||||||
|
context: Any
|
||||||
|
|
||||||
def __init__(self, inference_state, context, argument_node, trailer=None):
|
def __init__(self, inference_state, context, argument_node, trailer=None):
|
||||||
"""
|
"""
|
||||||
:param argument_node: May be an argument_node or a list of nodes.
|
:param argument_node: May be an argument_node or a list of nodes.
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ just one.
|
|||||||
from functools import reduce
|
from functools import reduce
|
||||||
from operator import add
|
from operator import add
|
||||||
from itertools import zip_longest
|
from itertools import zip_longest
|
||||||
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
from parso.python.tree import Name
|
from parso.python.tree import Name
|
||||||
|
|
||||||
@@ -21,12 +22,25 @@ from jedi.cache import memoize_method
|
|||||||
|
|
||||||
sentinel = object()
|
sentinel = object()
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from jedi.inference import InferenceState
|
||||||
|
|
||||||
|
|
||||||
class HasNoContext(Exception):
|
class HasNoContext(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class HelperValueMixin:
|
class HelperValueMixin:
|
||||||
|
parent_context: Any
|
||||||
|
inference_state: "InferenceState"
|
||||||
|
name: Any
|
||||||
|
get_filters: Any
|
||||||
|
is_stub: Any
|
||||||
|
py__getattribute__alternatives: Any
|
||||||
|
py__iter__: Any
|
||||||
|
py__mro__: Any
|
||||||
|
_as_context: Any
|
||||||
|
|
||||||
def get_root_context(self):
|
def get_root_context(self):
|
||||||
value = self
|
value = self
|
||||||
if value.parent_context is None:
|
if value.parent_context is None:
|
||||||
@@ -499,7 +513,7 @@ class ValueSet:
|
|||||||
return ValueSet.from_sets(_getitem(c, *args, **kwargs) for c in self._set)
|
return ValueSet.from_sets(_getitem(c, *args, **kwargs) for c in self._set)
|
||||||
|
|
||||||
def try_merge(self, function_name):
|
def try_merge(self, function_name):
|
||||||
value_set = self.__class__([])
|
value_set = ValueSet([])
|
||||||
for c in self._set:
|
for c in self._set:
|
||||||
try:
|
try:
|
||||||
method = getattr(c, function_name)
|
method = getattr(c, function_name)
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import traceback
|
|||||||
import weakref
|
import weakref
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from typing import Dict, TYPE_CHECKING
|
from typing import Dict, TYPE_CHECKING, Any
|
||||||
|
|
||||||
from jedi._compatibility import pickle_dump, pickle_load
|
from jedi._compatibility import pickle_dump, pickle_load
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
@@ -52,7 +52,7 @@ PICKLE_PROTOCOL = 4
|
|||||||
|
|
||||||
|
|
||||||
def _GeneralizedPopen(*args, **kwargs):
|
def _GeneralizedPopen(*args, **kwargs):
|
||||||
if os.name == 'nt':
|
if sys.platform == "win32":
|
||||||
try:
|
try:
|
||||||
# Was introduced in Python 3.7.
|
# Was introduced in Python 3.7.
|
||||||
CREATE_NO_WINDOW = subprocess.CREATE_NO_WINDOW
|
CREATE_NO_WINDOW = subprocess.CREATE_NO_WINDOW
|
||||||
@@ -104,6 +104,8 @@ def _cleanup_process(process, thread):
|
|||||||
|
|
||||||
|
|
||||||
class _InferenceStateProcess:
|
class _InferenceStateProcess:
|
||||||
|
get_compiled_method_return: Any
|
||||||
|
|
||||||
def __init__(self, inference_state: 'InferenceState') -> None:
|
def __init__(self, inference_state: 'InferenceState') -> None:
|
||||||
self._inference_state_weakref = weakref.ref(inference_state)
|
self._inference_state_weakref = weakref.ref(inference_state)
|
||||||
self._handles: Dict[int, AccessHandle] = {}
|
self._handles: Dict[int, AccessHandle] = {}
|
||||||
|
|||||||
@@ -592,7 +592,7 @@ def create_from_name(inference_state, compiled_value, name):
|
|||||||
value = create_cached_compiled_value(
|
value = create_cached_compiled_value(
|
||||||
inference_state,
|
inference_state,
|
||||||
access_path,
|
access_path,
|
||||||
parent_context=None if value is None else value.as_context(),
|
parent_context=None if value is None else value.as_context(), # type: ignore # TODO
|
||||||
)
|
)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
@@ -610,7 +610,7 @@ def create_from_access_path(inference_state, access_path):
|
|||||||
value = create_cached_compiled_value(
|
value = create_cached_compiled_value(
|
||||||
inference_state,
|
inference_state,
|
||||||
access,
|
access,
|
||||||
parent_context=None if value is None else value.as_context()
|
parent_context=None if value is None else value.as_context() # type: ignore # TODO
|
||||||
)
|
)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional
|
from typing import Optional, Any
|
||||||
|
|
||||||
from parso.python.tree import Name
|
from parso.python.tree import Name
|
||||||
|
|
||||||
@@ -16,6 +16,8 @@ from jedi import parser_utils
|
|||||||
|
|
||||||
class AbstractContext:
|
class AbstractContext:
|
||||||
# Must be defined: inference_state and tree_node and parent_context as an attribute/property
|
# Must be defined: inference_state and tree_node and parent_context as an attribute/property
|
||||||
|
tree_node: Any
|
||||||
|
parent_context: Any
|
||||||
|
|
||||||
def __init__(self, inference_state):
|
def __init__(self, inference_state):
|
||||||
self.inference_state = inference_state
|
self.inference_state = inference_state
|
||||||
@@ -218,6 +220,13 @@ class ValueContext(AbstractContext):
|
|||||||
|
|
||||||
|
|
||||||
class TreeContextMixin:
|
class TreeContextMixin:
|
||||||
|
tree_node: Any
|
||||||
|
is_module: Any
|
||||||
|
get_value: Any
|
||||||
|
inference_state: Any
|
||||||
|
is_class: Any
|
||||||
|
parent_context: Any
|
||||||
|
|
||||||
def infer_node(self, node):
|
def infer_node(self, node):
|
||||||
from jedi.inference.syntax_tree import infer_node
|
from jedi.inference.syntax_tree import infer_node
|
||||||
return infer_node(self, node)
|
return infer_node(self, node)
|
||||||
@@ -300,7 +309,6 @@ class TreeContextMixin:
|
|||||||
class FunctionContext(TreeContextMixin, ValueContext):
|
class FunctionContext(TreeContextMixin, ValueContext):
|
||||||
def get_filters(self, until_position=None, origin_scope=None):
|
def get_filters(self, until_position=None, origin_scope=None):
|
||||||
yield ParserTreeFilter(
|
yield ParserTreeFilter(
|
||||||
self.inference_state,
|
|
||||||
parent_context=self,
|
parent_context=self,
|
||||||
until_position=until_position,
|
until_position=until_position,
|
||||||
origin_scope=origin_scope
|
origin_scope=origin_scope
|
||||||
|
|||||||
@@ -16,6 +16,6 @@ class DocstringModuleContext(ModuleContext):
|
|||||||
super().__init__(module_value)
|
super().__init__(module_value)
|
||||||
self._in_module_context = in_module_context
|
self._in_module_context = in_module_context
|
||||||
|
|
||||||
def get_filters(self, origin_scope=None, until_position=None):
|
def get_filters(self, until_position=None, origin_scope=None):
|
||||||
yield from super().get_filters(until_position=until_position)
|
yield from super().get_filters(until_position=until_position)
|
||||||
yield from self._in_module_context.get_filters()
|
yield from self._in_module_context.get_filters()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ Filters are objects that you can use to filter names in different scopes. They
|
|||||||
are needed for name resolution.
|
are needed for name resolution.
|
||||||
"""
|
"""
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
from typing import List, MutableMapping, Type
|
from typing import MutableMapping, Type, Any
|
||||||
import weakref
|
import weakref
|
||||||
|
|
||||||
from parso.python.tree import Name, UsedNamesMapping
|
from parso.python.tree import Name, UsedNamesMapping
|
||||||
@@ -16,8 +16,8 @@ from jedi.inference.utils import to_list
|
|||||||
from jedi.inference.names import TreeNameDefinition, ParamName, \
|
from jedi.inference.names import TreeNameDefinition, ParamName, \
|
||||||
AnonymousParamName, AbstractNameDefinition, NameWrapper
|
AnonymousParamName, AbstractNameDefinition, NameWrapper
|
||||||
|
|
||||||
_definition_name_cache: MutableMapping[UsedNamesMapping, List[Name]]
|
_definition_name_cache: MutableMapping[UsedNamesMapping, dict[str, tuple[Name, ...]]] \
|
||||||
_definition_name_cache = weakref.WeakKeyDictionary()
|
= weakref.WeakKeyDictionary()
|
||||||
|
|
||||||
|
|
||||||
class AbstractFilter:
|
class AbstractFilter:
|
||||||
@@ -346,6 +346,9 @@ class _OverwriteMeta(type):
|
|||||||
|
|
||||||
|
|
||||||
class _AttributeOverwriteMixin:
|
class _AttributeOverwriteMixin:
|
||||||
|
overwritten_methods: Any
|
||||||
|
_wrapped_value: Any
|
||||||
|
|
||||||
def get_filters(self, *args, **kwargs):
|
def get_filters(self, *args, **kwargs):
|
||||||
yield SpecialMethodFilter(self, self.overwritten_methods, self._wrapped_value)
|
yield SpecialMethodFilter(self, self.overwritten_methods, self._wrapped_value)
|
||||||
yield from self._wrapped_value.get_filters(*args, **kwargs)
|
yield from self._wrapped_value.get_filters(*args, **kwargs)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
This module is about generics, like the `int` in `List[int]`. It's not about
|
This module is about generics, like the `int` in `List[int]`. It's not about
|
||||||
the Generic class.
|
the Generic class.
|
||||||
"""
|
"""
|
||||||
|
from abc import abstractmethod
|
||||||
|
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi.cache import memoize_method
|
from jedi.cache import memoize_method
|
||||||
@@ -24,6 +25,14 @@ def _resolve_forward_references(context, value_set):
|
|||||||
|
|
||||||
|
|
||||||
class _AbstractGenericManager:
|
class _AbstractGenericManager:
|
||||||
|
@abstractmethod
|
||||||
|
def __getitem__(self, index):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def to_tuple(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
def get_index_and_execute(self, index):
|
def get_index_and_execute(self, index):
|
||||||
try:
|
try:
|
||||||
return self[index].execute_annotation()
|
return self[index].execute_annotation()
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ values.
|
|||||||
This file deals with all the typing.py cases.
|
This file deals with all the typing.py cases.
|
||||||
"""
|
"""
|
||||||
import itertools
|
import itertools
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi.inference.compiled import builtin_from_name, create_simple_object
|
from jedi.inference.compiled import builtin_from_name, create_simple_object
|
||||||
@@ -186,6 +187,8 @@ class ProxyTypingValue(BaseTypingValue):
|
|||||||
|
|
||||||
|
|
||||||
class _TypingClassMixin(ClassMixin):
|
class _TypingClassMixin(ClassMixin):
|
||||||
|
_tree_name: Any
|
||||||
|
|
||||||
def py__bases__(self):
|
def py__bases__(self):
|
||||||
return [LazyKnownValues(
|
return [LazyKnownValues(
|
||||||
self.inference_state.builtins_module.py__getattribute__('object')
|
self.inference_state.builtins_module.py__getattribute__('object')
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import os
|
|||||||
from itertools import chain
|
from itertools import chain
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
|
||||||
from parso.python import tree
|
from parso import tree
|
||||||
|
|
||||||
|
|
||||||
def is_stdlib_path(path):
|
def is_stdlib_path(path):
|
||||||
|
|||||||
@@ -474,7 +474,7 @@ def _load_python_module(inference_state, file_io,
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _load_builtin_module(inference_state, import_names=None, sys_path=None):
|
def _load_builtin_module(inference_state, import_names, sys_path):
|
||||||
project = inference_state.project
|
project = inference_state.project
|
||||||
if sys_path is None:
|
if sys_path is None:
|
||||||
sys_path = inference_state.get_sys_path()
|
sys_path = inference_state.get_sys_path()
|
||||||
|
|||||||
+18
-7
@@ -1,9 +1,8 @@
|
|||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
from inspect import Parameter
|
from inspect import Parameter
|
||||||
from typing import Optional, Tuple
|
from typing import Optional, Tuple, Any
|
||||||
|
|
||||||
from jedi.parser_utils import find_statement_documentation, clean_scope_docstring
|
from jedi.parser_utils import find_statement_documentation, clean_scope_docstring
|
||||||
from jedi.inference.utils import unite
|
|
||||||
from jedi.inference.base_value import ValueSet, NO_VALUES
|
from jedi.inference.base_value import ValueSet, NO_VALUES
|
||||||
from jedi.inference.cache import inference_state_method_cache
|
from jedi.inference.cache import inference_state_method_cache
|
||||||
from jedi.inference import docstrings
|
from jedi.inference import docstrings
|
||||||
@@ -37,7 +36,6 @@ class AbstractNameDefinition:
|
|||||||
def infer(self):
|
def infer(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def goto(self):
|
def goto(self):
|
||||||
# Typically names are already definitions and therefore a goto on that
|
# Typically names are already definitions and therefore a goto on that
|
||||||
# name will always result on itself.
|
# name will always result on itself.
|
||||||
@@ -105,6 +103,9 @@ class AbstractArbitraryName(AbstractNameDefinition):
|
|||||||
|
|
||||||
|
|
||||||
class AbstractTreeName(AbstractNameDefinition):
|
class AbstractTreeName(AbstractNameDefinition):
|
||||||
|
tree_name: Any
|
||||||
|
parent_context: Any
|
||||||
|
|
||||||
def __init__(self, parent_context, tree_name):
|
def __init__(self, parent_context, tree_name):
|
||||||
self.parent_context = parent_context
|
self.parent_context = parent_context
|
||||||
self.tree_name = tree_name
|
self.tree_name = tree_name
|
||||||
@@ -194,10 +195,11 @@ class AbstractTreeName(AbstractNameDefinition):
|
|||||||
new_dotted = deep_ast_copy(par)
|
new_dotted = deep_ast_copy(par)
|
||||||
new_dotted.children[index - 1:] = []
|
new_dotted.children[index - 1:] = []
|
||||||
values = context.infer_node(new_dotted)
|
values = context.infer_node(new_dotted)
|
||||||
return unite(
|
return [
|
||||||
value.goto(name, name_context=context)
|
n
|
||||||
|
for n in value.goto(name, name_context=context)
|
||||||
for value in values
|
for value in values
|
||||||
)
|
]
|
||||||
|
|
||||||
if node_type == 'trailer' and par.children[0] == '.':
|
if node_type == 'trailer' and par.children[0] == '.':
|
||||||
values = infer_call_of_leaf(context, name, cut_own_trailer=True)
|
values = infer_call_of_leaf(context, name, cut_own_trailer=True)
|
||||||
@@ -222,6 +224,9 @@ class AbstractTreeName(AbstractNameDefinition):
|
|||||||
|
|
||||||
|
|
||||||
class ValueNameMixin:
|
class ValueNameMixin:
|
||||||
|
_value: Any
|
||||||
|
parent_context: Any
|
||||||
|
|
||||||
def infer(self):
|
def infer(self):
|
||||||
return ValueSet([self._value])
|
return ValueSet([self._value])
|
||||||
|
|
||||||
@@ -357,6 +362,8 @@ class TreeNameDefinition(AbstractTreeName):
|
|||||||
|
|
||||||
|
|
||||||
class _ParamMixin:
|
class _ParamMixin:
|
||||||
|
get_kind: Any
|
||||||
|
|
||||||
def maybe_positional_argument(self, include_star=True):
|
def maybe_positional_argument(self, include_star=True):
|
||||||
options = [Parameter.POSITIONAL_ONLY, Parameter.POSITIONAL_OR_KEYWORD]
|
options = [Parameter.POSITIONAL_ONLY, Parameter.POSITIONAL_OR_KEYWORD]
|
||||||
if include_star:
|
if include_star:
|
||||||
@@ -629,6 +636,10 @@ class NameWrapper:
|
|||||||
|
|
||||||
|
|
||||||
class StubNameMixin:
|
class StubNameMixin:
|
||||||
|
api_type: str
|
||||||
|
tree_name: Any
|
||||||
|
infer: Any
|
||||||
|
|
||||||
def py__doc__(self):
|
def py__doc__(self):
|
||||||
from jedi.inference.gradual.conversion import convert_names
|
from jedi.inference.gradual.conversion import convert_names
|
||||||
# Stubs are not complicated and we can just follow simple statements
|
# Stubs are not complicated and we can just follow simple statements
|
||||||
@@ -640,7 +651,7 @@ class StubNameMixin:
|
|||||||
|
|
||||||
names = convert_names(names, prefer_stub_to_compiled=False)
|
names = convert_names(names, prefer_stub_to_compiled=False)
|
||||||
if self in names:
|
if self in names:
|
||||||
return super().py__doc__()
|
return super().py__doc__() # type: ignore
|
||||||
else:
|
else:
|
||||||
# We have signatures ourselves in stubs, so don't use signatures
|
# We have signatures ourselves in stubs, so don't use signatures
|
||||||
# from the implementation.
|
# from the implementation.
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from inspect import Parameter
|
from inspect import Parameter
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from jedi.cache import memoize_method
|
from jedi.cache import memoize_method
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
@@ -6,6 +7,10 @@ from jedi import parser_utils
|
|||||||
|
|
||||||
|
|
||||||
class _SignatureMixin:
|
class _SignatureMixin:
|
||||||
|
get_param_names: Any
|
||||||
|
name: Any
|
||||||
|
annotation_string: Any
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
def param_strings():
|
def param_strings():
|
||||||
is_positional = False
|
is_positional = False
|
||||||
@@ -36,6 +41,8 @@ class _SignatureMixin:
|
|||||||
|
|
||||||
|
|
||||||
class AbstractSignature(_SignatureMixin):
|
class AbstractSignature(_SignatureMixin):
|
||||||
|
_function_value: Any
|
||||||
|
|
||||||
def __init__(self, value, is_bound=False):
|
def __init__(self, value, is_bound=False):
|
||||||
self.value = value
|
self.value = value
|
||||||
self.is_bound = is_bound
|
self.is_bound = is_bound
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ def infer_node(context, element):
|
|||||||
if isinstance(context, CompForContext):
|
if isinstance(context, CompForContext):
|
||||||
return _infer_node(context, element)
|
return _infer_node(context, element)
|
||||||
|
|
||||||
|
name_dicts = [{}]
|
||||||
if_stmt = element
|
if_stmt = element
|
||||||
while if_stmt is not None:
|
while if_stmt is not None:
|
||||||
if_stmt = if_stmt.parent
|
if_stmt = if_stmt.parent
|
||||||
@@ -104,7 +105,6 @@ def infer_node(context, element):
|
|||||||
if predefined_if_name_dict is None and if_stmt \
|
if predefined_if_name_dict is None and if_stmt \
|
||||||
and if_stmt.type == 'if_stmt' and context.inference_state.is_analysis:
|
and if_stmt.type == 'if_stmt' and context.inference_state.is_analysis:
|
||||||
if_stmt_test = if_stmt.children[1]
|
if_stmt_test = if_stmt.children[1]
|
||||||
name_dicts = [{}]
|
|
||||||
# If we already did a check, we don't want to do it again -> If
|
# If we already did a check, we don't want to do it again -> If
|
||||||
# value.predefined_names is filled, we stop.
|
# value.predefined_names is filled, we stop.
|
||||||
# We don't want to check the if stmt itself, it's just about
|
# We don't want to check the if stmt itself, it's just about
|
||||||
@@ -435,7 +435,7 @@ def _infer_expr_stmt(context, stmt, seek_name=None):
|
|||||||
value_set = ValueSet(to_mod(v) for v in left_values)
|
value_set = ValueSet(to_mod(v) for v in left_values)
|
||||||
else:
|
else:
|
||||||
operator = copy.copy(first_operator)
|
operator = copy.copy(first_operator)
|
||||||
operator.value = operator.value[:-1]
|
operator.value = operator.value[:-1] # type: ignore[attor-defined]
|
||||||
for_stmt = stmt.search_ancestor('for_stmt')
|
for_stmt = stmt.search_ancestor('for_stmt')
|
||||||
if for_stmt is not None and for_stmt.type == 'for_stmt' and value_set \
|
if for_stmt is not None and for_stmt.type == 'for_stmt' and value_set \
|
||||||
and parser_utils.for_stmt_defines_one_name(for_stmt):
|
and parser_utils.for_stmt_defines_one_name(for_stmt):
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ class PushBackIterator:
|
|||||||
def __init__(self, iterator):
|
def __init__(self, iterator):
|
||||||
self.pushes = []
|
self.pushes = []
|
||||||
self.iterator = iterator
|
self.iterator = iterator
|
||||||
self.current = None
|
|
||||||
|
|
||||||
def push_back(self, value):
|
def push_back(self, value):
|
||||||
self.pushes.append(value)
|
self.pushes.append(value)
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
from typing import Any
|
||||||
|
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi.inference.cache import inference_state_method_cache, CachedMetaClass
|
from jedi.inference.cache import inference_state_method_cache, CachedMetaClass
|
||||||
from jedi.inference import compiled
|
from jedi.inference import compiled
|
||||||
@@ -53,6 +55,10 @@ class FunctionAndClassBase(TreeValue):
|
|||||||
|
|
||||||
class FunctionMixin:
|
class FunctionMixin:
|
||||||
api_type = 'function'
|
api_type = 'function'
|
||||||
|
tree_node: Any
|
||||||
|
py__class__: Any
|
||||||
|
as_context: Any
|
||||||
|
get_signature_functions: Any
|
||||||
|
|
||||||
def get_filters(self, origin_scope=None):
|
def get_filters(self, origin_scope=None):
|
||||||
cls = self.py__class__()
|
cls = self.py__class__()
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from abc import abstractproperty
|
from abc import abstractproperty
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi import settings
|
from jedi import settings
|
||||||
@@ -187,6 +188,8 @@ class CompiledInstance(AbstractInstanceValue):
|
|||||||
|
|
||||||
|
|
||||||
class _BaseTreeInstance(AbstractInstanceValue):
|
class _BaseTreeInstance(AbstractInstanceValue):
|
||||||
|
get_defined_names: Any
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def array_type(self):
|
def array_type(self):
|
||||||
name = self.class_value.py__name__()
|
name = self.class_value.py__name__()
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
Contains all classes and functions to deal with lists, dicts, generators and
|
Contains all classes and functions to deal with lists, dicts, generators and
|
||||||
iterators in general.
|
iterators in general.
|
||||||
"""
|
"""
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from jedi.inference import compiled
|
from jedi.inference import compiled
|
||||||
from jedi.inference import analysis
|
from jedi.inference import analysis
|
||||||
from jedi.inference.lazy_value import LazyKnownValue, LazyKnownValues, \
|
from jedi.inference.lazy_value import LazyKnownValue, LazyKnownValues, \
|
||||||
@@ -20,6 +22,9 @@ from jedi.inference.value.dynamic_arrays import check_array_additions
|
|||||||
|
|
||||||
|
|
||||||
class IterableMixin:
|
class IterableMixin:
|
||||||
|
py__iter__: Any
|
||||||
|
inference_state: Any
|
||||||
|
|
||||||
def py__next__(self, contextualized_node=None):
|
def py__next__(self, contextualized_node=None):
|
||||||
return self.py__iter__(contextualized_node)
|
return self.py__iter__(contextualized_node)
|
||||||
|
|
||||||
@@ -128,6 +133,12 @@ def comprehension_from_atom(inference_state, value, atom):
|
|||||||
|
|
||||||
|
|
||||||
class ComprehensionMixin:
|
class ComprehensionMixin:
|
||||||
|
_defining_context: Any
|
||||||
|
_entry_node: Any
|
||||||
|
array_type: Any
|
||||||
|
_value_node: Any
|
||||||
|
_sync_comp_for_node: Any
|
||||||
|
|
||||||
@inference_state_method_cache()
|
@inference_state_method_cache()
|
||||||
def _get_comp_for_context(self, parent_context, comp_for):
|
def _get_comp_for_context(self, parent_context, comp_for):
|
||||||
return CompForContext(parent_context, comp_for)
|
return CompForContext(parent_context, comp_for)
|
||||||
@@ -176,6 +187,8 @@ class ComprehensionMixin:
|
|||||||
|
|
||||||
|
|
||||||
class _DictMixin:
|
class _DictMixin:
|
||||||
|
get_mapping_item_values: Any
|
||||||
|
|
||||||
def _get_generics(self):
|
def _get_generics(self):
|
||||||
return tuple(c_set.py__class__() for c_set in self.get_mapping_item_values())
|
return tuple(c_set.py__class__() for c_set in self.get_mapping_item_values())
|
||||||
|
|
||||||
@@ -248,6 +261,9 @@ class GeneratorComprehension(_BaseComprehension, GeneratorBase):
|
|||||||
|
|
||||||
|
|
||||||
class _DictKeyMixin:
|
class _DictKeyMixin:
|
||||||
|
_dict_keys: Any
|
||||||
|
_dict_values: Any
|
||||||
|
|
||||||
# TODO merge with _DictMixin?
|
# TODO merge with _DictMixin?
|
||||||
def get_mapping_item_values(self):
|
def get_mapping_item_values(self):
|
||||||
return self._dict_keys(), self._dict_values()
|
return self._dict_keys(), self._dict_values()
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ py__doc__() Returns the docstring for a value.
|
|||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import List, Optional, Tuple
|
from typing import List, Optional, Tuple, TYPE_CHECKING, Any
|
||||||
|
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi.parser_utils import get_cached_parent_scope, expr_is_dotted, \
|
from jedi.parser_utils import get_cached_parent_scope, expr_is_dotted, \
|
||||||
@@ -61,6 +61,9 @@ from inspect import Parameter
|
|||||||
from jedi.inference.names import BaseTreeParamName
|
from jedi.inference.names import BaseTreeParamName
|
||||||
from jedi.inference.signature import AbstractSignature
|
from jedi.inference.signature import AbstractSignature
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from jedi.inference import InferenceState
|
||||||
|
|
||||||
|
|
||||||
class ClassName(TreeNameDefinition):
|
class ClassName(TreeNameDefinition):
|
||||||
def __init__(self, class_value, tree_name, name_context, apply_decorators):
|
def __init__(self, class_value, tree_name, name_context, apply_decorators):
|
||||||
@@ -197,6 +200,15 @@ def get_dataclass_param_names(cls) -> List[DataclassParamName]:
|
|||||||
|
|
||||||
|
|
||||||
class ClassMixin:
|
class ClassMixin:
|
||||||
|
tree_node: Any
|
||||||
|
parent_context: Any
|
||||||
|
inference_state: InferenceState
|
||||||
|
py__bases__: Any
|
||||||
|
get_metaclasses: Any
|
||||||
|
get_metaclass_filters: Any
|
||||||
|
get_metaclass_signatures: Any
|
||||||
|
list_type_vars: Any
|
||||||
|
|
||||||
def is_class(self):
|
def is_class(self):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional
|
from typing import Optional, TYPE_CHECKING, Any
|
||||||
|
|
||||||
from jedi.inference.cache import inference_state_method_cache
|
from jedi.inference.cache import inference_state_method_cache
|
||||||
from jedi.inference.names import AbstractNameDefinition, ModuleName
|
from jedi.inference.names import AbstractNameDefinition, ModuleName
|
||||||
@@ -13,6 +13,9 @@ from jedi.inference.compiled import create_simple_object
|
|||||||
from jedi.inference.base_value import ValueSet
|
from jedi.inference.base_value import ValueSet
|
||||||
from jedi.inference.context import ModuleContext
|
from jedi.inference.context import ModuleContext
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from jedi.inference import InferenceState
|
||||||
|
|
||||||
|
|
||||||
class _ModuleAttributeName(AbstractNameDefinition):
|
class _ModuleAttributeName(AbstractNameDefinition):
|
||||||
"""
|
"""
|
||||||
@@ -35,6 +38,11 @@ class _ModuleAttributeName(AbstractNameDefinition):
|
|||||||
|
|
||||||
|
|
||||||
class SubModuleDictMixin:
|
class SubModuleDictMixin:
|
||||||
|
inference_state: "InferenceState"
|
||||||
|
is_package: Any
|
||||||
|
py__path__: Any
|
||||||
|
as_context: Any
|
||||||
|
|
||||||
@inference_state_method_cache()
|
@inference_state_method_cache()
|
||||||
def sub_modules_dict(self):
|
def sub_modules_dict(self):
|
||||||
"""
|
"""
|
||||||
@@ -57,6 +65,10 @@ class SubModuleDictMixin:
|
|||||||
|
|
||||||
class ModuleMixin(SubModuleDictMixin):
|
class ModuleMixin(SubModuleDictMixin):
|
||||||
_module_name_class = ModuleName
|
_module_name_class = ModuleName
|
||||||
|
tree_node: Any
|
||||||
|
string_names: Any
|
||||||
|
sub_modules_dict: Any
|
||||||
|
py__file__: Any
|
||||||
|
|
||||||
def get_filters(self, origin_scope=None):
|
def get_filters(self, origin_scope=None):
|
||||||
yield MergedFilter(
|
yield MergedFilter(
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ def get_parent_scope(node, include_flows=False):
|
|||||||
# the if, but the parent of the if.
|
# the if, but the parent of the if.
|
||||||
if not (scope.type == 'if_stmt'
|
if not (scope.type == 'if_stmt'
|
||||||
and any(n.start_pos <= node.start_pos < n.end_pos
|
and any(n.start_pos <= node.start_pos < n.end_pos
|
||||||
for n in scope.get_test_nodes())):
|
for n in scope.get_test_nodes())): # type: ignore[attr-defined]
|
||||||
return scope
|
return scope
|
||||||
|
|
||||||
scope = scope.parent
|
scope = scope.parent
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ def _iter_pytest_modules(module_context, skip_own_module=False):
|
|||||||
folder = folder.get_parent_folder()
|
folder = folder.get_parent_folder()
|
||||||
|
|
||||||
# prevent an infinite for loop if the same parent folder is return twice
|
# prevent an infinite for loop if the same parent folder is return twice
|
||||||
if last_folder is not None and folder.path == last_folder.path:
|
if last_folder is not None and folder.path == last_folder.path: # type: ignore # TODO
|
||||||
break
|
break
|
||||||
last_folder = folder # keep track of the last found parent name
|
last_folder = folder # keep track of the last found parent name
|
||||||
|
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ def execute(callback):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
return func(value, arguments=arguments, callback=call)
|
return func(value, arguments=arguments, callback=call) # type: ignore
|
||||||
return call()
|
return call()
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|||||||
+1
-15
@@ -1,4 +1,4 @@
|
|||||||
[tool.mypy]
|
[tool.zuban]
|
||||||
# Exclude our copies of external stubs
|
# Exclude our copies of external stubs
|
||||||
exclude = "^jedi/third_party"
|
exclude = "^jedi/third_party"
|
||||||
|
|
||||||
@@ -8,25 +8,11 @@ enable_error_code = "ignore-without-code"
|
|||||||
# Ensure generics are explicit about what they are (e.g: `List[str]` rather than
|
# Ensure generics are explicit about what they are (e.g: `List[str]` rather than
|
||||||
# just `List`)
|
# just `List`)
|
||||||
disallow_any_generics = true
|
disallow_any_generics = true
|
||||||
|
|
||||||
disallow_subclassing_any = true
|
disallow_subclassing_any = true
|
||||||
|
|
||||||
# Avoid creating future gotchas emerging from bad typing
|
# Avoid creating future gotchas emerging from bad typing
|
||||||
warn_redundant_casts = true
|
warn_redundant_casts = true
|
||||||
warn_unused_ignores = true
|
|
||||||
warn_return_any = true
|
warn_return_any = true
|
||||||
warn_unused_configs = true
|
warn_unused_configs = true
|
||||||
|
|
||||||
warn_unreachable = true
|
|
||||||
|
|
||||||
# Require values to be explicitly re-exported; this makes things easier for
|
|
||||||
# Flake8 too and avoids accidentally importing thing from the "wrong" place
|
|
||||||
# (which helps avoid circular imports)
|
|
||||||
implicit_reexport = false
|
|
||||||
|
|
||||||
strict_equality = true
|
strict_equality = true
|
||||||
|
|
||||||
[[tool.mypy.overrides]]
|
|
||||||
# Various __init__.py files which contain re-exports we want to implicitly make.
|
|
||||||
module = ["jedi", "jedi.inference.compiled", "jedi.inference.value", "parso"]
|
|
||||||
implicit_reexport = true
|
|
||||||
|
|||||||
Reference in New Issue
Block a user