mirror of
https://github.com/davidhalter/jedi.git
synced 2026-10-20 23:47:05 +08:00
Honor return annotations of async pytest fixtures
Async fixtures skipped the annotation branch, so a `-> T` annotation was ignored and only the body was inferred. Infer the annotation directly: the awaited value for coroutines, and the yielded value for annotated async generators. Add cases where the body is not inferable. Also drop the tooling note from the AUTHORS entry. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d8efff8e30
commit
3f7e8adddc
3 files changed
+35
-5
No files matched your search
+1
-1
@@ -71,7 +71,7 @@ Code Contributors
|
|||||||
- Dhanraj E (@Dhanu-dynamic) <dhanraj@labs.digiscrypt.com>
|
- Dhanraj E (@Dhanu-dynamic) <dhanraj@labs.digiscrypt.com>
|
||||||
- Charan Rathore (@charan-rathore)
|
- Charan Rathore (@charan-rathore)
|
||||||
|
|
||||||
- Abdullah Ahmed (@abdull-ah-med) (with OpenAI Codex assistance)
|
- Abdullah Ahmed (@abdull-ah-med)
|
||||||
|
|
||||||
And a few more "anonymous" contributors.
|
And a few more "anonymous" contributors.
|
||||||
|
|
||||||
|
|||||||
+16
-3
@@ -2,7 +2,9 @@ import sys
|
|||||||
from typing import List
|
from typing import List
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
from jedi.inference.arguments import ValuesArguments
|
||||||
from jedi.inference.cache import inference_state_method_cache
|
from jedi.inference.cache import inference_state_method_cache
|
||||||
|
from jedi.inference.gradual.annotation import infer_return_types
|
||||||
from jedi.inference.imports import goto_import, load_module_from_path
|
from jedi.inference.imports import goto_import, load_module_from_path
|
||||||
from jedi.inference.filters import ParserTreeFilter
|
from jedi.inference.filters import ParserTreeFilter
|
||||||
from jedi.inference.base_value import NO_VALUES, ValueSet
|
from jedi.inference.base_value import NO_VALUES, ValueSet
|
||||||
@@ -31,9 +33,20 @@ def execute(callback):
|
|||||||
|
|
||||||
def infer_anonymous_param(func):
|
def infer_anonymous_param(func):
|
||||||
def get_returns(value):
|
def get_returns(value):
|
||||||
# Async fixtures provide the awaited value, rather than a coroutine.
|
if value.tree_node.annotation is not None:
|
||||||
if (value.tree_node.annotation is not None
|
if value.tree_node.parent.type == 'async_funcdef':
|
||||||
and value.tree_node.parent.type != 'async_funcdef'):
|
# Async fixtures provide the awaited value, rather than a
|
||||||
|
# coroutine. The annotation of an async generator describes
|
||||||
|
# the iterator, so the value is what that iterator yields.
|
||||||
|
result = infer_return_types(value, ValuesArguments([]))
|
||||||
|
if value.as_context().is_generator():
|
||||||
|
return ValueSet.from_sets(
|
||||||
|
lazy_value.infer()
|
||||||
|
for v in result
|
||||||
|
for lazy_value in v.iterate(is_async=True)
|
||||||
|
)
|
||||||
|
return result
|
||||||
|
|
||||||
result = value.execute_with_values()
|
result = value.execute_with_values()
|
||||||
if any(v.name.get_qualified_names(include_module_names=True)
|
if any(v.name.get_qualified_names(include_module_names=True)
|
||||||
== ('typing', 'Generator')
|
== ('typing', 'Generator')
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from typing import Generator
|
from typing import AsyncGenerator, Generator
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from pytest import fixture
|
from pytest import fixture
|
||||||
@@ -229,6 +229,16 @@ async def async_yield_fixture():
|
|||||||
yield 1.0
|
yield 1.0
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
async def async_annotated_opaque() -> int:
|
||||||
|
return opaque_value
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
async def async_generator_annotated() -> AsyncGenerator[str, None]:
|
||||||
|
yield opaque_value
|
||||||
|
|
||||||
|
|
||||||
#? ['async_fixture']
|
#? ['async_fixture']
|
||||||
def test_async_fixture_completion(async_fixt
|
def test_async_fixture_completion(async_fixt
|
||||||
pass
|
pass
|
||||||
@@ -243,6 +253,13 @@ def test_async_fixture_inference(async_fixture, async_annotated_fixture, async_y
|
|||||||
async_yield_fixture
|
async_yield_fixture
|
||||||
|
|
||||||
|
|
||||||
|
def test_async_fixture_annotation(async_annotated_opaque, async_generator_annotated):
|
||||||
|
#? int()
|
||||||
|
async_annotated_opaque
|
||||||
|
#? str()
|
||||||
|
async_generator_annotated
|
||||||
|
|
||||||
|
|
||||||
#! 30 ['def async_fixture']
|
#! 30 ['def async_fixture']
|
||||||
def test_async_fixture_goto(async_fixture):
|
def test_async_fixture_goto(async_fixture):
|
||||||
pass
|
pass
|
||||||
Reference in new issue
Block a user