Files
jedi/test/completion/pytest.py
T
Abdullah AhmedandClaude Sonnet 5.5 3f7e8adddc 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>
2026-10-12 04:52:32 -04:00

266 lines
4.3 KiB
Python

from typing import AsyncGenerator, Generator
import pytest
from pytest import fixture
@pytest.fixture(scope='module')
def my_fixture() -> str:
pass
@fixture
def my_simple_fixture():
return 1
@fixture
def my_yield_fixture():
yield 1
@fixture
class MyClassFixture():
pass
# -----------------
# goto/infer
# -----------------
#! 18 ['def my_conftest_fixture']
def test_x(my_conftest_fixture, my_fixture, my_not_existing_fixture, my_yield_fixture):
#? str()
my_fixture
#? int()
my_yield_fixture
#?
my_not_existing_fixture
#? float()
return my_conftest_fixture
#? 18 float()
def test_x(my_conftest_fixture, my_fixture):
pass
#! 18 ['param MyClassFixture']
def test_x(MyClassFixture):
#?
MyClassFixture
#? 15
def lala(my_fixture):
pass
@pytest.fixture
#? 15 str()
def lala(my_fixture):
pass
#! 15 ['param my_fixture']
def lala(my_fixture):
pass
@pytest.fixture
#! 15 ['def my_fixture']
def lala(my_fixture):
pass
# overriding types of a fixture should be possible
def test_x(my_yield_fixture: str):
#? str()
my_yield_fixture
# -----------------
# completion
# -----------------
#? 34 ['my_fixture']
def test_x(my_simple_fixture, my_fixture):
return
#? 34 ['my_fixture']
def test_x(my_simple_fixture, my_fixture):
return
#? ['my_fixture']
def test_x(my_simple_fixture, my_f
return
#? 18 ['my_simple_fixture']
def test_x(my_simple_fixture):
return
#? ['my_simple_fixture']
def test_x(my_simp
return
#? ['my_conftest_fixture']
def test_x(my_con
return
#? 18 ['my_conftest_fixture']
def test_x(my_conftest_fixture):
return
#? ['my_module_fixture']
def test_x(my_modu
return
#? []
def lala(my_con
return
@pytest.fixture
#? ['my_conftest_fixture']
def lala(my_con
return
@pytest.fixture
#? 15 ['my_conftest_fixture']
def lala(my_con):
return
@pytest.fixture
@some_decorator
#? ['my_conftest_fixture']
def lala(my_con
return
@pytest.fixture
@some_decorator
#? 15 ['my_conftest_fixture']
def lala(my_con):
return
# -----------------
# pytest owned fixtures
# -----------------
#? ['monkeypatch']
def test_p(monkeyp
#! 15 ['def monkeypatch']
def test_p(monkeypatch):
#? ['setattr']
monkeypatch.setatt
#? ['capsysbinary']
def test_p(capsysbin
def close_parens():
pass
# -----------------
# inheritance
# -----------------
@fixture
#? 40 ['inheritance_fixture']
def inheritance_fixture(inheritance_fixture):
#? str()
inheritance_fixture
#? ['upper']
inheritance_fixture.upper
return 1
#! 48 ['def inheritance_fixture']
def test_inheritance_fixture(inheritance_fixture, caplog):
#? int()
inheritance_fixture
#? ['set_level']
caplog.set_le
@pytest.fixture
def caplog(caplog):
yield caplog
# -----------------
# Generator with annotation
# -----------------
@pytest.fixture
def with_annot() -> Generator[float, None, None]:
pass
def test_with_annot(inheritance_fixture, with_annot):
#? float()
with_annot
# -----------------
# pytest external plugins
# -----------------
#? ['admin_user', 'admin_client']
def test_z(admin
#! 15 ['def admin_client']
def test_p(admin_client):
#? ['login', 'logout']
admin_client.log
@pytest.fixture
@some_decorator
#? ['admin_user']
def bla(admin_u
return
@pytest.fixture
@some_decorator
#! 12 ['def admin_user']
def bla(admin_user):
pass
# -----------------
# asynchronous fixtures
# -----------------
@pytest.fixture
async def async_fixture():
return 1
@pytest.fixture(scope='module')
async def async_annotated_fixture() -> str:
return ''
@fixture
async def async_yield_fixture():
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']
def test_async_fixture_completion(async_fixt
pass
def test_async_fixture_inference(async_fixture, async_annotated_fixture, async_yield_fixture):
#? int()
async_fixture
#? str()
async_annotated_fixture
#? float()
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']
def test_async_fixture_goto(async_fixture):
pass