From ba7776c0d942e52427ab3832a3a81eed92a33fe9 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Fri, 10 Jan 2020 12:39:40 +0100 Subject: [PATCH] Make sure that CompiledValue can deal with string annotations Fixes #952 Inspired by #1461 --- jedi/inference/compiled/access.py | 11 +++++++++ test/test_api/test_interpreter.py | 39 +++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/jedi/inference/compiled/access.py b/jedi/inference/compiled/access.py index 7fec126f..350db95a 100644 --- a/jedi/inference/compiled/access.py +++ b/jedi/inference/compiled/access.py @@ -538,6 +538,17 @@ class DirectObjectAccess(object): if o is None: return None + try: + # Python 2 doesn't have typing. + import typing + except ImportError: + pass + else: + try: + o = typing.get_type_hints(self._obj).get('return') + except Exception: + pass + return self._create_access_path(o) def negate(self): diff --git a/test/test_api/test_interpreter.py b/test/test_api/test_interpreter.py index 09685291..2c7a39e5 100644 --- a/test/test_api/test_interpreter.py +++ b/test/test_api/test_interpreter.py @@ -18,6 +18,11 @@ else: eval(compile("""def exec_(source, global_map): exec source in global_map """, 'blub', 'exec')) +if py_version > 34: + import typing +else: + typing = None + class _GlobalNameSpace: class SideEffectContainer: @@ -626,3 +631,37 @@ def test_dict_getitem(code, types): comps = jedi.Interpreter(code, [locals()]).infer() assert [c.name for c in comps] == types + + +def foo(): + raise KeyError + + +def bar(): + return float + + +@pytest.mark.skipif(sys.version_info < (3, 5), reason="Ignore Python 2, because EOL") +@pytest.mark.parametrize( + 'annotations, result', [ + ({}, []), + (None, []), + ({'asdf': 'str'}, []), + + ({'return': 'str'}, ['str']), + ({'return': 'str().upper'}, []), + ({'return': 'foo()'}, []), + ({'return': 'bar()'}, ['float']), + # typing is available via globals. + #({'return': 'typing.Union[str, int]'}, ['str']), + + ({'return': 'decimal.Decimal'}, []), + ({'return': 'lalalalallalaa'}, []), + ({'return': 'lalalalallalaa.lala'}, []), + ] +) +def test_string_annotation(annotations, result): + x = lambda foo: 1 + x.__annotations__ = annotations + defs = jedi.Interpreter('x()', [locals()]).goto_definitions() + assert [d.name for d in defs] == result