Coverage for /home/crpier/Projects/snektest/snektest/annotations.py: 84%

37 statements  

« prev     ^ index     » next       coverage.py v7.14.1, created at 2026-06-07 00:30 +0300

1from collections.abc import AsyncGenerator, Generator 

2from collections.abc import Coroutine as _Coroutine 

3from dataclasses import dataclass 

4from pathlib import Path 

5from typing import Annotated, Any, NewType 

6 

7from pydantic import ( 

8 GetCoreSchemaHandler, 

9 GetJsonSchemaHandler, 

10 TypeAdapter, 

11 ValidationInfo, 

12) 

13from pydantic.json_schema import JsonSchemaValue 

14from pydantic_core import CoreSchema, PydanticCustomError 

15from pydantic_core.core_schema import ( 

16 with_info_after_validator_function, 

17) 

18 

19type AsyncFixture[T] = AsyncGenerator[T] 

20type AsyncSessionFixture[T] = AsyncGenerator[T] 

21type Coroutine[T] = _Coroutine[None, None, T] 

22type Fixture[T] = Generator[T, None, None] # noqa: UP043 

23type SessionFixture[T] = Generator[T, None, None] # noqa: UP043 

24 

25 

26@dataclass 

27class PyFileType: 

28 def __get_pydantic_json_schema__( 

29 self, core_schema: CoreSchema, handler: GetJsonSchemaHandler 

30 ) -> JsonSchemaValue: 

31 field_schema = handler(core_schema) 

32 field_schema.update(format="file-path", type="string") 

33 return field_schema 

34 

35 def __get_pydantic_core_schema__( 

36 self, source: Any, handler: GetCoreSchemaHandler 

37 ) -> CoreSchema: 

38 return with_info_after_validator_function( 

39 self.validate_file, 

40 handler(source), 

41 ) 

42 

43 @staticmethod 

44 def validate_file(path: Path, _: ValidationInfo) -> Path: 

45 if not path.is_file(): 

46 err_type = "path_not_file" 

47 msg = "Path does not point to a file" 

48 raise PydanticCustomError(err_type, msg) 

49 if path.suffix != ".py": 

50 err_type = "path_not_python" 

51 msg = "File path points to is not `.py`" 

52 raise PydanticCustomError(err_type, msg) 

53 return path 

54 

55 def __hash__(self) -> int: 

56 return hash(self.__class__.__name__) 

57 

58 

59PyFilePath = Annotated[NewType("PyFile", Path), PyFileType()] 

60validate_PyFilePath = TypeAdapter[PyFilePath](PyFilePath).validate_python