Coverage for lintro / tools / core / option_validators.py: 97%

37 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2026-04-03 18:53 +0000

1"""Option validation utilities for tool plugins. 

2 

3This module provides common validation functions to reduce boilerplate 

4in tool set_options() methods. 

5""" 

6 

7from typing import Any 

8 

9 

10def validate_bool(value: Any, name: str) -> None: 

11 """Validate that value is a boolean if not None. 

12 

13 Args: 

14 value: Value to validate. 

15 name: Parameter name for error message. 

16 

17 Raises: 

18 ValueError: If value is not None and not a boolean. 

19 """ 

20 if value is not None and not isinstance(value, bool): 

21 raise ValueError(f"{name} must be a boolean") 

22 

23 

24def validate_str(value: Any, name: str) -> None: 

25 """Validate that value is a string if not None. 

26 

27 Args: 

28 value: Value to validate. 

29 name: Parameter name for error message. 

30 

31 Raises: 

32 ValueError: If value is not None and not a string. 

33 """ 

34 if value is not None and not isinstance(value, str): 

35 raise ValueError(f"{name} must be a string") 

36 

37 

38def validate_int( 

39 value: Any, 

40 name: str, 

41 min_value: int | None = None, 

42 max_value: int | None = None, 

43) -> None: 

44 """Validate that value is an integer if not None. 

45 

46 Args: 

47 value: Value to validate. 

48 name: Parameter name for error message. 

49 min_value: Optional minimum allowed value (inclusive). 

50 max_value: Optional maximum allowed value (inclusive). 

51 

52 Raises: 

53 ValueError: If value is not None and not an integer, or if value 

54 is outside the specified range. 

55 """ 

56 if value is None: 

57 return 

58 

59 if not isinstance(value, int) or isinstance(value, bool): 

60 raise ValueError(f"{name} must be an integer") 

61 

62 if min_value is not None and value < min_value: 

63 raise ValueError(f"{name} must be at least {min_value}") 

64 

65 if max_value is not None and value > max_value: 

66 raise ValueError(f"{name} must be at most {max_value}") 

67 

68 

69def validate_positive_int(value: Any, name: str) -> None: 

70 """Validate that value is a positive integer if not None. 

71 

72 Args: 

73 value: Value to validate. 

74 name: Parameter name for error message. 

75 

76 Raises: 

77 ValueError: If value is not None and not a positive integer. 

78 """ 

79 if value is not None: 

80 if not isinstance(value, int) or isinstance(value, bool): 

81 raise ValueError(f"{name} must be an integer") 

82 if value <= 0: 

83 raise ValueError(f"{name} must be positive") 

84 

85 

86def validate_list(value: Any, name: str) -> None: 

87 """Validate that value is a list if not None. 

88 

89 Args: 

90 value: Value to validate. 

91 name: Parameter name for error message. 

92 

93 Raises: 

94 ValueError: If value is not None and not a list. 

95 """ 

96 if value is not None and not isinstance(value, list): 

97 raise ValueError(f"{name} must be a list") 

98 

99 

100def normalize_str_or_list(value: Any, name: str) -> list[str] | None: 

101 """Normalize a string or list value to a list. 

102 

103 Args: 

104 value: Value to normalize (string, list, or None). 

105 name: Parameter name for error message. 

106 

107 Returns: 

108 List of strings, or None if input was None. 

109 

110 Raises: 

111 ValueError: If value is not None, string, or list. 

112 """ 

113 if value is None: 

114 return None 

115 if isinstance(value, str): 

116 return [value] 

117 if isinstance(value, list): 

118 if not all(isinstance(item, str) for item in value): 

119 raise ValueError(f"{name} must be a string or list of strings") 

120 return value 

121 raise ValueError(f"{name} must be a string or list") 

122 

123 

124def filter_none_options(**kwargs: Any) -> dict[str, Any]: 

125 """Filter out None values from keyword arguments. 

126 

127 Args: 

128 **kwargs: Keyword arguments to filter. 

129 

130 Returns: 

131 Dictionary with only non-None values. 

132 """ 

133 return {k: v for k, v in kwargs.items() if v is not None}