Coverage for src / loman / compat.py: 100%

28 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-03-22 21:30 +0000

1"""Compatibility utilities for function signature inspection.""" 

2 

3import inspect 

4from collections.abc import Callable 

5from dataclasses import dataclass, field 

6from typing import Any 

7 

8 

9@dataclass 

10class _Signature: 

11 """Internal representation of a function signature for compatibility inspection.""" 

12 

13 kwd_params: list[str] = field() 

14 default_params: list[str] = field() 

15 has_var_args: bool = field() 

16 has_var_kwds: bool = field() 

17 

18 

19def get_signature(func: Callable[..., Any]) -> _Signature: 

20 """Extract function signature information for compatibility purposes.""" 

21 sig = inspect.signature(func) 

22 pk = inspect._ParameterKind 

23 has_var_args = False 

24 has_var_kwds = False 

25 all_keyword_params = [] 

26 default_params = [] 

27 for param_name, param in sig.parameters.items(): 

28 if param.kind == pk.VAR_POSITIONAL: 

29 has_var_args = True 

30 elif param.kind == pk.VAR_KEYWORD: 

31 has_var_kwds = True 

32 elif param.kind in (pk.POSITIONAL_OR_KEYWORD, pk.KEYWORD_ONLY): 

33 all_keyword_params.append(param_name) 

34 if param.default != inspect._empty: 

35 default_params.append(param_name) 

36 else: 

37 raise NotImplementedError(f"Unexpected param kind: {param.kind}") 

38 return _Signature(all_keyword_params, default_params, has_var_args, has_var_kwds)