diff --git a/jedi/inference/compiled/mixed.py b/jedi/inference/compiled/mixed.py index 43e0ed6c..b323d70e 100644 --- a/jedi/inference/compiled/mixed.py +++ b/jedi/inference/compiled/mixed.py @@ -187,7 +187,7 @@ def _find_syntax_node_name(inference_state, python_object): try: python_object = _get_object_to_check(python_object) path = inspect.getsourcefile(python_object) - except TypeError: + except (OSError, TypeError): # The type might not be known (e.g. class_with_dict.__weakref__) return None path = None if path is None else Path(path) diff --git a/test/test_api/test_interpreter.py b/test/test_api/test_interpreter.py index 4154c072..e6232e05 100644 --- a/test/test_api/test_interpreter.py +++ b/test/test_api/test_interpreter.py @@ -711,3 +711,24 @@ def test_negate(): assert x.name == 'int' value, = x._name.infer() assert value.get_safe_value() == -3 + + +def test_complete_not_findable_class_source(): + class TestClass(): + ta=1 + ta1=2 + + # Simulate the environment where the class is defined in + # an interactive session and therefore inspect module + # cannot find its source code and raises OSError (Py 3.10+) or TypeError. + TestClass.__module__ = "__main__" + # There is a pytest __main__ module we have to remove temporarily. + module = sys.modules.pop("__main__") + try: + interpreter = jedi.Interpreter("TestClass.", [locals()]) + completions = interpreter.complete(column=10, line=1) + finally: + sys.modules["__main__"] = module + + assert "ta" in [c.name for c in completions] + assert "ta1" in [c.name for c in completions]