diff --git a/jedi/evaluate/gradual/typeshed.py b/jedi/evaluate/gradual/typeshed.py index d0cd34ed..bc350898 100644 --- a/jedi/evaluate/gradual/typeshed.py +++ b/jedi/evaluate/gradual/typeshed.py @@ -185,8 +185,12 @@ def _try_to_load_stub(evaluator, import_names, actual_context_set, # 4. Try to load pyi file somewhere if actual_context_set was not defined. if not actual_context_set: if parent_module_context is not None: - # TODO this attribute doesn't always exist - check_path = parent_module_context.py__path__() + try: + method = parent_module_context.py__path__ + except AttributeError: + check_path = [] + else: + check_path = method() # In case import_names names_for_path = (import_names[-1],) else: diff --git a/test/examples/stub_packages/no_python-stubs/__init__.pyi b/test/examples/stub_packages/no_python-stubs/__init__.pyi new file mode 100644 index 00000000..18770a10 --- /dev/null +++ b/test/examples/stub_packages/no_python-stubs/__init__.pyi @@ -0,0 +1 @@ +foo: int diff --git a/test/examples/stub_packages/with_python-stubs/__init__.pyi b/test/examples/stub_packages/with_python-stubs/__init__.pyi new file mode 100644 index 00000000..5e7ee1b5 --- /dev/null +++ b/test/examples/stub_packages/with_python-stubs/__init__.pyi @@ -0,0 +1,2 @@ +both: int +stub_only: str diff --git a/test/examples/stub_packages/with_python-stubs/module.pyi b/test/examples/stub_packages/with_python-stubs/module.pyi new file mode 100644 index 00000000..53331495 --- /dev/null +++ b/test/examples/stub_packages/with_python-stubs/module.pyi @@ -0,0 +1 @@ +in_sub_module: int diff --git a/test/examples/stub_packages/with_python/__init__.py b/test/examples/stub_packages/with_python/__init__.py new file mode 100644 index 00000000..d16c270e --- /dev/null +++ b/test/examples/stub_packages/with_python/__init__.py @@ -0,0 +1,2 @@ +python_only = 1 +both = '' diff --git a/test/examples/stub_packages/with_python/module.py b/test/examples/stub_packages/with_python/module.py new file mode 100644 index 00000000..375009f8 --- /dev/null +++ b/test/examples/stub_packages/with_python/module.py @@ -0,0 +1 @@ +in_sub_module = '' diff --git a/test/test_evaluate/test_gradual/test_stub_loading.py b/test/test_evaluate/test_gradual/test_stub_loading.py new file mode 100644 index 00000000..c3d4fc90 --- /dev/null +++ b/test/test_evaluate/test_gradual/test_stub_loading.py @@ -0,0 +1,27 @@ +from functools import partial +from test.helpers import get_example_dir +from jedi.api.project import Project + +import pytest + + +@pytest.fixture +def ScriptInStubFolder(Script): + path = get_example_dir('stub_packages') + project = Project(path, sys_path=[path], smart_sys_path=False) + return partial(Script, _project=project) + + +@pytest.mark.parametrize( + ('code', 'expected'), [ + ('from no_python import foo', ['int']), + ('from with_python import stub_only', ['str']), + ('from with_python import python_only', []), + ('from with_python import both', ['int']), + ('from with_python import something_random', []), + ('from with_python.module import in_sub_module', ['int']), + ] +) +def test_find_stubs_infer(ScriptInStubFolder, code, expected): + defs = ScriptInStubFolder(code).goto_definitions() + assert [d.name for d in defs] == expected