diff --git a/jedi/inference/compiled/access.py b/jedi/inference/compiled/access.py index 350db95a..dfca7d9c 100644 --- a/jedi/inference/compiled/access.py +++ b/jedi/inference/compiled/access.py @@ -484,6 +484,19 @@ class DirectObjectAccess(object): op = _OPERATORS[operator] return self._create_access_path(op(self._obj, other_access._obj)) + def get_annotation_name_and_args(self): + """ + Returns Tuple[Optional[str], Tuple[AccessPath, ...]] + """ + if sys.version_info < (3, 5): + return None, () + + import typing + args = typing.get_args(self._obj) + origin = typing.get_origin(self._obj) + name = None if origin is None else str(origin) + return name, tuple(self._create_access_path(arg) for arg in args) + def needs_type_completions(self): return inspect.isclass(self._obj) and self._obj != type diff --git a/jedi/inference/compiled/value.py b/jedi/inference/compiled/value.py index 3a54289e..54814294 100644 --- a/jedi/inference/compiled/value.py +++ b/jedi/inference/compiled/value.py @@ -271,6 +271,11 @@ class CompiledObject(Value): if self.access_handle.get_repr() == 'None': # None as an annotation doesn't need to be executed. return ValueSet([self]) + + name, args = self.access_handle.get_annotation_name_and_args() + arguments = [create_from_access_path(self.inference_state, path) for path in args] + if name == 'typing.Union': + return ValueSet.from_sets(arg.execute_annotation() for arg in arguments) return super(CompiledObject, self).execute_annotation() def negate(self): diff --git a/test/test_api/test_interpreter.py b/test/test_api/test_interpreter.py index 2c7a39e5..639a0e64 100644 --- a/test/test_api/test_interpreter.py +++ b/test/test_api/test_interpreter.py @@ -653,7 +653,11 @@ def bar(): ({'return': 'foo()'}, []), ({'return': 'bar()'}, ['float']), # typing is available via globals. - #({'return': 'typing.Union[str, int]'}, ['str']), + ({'return': 'typing.Union[str, int]'}, ['int', 'str']), + ({'return': 'typing.Union["str", int]'}, ['int']), + ({'return': 'typing.Union["str", 1]'}, []), + ({'return': 'typing.Optional[str]'}, ['NoneType', 'str']), + ({'return': 'typing.Optional[str, int]'}, []), # Takes only one arg ({'return': 'decimal.Decimal'}, []), ({'return': 'lalalalallalaa'}, []),