From e7fdbcc834e57e75733d7e3776467511794b5c79 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Wed, 4 Feb 2026 01:55:53 +0100 Subject: [PATCH] Fix a few more typing issues --- jedi/api/completion.py | 3 ++- jedi/api/environment.py | 2 +- jedi/cache.py | 2 +- jedi/debug.py | 2 +- jedi/inference/__init__.py | 1 + jedi/inference/arguments.py | 2 +- jedi/inference/base_value.py | 15 ++++++++++----- jedi/inference/compiled/getattr_static.py | 4 ++-- jedi/inference/compiled/subprocess/functions.py | 5 ++++- jedi/inference/dynamic_params.py | 4 ++-- jedi/inference/gradual/base.py | 4 ++-- jedi/inference/names.py | 6 +++--- jedi/inference/syntax_tree.py | 2 +- jedi/inference/value/instance.py | 1 + jedi/inference/value/iterable.py | 2 +- jedi/inference/value/klass.py | 3 +++ jedi/plugins/django.py | 3 ++- 17 files changed, 38 insertions(+), 23 deletions(-) diff --git a/jedi/api/completion.py b/jedi/api/completion.py index a9932150..376814a1 100644 --- a/jedi/api/completion.py +++ b/jedi/api/completion.py @@ -1,5 +1,6 @@ import re from textwrap import dedent +from typing import Any from inspect import Parameter from parso.python.token import PythonTokenTypes @@ -265,7 +266,7 @@ class Completion: elif type_ == 'for_stmt': allowed_transitions.append('else') - completion_names = [] + completion_names: list[Any] = [] kwargs_only = False if any(t in allowed_transitions for t in (PythonTokenTypes.NAME, diff --git a/jedi/api/environment.py b/jedi/api/environment.py index 0bf9169e..f9f78b08 100644 --- a/jedi/api/environment.py +++ b/jedi/api/environment.py @@ -254,7 +254,7 @@ def get_cached_default_environment(): # /path/to/env so we need to fully resolve the paths in order to # compare them. if var and os.path.realpath(var) != os.path.realpath(environment.path): - _get_cached_default_environment.clear_cache() + _get_cached_default_environment.clear_cache() # type: ignore[attr-defined] return _get_cached_default_environment() return environment diff --git a/jedi/cache.py b/jedi/cache.py index 2bb15105..e6e371de 100644 --- a/jedi/cache.py +++ b/jedi/cache.py @@ -93,7 +93,7 @@ def time_cache(seconds): cache[key] = time.time(), result return result - wrapper.clear_cache = lambda: cache.clear() + wrapper.clear_cache = lambda: cache.clear() # type: ignore[attr-defined] return wrapper return decorator diff --git a/jedi/debug.py b/jedi/debug.py index 167be41b..8f2340af 100644 --- a/jedi/debug.py +++ b/jedi/debug.py @@ -36,7 +36,7 @@ try: # pytest resets the stream at the end - causes troubles. Since # after every output the stream is reset automatically we don't # need this. - initialise.atexit_done = True + initialise.atexit_done = True # type: ignore[attr-defined] try: init(strip=False) except Exception: diff --git a/jedi/inference/__init__.py b/jedi/inference/__init__.py index 2d0a7099..b468730e 100644 --- a/jedi/inference/__init__.py +++ b/jedi/inference/__init__.py @@ -85,6 +85,7 @@ from jedi.plugins import plugin_manager class InferenceState: analysis_modules: list[Any] + def __init__(self, project, environment=None, script_path=None): if environment is None: environment = project.get_environment() diff --git a/jedi/inference/arguments.py b/jedi/inference/arguments.py index b2c28ad3..122a8a67 100644 --- a/jedi/inference/arguments.py +++ b/jedi/inference/arguments.py @@ -135,7 +135,7 @@ class _AbstractArgumentsMixin: class AbstractArguments(_AbstractArgumentsMixin): context = None - argument_node = None + argument_node: Any = None trailer = None diff --git a/jedi/inference/base_value.py b/jedi/inference/base_value.py index 6df71e9f..25c4181d 100644 --- a/jedi/inference/base_value.py +++ b/jedi/inference/base_value.py @@ -351,11 +351,16 @@ class _ValueWrapperBase(HelperValueMixin): class LazyValueWrapper(_ValueWrapperBase): - @safe_property - @memoize_method - def _wrapped_value(self): - with debug.increase_indent_cm('Resolve lazy value wrapper'): - return self._get_wrapped_value() + if TYPE_CHECKING: + @property + def _wrapped_value(self) -> Any: + return + else: + @safe_property + @memoize_method + def _wrapped_value(self): + with debug.increase_indent_cm('Resolve lazy value wrapper'): + return self._get_wrapped_value() def __repr__(self): return '<%s>' % (self.__class__.__name__) diff --git a/jedi/inference/compiled/getattr_static.py b/jedi/inference/compiled/getattr_static.py index 03c199ef..dd02f4d6 100644 --- a/jedi/inference/compiled/getattr_static.py +++ b/jedi/inference/compiled/getattr_static.py @@ -39,7 +39,7 @@ def _is_type(obj): def _shadowed_dict(klass): - dict_attr = type.__dict__["__dict__"] + dict_attr = type.__dict__["__dict__"] # type: ignore[index] for entry in _static_getmro(klass): try: class_dict = dict_attr.__get__(entry)["__dict__"] @@ -54,7 +54,7 @@ def _shadowed_dict(klass): def _static_getmro(klass): - mro = type.__dict__['__mro__'].__get__(klass) + mro = type.__dict__['__mro__'].__get__(klass) # type: ignore[index] if not isinstance(mro, (tuple, list)): # There are unfortunately no tests for this, I was not able to # reproduce this in pure Python. However should still solve the issue diff --git a/jedi/inference/compiled/subprocess/functions.py b/jedi/inference/compiled/subprocess/functions.py index 50c47b83..497c8098 100644 --- a/jedi/inference/compiled/subprocess/functions.py +++ b/jedi/inference/compiled/subprocess/functions.py @@ -158,7 +158,10 @@ def _find_module(string, path=None, full_name=None, is_global_search=True): if loader is None and not spec.has_location: # This is a namespace package. full_name = string if not path else full_name - implicit_ns_info = ImplicitNSInfo(full_name, spec.submodule_search_locations._path) + implicit_ns_info = ImplicitNSInfo( + full_name, + spec.submodule_search_locations._path, # type: ignore[union-attr] + ) return implicit_ns_info, True break diff --git a/jedi/inference/dynamic_params.py b/jedi/inference/dynamic_params.py index e759111a..dc15296e 100644 --- a/jedi/inference/dynamic_params.py +++ b/jedi/inference/dynamic_params.py @@ -109,7 +109,7 @@ def _search_function_arguments(module_context, funcdef, string_name): if string_name == '__init__': cls = get_parent_scope(funcdef) if cls.type == 'classdef': - string_name = cls.name.value + string_name = cls.name.value # type: ignore[union-attr] compare_node = cls found_arguments = False @@ -203,7 +203,7 @@ def _check_name_for_execution(inference_state, context, compare_node, name, trai # Here we're trying to find decorators by checking the first # parameter. It's not very generic though. Should find a better # solution that also applies to nested decorators. - param_names = value.parent_context.get_param_names() + param_names = value.parent_context.get_param_names() # type: ignore[attr-defined] if len(param_names) != 1: continue values = param_names[0].infer() diff --git a/jedi/inference/gradual/base.py b/jedi/inference/gradual/base.py index ce574297..33bf6201 100644 --- a/jedi/inference/gradual/base.py +++ b/jedi/inference/gradual/base.py @@ -195,7 +195,7 @@ class GenericClass(DefineGenericBaseClass, ClassMixin): @to_list def py__bases__(self): - for base in self._wrapped_value.py__bases__(): + for base in self._wrapped_value.py__bases__(): # type: ignore[attr-defined] yield _LazyGenericBaseClass(self, base, self._generics_manager) def _create_instance_with_generics(self, generics_manager): @@ -384,7 +384,7 @@ class BaseTypingValue(LazyValueWrapper): return _PseudoTreeNameClass(self.parent_context, self._tree_name) def get_signatures(self): - return self._wrapped_value.get_signatures() + return self._wrapped_value.get_signatures() # type: ignore[attr-defined] def __repr__(self): return '%s(%s)' % (self.__class__.__name__, self._tree_name.value) diff --git a/jedi/inference/names.py b/jedi/inference/names.py index 59262428..dc6c348c 100644 --- a/jedi/inference/names.py +++ b/jedi/inference/names.py @@ -245,7 +245,7 @@ class ValueNameMixin: def get_root_context(self): if self.parent_context is None: # A module return self._value.as_context() - return super().get_root_context() + return super().get_root_context() # type: ignore def get_defining_qualified_value(self): context = self.parent_context @@ -365,13 +365,13 @@ class _ParamMixin: get_kind: Any def maybe_positional_argument(self, include_star=True): - options = [Parameter.POSITIONAL_ONLY, Parameter.POSITIONAL_OR_KEYWORD] + options: list[int] = [Parameter.POSITIONAL_ONLY, Parameter.POSITIONAL_OR_KEYWORD] if include_star: options.append(Parameter.VAR_POSITIONAL) return self.get_kind() in options def maybe_keyword_argument(self, include_stars=True): - options = [Parameter.KEYWORD_ONLY, Parameter.POSITIONAL_OR_KEYWORD] + options: list[int] = [Parameter.KEYWORD_ONLY, Parameter.POSITIONAL_OR_KEYWORD] if include_stars: options.append(Parameter.VAR_KEYWORD) return self.get_kind() in options diff --git a/jedi/inference/syntax_tree.py b/jedi/inference/syntax_tree.py index e4d1b785..9baf3bf4 100644 --- a/jedi/inference/syntax_tree.py +++ b/jedi/inference/syntax_tree.py @@ -435,7 +435,7 @@ def _infer_expr_stmt(context, stmt, seek_name=None): value_set = ValueSet(to_mod(v) for v in left_values) else: operator = copy.copy(first_operator) - operator.value = operator.value[:-1] # type: ignore[attor-defined] + operator.value = operator.value[:-1] for_stmt = stmt.search_ancestor('for_stmt') 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): diff --git a/jedi/inference/value/instance.py b/jedi/inference/value/instance.py index 70babc2b..0ea89155 100644 --- a/jedi/inference/value/instance.py +++ b/jedi/inference/value/instance.py @@ -189,6 +189,7 @@ class CompiledInstance(AbstractInstanceValue): class _BaseTreeInstance(AbstractInstanceValue): get_defined_names: Any + _arguments: Any @property def array_type(self): diff --git a/jedi/inference/value/iterable.py b/jedi/inference/value/iterable.py index a4e9f7bb..aea79863 100644 --- a/jedi/inference/value/iterable.py +++ b/jedi/inference/value/iterable.py @@ -233,7 +233,7 @@ class Sequence(LazyAttributeOverwrite, IterableMixin): class _BaseComprehension(ComprehensionMixin): def __init__(self, inference_state, defining_context, sync_comp_for_node, entry_node): assert sync_comp_for_node.type == 'sync_comp_for' - super().__init__(inference_state) + super().__init__(inference_state) # type: ignore[call-arg] self._defining_context = defining_context self._sync_comp_for_node = sync_comp_for_node self._entry_node = entry_node diff --git a/jedi/inference/value/klass.py b/jedi/inference/value/klass.py index 01844249..11c70fe2 100644 --- a/jedi/inference/value/klass.py +++ b/jedi/inference/value/klass.py @@ -694,6 +694,9 @@ class ClassValue(ClassMixin, FunctionAndClassBase, metaclass=CachedMetaClass): """ bases_arguments = self._get_bases_arguments() + if bases_arguments is None: + return None + if bases_arguments.argument_node.type != "arglist": # If it is not inheriting from the base model and having # extra parameters, then init behavior is not changed. diff --git a/jedi/plugins/django.py b/jedi/plugins/django.py index cd443bbd..c83620d7 100644 --- a/jedi/plugins/django.py +++ b/jedi/plugins/django.py @@ -2,6 +2,7 @@ Module is used to infer Django model fields. """ from inspect import Parameter +from typing import Any from jedi import debug from jedi.inference.cache import inference_state_function_cache @@ -140,7 +141,7 @@ def _new_dict_filter(cls, is_instance): include_metaclasses=False, include_type_when_class=False) ) - dct = { + dct: dict[str, Any] = { name.string_name: DjangoModelName(cls, name, is_instance) for filter_ in reversed(filters) for name in filter_.values()