Fix a lot of test related typing issues

This commit is contained in:
Dave Halter
2026-02-10 19:38:55 +01:00
parent 6903bc25d5
commit 8cbb817b12
20 changed files with 47 additions and 40 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
[tool.zuban] [tool.zuban]
# Exclude our copies of external stubs # Exclude our copies of external stubs
exclude = "^jedi/third_party" exclude = "^jedi/third_party|^test/(completion|refactor|static_analysis|examples)/"
show_error_codes = true show_error_codes = true
enable_error_code = "ignore-without-code" enable_error_code = "ignore-without-code"
+1 -1
View File
@@ -13,7 +13,7 @@ Note: This requires the psutil library, available on PyPI.
import time import time
import sys import sys
import os import os
import psutil import psutil # type: ignore[import-untyped]
sys.path.insert(0, os.path.abspath(os.path.dirname(__file__) + '/..')) sys.path.insert(0, os.path.abspath(os.path.dirname(__file__) + '/..'))
import jedi import jedi
+1 -1
View File
@@ -56,7 +56,7 @@ def main(args):
run(code, i, infer=infer) run(code, i, infer=infer)
if args['--precision']: if args['--precision']:
pstats.f8 = f8 pstats.f8 = f8 # type: ignore[attr-defined] # TODO this does not seem to exist?!
jedi.set_debug_function(notices=args['--debug']) jedi.set_debug_function(notices=args['--debug'])
if args['--omit']: if args['--omit']:
+2 -2
View File
@@ -17,11 +17,11 @@ import sys
try: try:
import urllib.request as urllib2 import urllib.request as urllib2
except ImportError: except ImportError:
import urllib2 import urllib2 # type: ignore[import-not-found, no-redef]
import gc import gc
from os.path import abspath, dirname from os.path import abspath, dirname
import objgraph import objgraph # type: ignore[import-untyped]
sys.path.insert(0, dirname(dirname(abspath(__file__)))) sys.path.insert(0, dirname(dirname(abspath(__file__))))
import jedi import jedi
+1 -1
View File
@@ -37,7 +37,7 @@ setup(name='jedi',
packages=find_packages(exclude=['test', 'test.*']), packages=find_packages(exclude=['test', 'test.*']),
python_requires='>=3.8', python_requires='>=3.8',
# Python 3.13 grammars are added to parso in 0.8.4 # Python 3.13 grammars are added to parso in 0.8.4
install_requires=['parso>=0.8.5,<0.9.0'], install_requires=['parso>=0.8.6,<0.9.0'],
extras_require={ extras_require={
'testing': [ 'testing': [
'pytest<9.0.0', 'pytest<9.0.0',
-2
View File
@@ -35,7 +35,6 @@ Usage:
Options: Options:
-h --help Show this screen. -h --help Show this screen.
--record=<file> Exceptions are recorded in here [default: record.json]. --record=<file> Exceptions are recorded in here [default: record.json].
-f, --fs-cache By default, file system cache is off for reproducibility.
-n, --maxtries=<nr> Maximum of random tries [default: 100] -n, --maxtries=<nr> Maximum of random tries [default: 100]
-d, --debug Jedi print debugging when an error is raised. -d, --debug Jedi print debugging when an error is raised.
-s Shows the path/line numbers of every completion before it starts. -s Shows the path/line numbers of every completion before it starts.
@@ -187,7 +186,6 @@ def main(arguments):
'pudb' if arguments['--pudb'] else None 'pudb' if arguments['--pudb'] else None
record = arguments['--record'] record = arguments['--record']
jedi.settings.use_filesystem_cache = arguments['--fs-cache']
if arguments['--debug']: if arguments['--debug']:
jedi.set_debug_function() jedi.set_debug_function()
+1 -1
View File
@@ -14,7 +14,7 @@ from jedi.api.interpreter import MixedModuleContext
# For interpreter tests sometimes the path of this directory is in the sys # For interpreter tests sometimes the path of this directory is in the sys
# path, which we definitely don't want. So just remove it globally. # path, which we definitely don't want. So just remove it globally.
try: try:
sys.path.remove(helpers.test_dir) sys.path.remove(str(helpers.test_dir))
except ValueError: except ValueError:
pass pass
+2
View File
@@ -168,6 +168,8 @@ class BaseTestCase(object):
class IntegrationTestCase(BaseTestCase): class IntegrationTestCase(BaseTestCase):
source: str # Defined as a side effect
def __init__(self, test_type, correct, line_nr, column, start, line, def __init__(self, test_type, correct, line_nr, column, start, line,
path=None, skip_version_info=None): path=None, skip_version_info=None):
super().__init__(skip_version_info) super().__init__(skip_version_info)
+2 -1
View File
@@ -3,6 +3,7 @@ import os
from textwrap import dedent from textwrap import dedent
from itertools import count from itertools import count
from pathlib import Path from pathlib import Path
from typing import Any
import pytest import pytest
@@ -301,7 +302,7 @@ def test_file_path_should_have_completions(Script):
assert Script('r"').complete() # See GH #1503 assert Script('r"').complete() # See GH #1503
_dict_keys_completion_tests = [ _dict_keys_completion_tests: "list[tuple[str, int | None, list[str | Any]]]" = [
('ints[', 5, ['1', '50', Ellipsis]), ('ints[', 5, ['1', '50', Ellipsis]),
('ints[]', 5, ['1', '50', Ellipsis]), ('ints[]', 5, ['1', '50', Ellipsis]),
('ints[1]', 5, ['1', '50', Ellipsis]), ('ints[1]', 5, ['1', '50', Ellipsis]),
+1 -1
View File
@@ -32,7 +32,7 @@ def test_versions(version):
try: try:
env = get_system_environment(version) env = get_system_environment(version)
except InvalidPythonEnvironment: except InvalidPythonEnvironment:
if int(version.replace('.', '')) == str(sys.version_info[0]) + str(sys.version_info[1]): if version.replace('.', '') == str(sys.version_info[0]) + str(sys.version_info[1]):
# At least the current version has to work # At least the current version has to work
raise raise
pytest.skip() pytest.skip()
+3
View File
@@ -15,6 +15,7 @@ There are three kinds of test:
import textwrap import textwrap
from unittest import TestCase from unittest import TestCase
from typing import Any
import pytest import pytest
@@ -22,6 +23,8 @@ import jedi
class MixinTestFullName(object): class MixinTestFullName(object):
assertEqual: Any
operation = None operation = None
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
+11 -11
View File
@@ -78,7 +78,7 @@ def test_numpy_like_non_zero():
def test_nested_resolve(): def test_nested_resolve():
class XX: class XX:
def x(): def x(): # type: ignore[misc]
pass pass
cls = get_completion('XX', locals()) cls = get_completion('XX', locals())
@@ -92,7 +92,7 @@ def test_side_effect_completion():
Python code, however we want references to Python code as well. Therefore Python code, however we want references to Python code as well. Therefore
we need some mixed kind of magic for tests. we need some mixed kind of magic for tests.
""" """
_GlobalNameSpace.SideEffectContainer.foo = 1 _GlobalNameSpace.SideEffectContainer.foo = 1 # type: ignore[attr-defined]
side_effect = get_completion('SideEffectContainer', _GlobalNameSpace.__dict__) side_effect = get_completion('SideEffectContainer', _GlobalNameSpace.__dict__)
# It's a class that contains MixedObject. # It's a class that contains MixedObject.
@@ -166,7 +166,7 @@ def test_getitem_side_effects():
# Possible side effects here, should therefore not call this. # Possible side effects here, should therefore not call this.
if True: if True:
raise NotImplementedError() raise NotImplementedError()
return index return index # type: ignore[unreachable]
foo = Foo2() foo = Foo2()
_assert_interpreter_complete('foo["asdf"].upper', locals(), ['upper']) _assert_interpreter_complete('foo["asdf"].upper', locals(), ['upper'])
@@ -198,7 +198,7 @@ def test__getattr__completions(allow_unsafe_getattr, class_is_findable):
raise AttributeError(name) raise AttributeError(name)
def __dir__(self): def __dir__(self):
return ['foo', 'fbar'] + object.__dir__(self) return ['foo', 'fbar'] + object.__dir__(self) # type: ignore[operator]
if not class_is_findable: if not class_is_findable:
CompleteGetattr.__name__ = "something_somewhere" CompleteGetattr.__name__ = "something_somewhere"
@@ -388,7 +388,7 @@ def test_dir_magic_method(allow_unsafe_getattr):
raise AttributeError(name) raise AttributeError(name)
def __dir__(self): def __dir__(self):
return ['foo', 'bar'] + object.__dir__(self) return ['foo', 'bar'] + object.__dir__(self) # type: ignore[operator]
itp = jedi.Interpreter("ca.", [{'ca': CompleteAttrs()}]) itp = jedi.Interpreter("ca.", [{'ca': CompleteAttrs()}])
completions = itp.complete() completions = itp.complete()
@@ -410,7 +410,7 @@ def test_dir_magic_method(allow_unsafe_getattr):
def test_name_not_findable(): def test_name_not_findable():
class X(): class X():
if 0: if 0:
NOT_FINDABLE # noqa: F821 NOT_FINDABLE # type: ignore[unreachable] # noqa: F821
def hidden(self): def hidden(self):
return return
@@ -493,7 +493,7 @@ def test__wrapped__():
def test_illegal_class_instance(): def test_illegal_class_instance():
class X: class X:
__class__ = 1 __class__ = 1 # type: ignore[assignment]
X.__name__ = 'asdf' X.__name__ = 'asdf'
d, = jedi.Interpreter('foo', [{'foo': X()}]).infer() d, = jedi.Interpreter('foo', [{'foo': X()}]).infer()
v, = d._name.infer() v, = d._name.infer()
@@ -537,7 +537,7 @@ def test_partial_signatures(code, expected, index):
def test_type_var(): def test_type_var():
"""This was an issue before, see Github #1369""" """This was an issue before, see Github #1369"""
x = typing.TypeVar('myvar') x = typing.TypeVar('myvar') # type: ignore[misc]
def_, = jedi.Interpreter('x', [locals()]).infer() def_, = jedi.Interpreter('x', [locals()]).infer()
assert def_.name == 'TypeVar' assert def_.name == 'TypeVar'
@@ -576,7 +576,7 @@ def test_dict_completion(code, column, expected):
strs = {'asdf': 1, """foo""": 2, r'fbar': 3} strs = {'asdf': 1, """foo""": 2, r'fbar': 3}
mixed = {1: 2, 1.10: 4, None: 6, r'a\sdf': 8, b'foo': 9} mixed = {1: 2, 1.10: 4, None: 6, r'a\sdf': 8, b'foo': 9}
class Inherited(dict): class Inherited(dict): # type: ignore[type-arg]
pass pass
inherited = Inherited(blablu=3) inherited = Inherited(blablu=3)
@@ -624,10 +624,10 @@ def test_dunders(class_is_findable, code, expected, allow_unsafe_getattr):
def __getitem__(self, key) -> int: def __getitem__(self, key) -> int:
return 1 return 1
def __iter__(self, key) -> Iterator[str]: def __iter__(self, key) -> Iterator[str]: # type: ignore[empty-body]
pass pass
def __next__(self, key) -> float: def __next__(self, key) -> float: # type: ignore[empty-body]
pass pass
if not class_is_findable: if not class_is_findable:
+1 -1
View File
@@ -54,7 +54,7 @@ def test_rename_mod(Script, dir_with_content):
''').format(dir=dir_with_content) ''').format(dir=dir_with_content)
@pytest.mark.skipif('sys.version_info[:2] < (3, 8)', message="Python 3.8 introduces dirs_exist_ok") @pytest.mark.skipif('sys.version_info[:2] < (3, 8)', reason="Python 3.8 introduces dirs_exist_ok")
def test_namespace_package(Script, tmpdir): def test_namespace_package(Script, tmpdir):
origin = get_example_dir('implicit_namespace_package') origin = get_example_dir('implicit_namespace_package')
shutil.copytree(origin, tmpdir.strpath, dirs_exist_ok=True) shutil.copytree(origin, tmpdir.strpath, dirs_exist_ok=True)
+1 -1
View File
@@ -13,7 +13,7 @@ class SomeClass:
def twice(self, b): def twice(self, b):
pass pass
def some_function(): def some_function(self):
pass pass
+2 -2
View File
@@ -11,14 +11,14 @@ import jedi
from ..helpers import test_dir from ..helpers import test_dir
try: try:
import numpydoc # NOQA import numpydoc # type: ignore[import-not-found] # NOQA
except ImportError: except ImportError:
numpydoc_unavailable = True numpydoc_unavailable = True
else: else:
numpydoc_unavailable = False numpydoc_unavailable = False
try: try:
import numpy # NOQA import numpy # type: ignore[import-not-found] # NOQA
except ImportError: except ImportError:
numpy_unavailable = True numpy_unavailable = True
else: else:
@@ -222,7 +222,7 @@ def test_goto_stubs_on_itself(Script, code, type_):
def test_module_exists_only_as_stub(Script): def test_module_exists_only_as_stub(Script):
try: try:
import redis # noqa: F401 import redis # type: ignore[import-untyped] # noqa: F401
except ImportError: except ImportError:
pass pass
else: else:
+2 -2
View File
@@ -30,13 +30,13 @@ def test_find_module_basic():
def test_find_module_package(): def test_find_module_package():
file_io, is_package = _find_module('json') file_io, is_package = _find_module('json')
assert file_io.path.parts[-2:] == ('json', '__init__.py') assert file_io.path.parts[-2:] == ('json', '__init__.py') # type: ignore[union-attr]
assert is_package is True assert is_package is True
def test_find_module_not_package(): def test_find_module_not_package():
file_io, is_package = _find_module('io') file_io, is_package = _find_module('io')
assert file_io.path.name == 'io.py' assert file_io.path.name == 'io.py' # type: ignore[union-attr]
assert is_package is False assert is_package is False
+4 -4
View File
@@ -56,10 +56,10 @@ def test_generics_methods(code, expected, class_findable):
class Reader(Generic[T]): class Reader(Generic[T]):
@classmethod @classmethod
def read(cls) -> T: def read(cls) -> T:
return cls() return cls() # type: ignore[return-value]
def method(self) -> T: def method(self) -> T:
return 1 return 1 # type: ignore[return-value]
class Foo(Reader[str]): class Foo(Reader[str]):
def transform(self) -> int: def transform(self) -> int:
@@ -94,7 +94,7 @@ def test_signature():
pass pass
from inspect import Signature, Parameter from inspect import Signature, Parameter
some_signature.__signature__ = Signature([ some_signature.__signature__ = Signature([ # type: ignore[attr-defined]
Parameter('bar', kind=Parameter.KEYWORD_ONLY, default=1) Parameter('bar', kind=Parameter.KEYWORD_ONLY, default=1)
]) ])
@@ -105,7 +105,7 @@ def test_signature():
def test_compiled_signature_annotation_string(): def test_compiled_signature_annotation_string():
import typing import typing
def func(x: typing.Type, y: typing.Union[typing.Type, int]): def func(x: typing.Type, y: typing.Union[typing.Type, int]): # type: ignore[type-arg]
pass pass
func.__name__ = 'not_func' func.__name__ = 'not_func'
+2 -1
View File
@@ -2,6 +2,7 @@ from textwrap import dedent
from operator import eq, ge, lt from operator import eq, ge, lt
import re import re
import os import os
from typing import Any
import pytest import pytest
@@ -448,7 +449,7 @@ def test_dataclass_signature(
assert price.name == price_type_infer assert price.name == price_type_infer
dataclass_transform_cases = [ dataclass_transform_cases: list[Any] = [
# Attributes on the decorated class and its base classes # Attributes on the decorated class and its base classes
# are not considered to be fields. # are not considered to be fields.
# 1/ Declare dataclass transformer # 1/ Declare dataclass transformer
+8 -6
View File
@@ -1,7 +1,9 @@
from typing import Any
try: try:
import readline import readline
except ImportError: except ImportError:
readline = False readline = False # type: ignore[assignment]
import unittest import unittest
from jedi import utils from jedi import utils
@@ -15,7 +17,7 @@ class TestSetupReadline(unittest.TestCase):
def setUp(self, *args, **kwargs): def setUp(self, *args, **kwargs):
super().setUp(*args, **kwargs) super().setUp(*args, **kwargs)
self.namespace = self.NameSpace() self.namespace: Any = self.NameSpace()
utils.setup_readline(self.namespace) utils.setup_readline(self.namespace)
def complete(self, text): def complete(self, text):
@@ -47,8 +49,8 @@ class TestSetupReadline(unittest.TestCase):
def test_modules(self): def test_modules(self):
import sys import sys
import os import os
self.namespace.sys = sys self.namespace.sys = sys # type: ignore[attr-defined]
self.namespace.os = os self.namespace.os = os # type: ignore[attr-defined]
try: try:
assert self.complete('os.path.join') == ['os.path.join'] assert self.complete('os.path.join') == ['os.path.join']
@@ -58,8 +60,8 @@ class TestSetupReadline(unittest.TestCase):
c = {'os.' + d for d in dir(os) if d.startswith('ch')} c = {'os.' + d for d in dir(os) if d.startswith('ch')}
assert set(self.complete('os.ch')) == set(c) assert set(self.complete('os.ch')) == set(c)
finally: finally:
del self.namespace.sys del self.namespace.sys # type: ignore[attr-defined]
del self.namespace.os del self.namespace.os # type: ignore[attr-defined]
def test_calls(self): def test_calls(self):
s = 'str(bytes' s = 'str(bytes'