Coverage for src/rtflite/type_guards.py: 80%

15 statements  

« prev     ^ index     » next       coverage.py v7.10.5, created at 2025-08-25 22:35 +0000

1"""Type guards for RTF components to handle Union types safely.""" 

2 

3from collections.abc import Sequence 

4from typing import Any, TypeGuard 

5 

6from .input import RTFBody, RTFColumnHeader 

7 

8 

9def is_single_header( 

10 header: RTFColumnHeader | Sequence[RTFColumnHeader | None] | None, 

11) -> TypeGuard[RTFColumnHeader]: 

12 """Check if header is a single RTFColumnHeader instance.""" 

13 return header is not None and not isinstance(header, (list, tuple)) 

14 

15 

16def is_single_body(body: RTFBody | Sequence[RTFBody] | None) -> TypeGuard[RTFBody]: 

17 """Check if body is a single RTFBody instance.""" 

18 return body is not None and not isinstance(body, (list, tuple)) 

19 

20 

21def is_list_header( 

22 header: RTFColumnHeader | Sequence[RTFColumnHeader | None] | None, 

23) -> TypeGuard[Sequence[RTFColumnHeader | None]]: 

24 """Check if header is a sequence of RTFColumnHeader instances.""" 

25 return isinstance(header, (list, tuple)) 

26 

27 

28def is_list_body( 

29 body: RTFBody | Sequence[RTFBody] | None, 

30) -> TypeGuard[Sequence[RTFBody]]: 

31 """Check if body is a sequence of RTFBody instances.""" 

32 return isinstance(body, (list, tuple)) 

33 

34 

35def is_nested_header_list( 

36 header: Any, 

37) -> TypeGuard[list[list[RTFColumnHeader | None]]]: 

38 """Check if header is a nested list of RTFColumnHeader instances.""" 

39 return isinstance(header, list) and len(header) > 0 and isinstance(header[0], list) 

40 

41 

42def is_flat_header_list( 

43 header: Any, 

44) -> TypeGuard[list[RTFColumnHeader | None]]: 

45 """Check if header is a flat list of RTFColumnHeader instances.""" 

46 return isinstance(header, list) and ( 

47 len(header) == 0 or not isinstance(header[0], list) 

48 )