Coverage for src/fluree_py/http/mixin/utils.py: 77%

22 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-02 03:03 +0000

1"""Utility functions for resolving generic type parameters in mixins.""" 

2 

3import sys 

4from typing import Any, ForwardRef 

5 

6 

7def find_base_class(cls: type[Any], base_name: str) -> type[Any]: 

8 """Locates a base class by name in the class's original bases. 

9 

10 Exceptions: 

11 TypeError: If the base class cannot be found. 

12 """ 

13 for base in cls.__orig_bases__: 

14 if base.__name__ == base_name: 

15 return base 

16 return cls 

17 

18 

19def resolve_base_class_reference(cls: type[Any], base_name: str) -> type[Any]: 

20 """Resolves the type parameter from a generic base class. 

21 

22 Exceptions: 

23 TypeError: If no type argument is found or if the type cannot be resolved. 

24 """ 

25 base_class = find_base_class(cls, base_name) 

26 

27 if not hasattr(base_class, "__args__"): 

28 return cls 

29 

30 type_arg = base_class.__args__[0] 

31 if not type_arg: 

32 raise TypeError(f"No argument found for {base_name}") 

33 

34 if not isinstance(type_arg, ForwardRef): 

35 return type_arg 

36 

37 if sys.version_info < (3, 13): 

38 resolved_type = type_arg._evaluate( 

39 sys.modules[cls.__module__].__dict__, 

40 locals(), 

41 recursive_guard=frozenset(), 

42 ) 

43 else: 

44 resolved_type = type_arg._evaluate( 

45 sys.modules[cls.__module__].__dict__, 

46 locals(), 

47 type_params=(), 

48 recursive_guard=frozenset(), 

49 ) 

50 

51 if not resolved_type: 

52 raise TypeError(f"Unable to resolve type argument {type_arg}") 

53 

54 return resolved_type