Coverage for tests/test_stdlib.py: 94.12%

28 statements  

« prev     ^ index     » next       coverage.py v7.6.2, created at 2024-10-12 01:34 +0200

1"""Fuzzing on the standard library.""" 

2 

3from __future__ import annotations 

4 

5import sys 

6from contextlib import suppress 

7from typing import TYPE_CHECKING 

8 

9import pytest 

10 

11from griffe import GriffeLoader, LoadingError 

12 

13if TYPE_CHECKING: 

14 from collections.abc import Iterator 

15 

16 from griffe import Alias, Object 

17 

18 

19def _access_inherited_members(obj: Object | Alias) -> None: 

20 try: 

21 is_class = obj.is_class 

22 except Exception: # noqa: BLE001 

23 return 

24 if is_class: 

25 assert obj.inherited_members is not None 

26 else: 

27 for cls in obj.classes.values(): 

28 _access_inherited_members(cls) 

29 

30 

31@pytest.fixture(name="stdlib_loader", scope="session") 

32def fixture_stdlib_loader() -> Iterator[GriffeLoader]: 

33 """Yield a GriffeLoader instance. 

34 

35 During teardown, resolve aliases and access inherited members 

36 to make sure that no exception is raised when computing MRO. 

37 """ 

38 loader = GriffeLoader(allow_inspection=False, store_source=False) 

39 yield loader 

40 loader.resolve_aliases(implicit=True, external=None) 

41 for module in loader.modules_collection.members.values(): 

42 _access_inherited_members(module) 

43 loader.stats() 

44 

45 

46@pytest.mark.skipif(sys.version_info < (3, 10), reason="Python less than 3.10 does not have sys.stdlib_module_names") 

47@pytest.mark.parametrize("mod", sorted([m for m in getattr(sys, "stdlib_module_names", ()) if not m.startswith("_")])) 

48def test_fuzzing_on_stdlib(stdlib_loader: GriffeLoader, mod: str) -> None: 

49 """Run Griffe on the standard library.""" 

50 with suppress(ImportError, LoadingError): 

51 stdlib_loader.load(mod)