Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/hypothesis/internal/validation.py: 61%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

66 statements  

1# This file is part of Hypothesis, which may be found at 

2# https://github.com/HypothesisWorks/hypothesis/ 

3# 

4# Copyright the Hypothesis Authors. 

5# Individual contributors are listed in AUTHORS.rst and the git log. 

6# 

7# This Source Code Form is subject to the terms of the Mozilla Public License, 

8# v. 2.0. If a copy of the MPL was not distributed with this file, You can 

9# obtain one at https://mozilla.org/MPL/2.0/. 

10 

11import decimal 

12import math 

13from numbers import Rational, Real 

14from typing import Union 

15 

16from hypothesis.errors import InvalidArgument 

17from hypothesis.internal.coverage import check_function 

18 

19 

20@check_function 

21def check_type(typ: Union[type, tuple[type, ...]], arg: object, name: str) -> None: 

22 if not isinstance(arg, typ): 

23 if isinstance(typ, tuple): 

24 assert len(typ) >= 2, "Use bare type instead of len-1 tuple" 

25 typ_string = "one of " + ", ".join(t.__name__ for t in typ) 

26 else: 

27 typ_string = typ.__name__ 

28 

29 if typ_string == "SearchStrategy": 

30 from hypothesis.strategies import SearchStrategy 

31 

32 # Use hypothesis.strategies._internal.strategies.check_strategy 

33 # instead, as it has some helpful "did you mean..." logic. 

34 assert typ is not SearchStrategy, "use check_strategy instead" 

35 

36 raise InvalidArgument( 

37 f"Expected {typ_string} but got {name}={arg!r} (type={type(arg).__name__})" 

38 ) 

39 

40 

41@check_function 

42def check_valid_integer(value, name): 

43 """Checks that value is either unspecified, or a valid integer. 

44 

45 Otherwise raises InvalidArgument. 

46 """ 

47 if value is None: 

48 return 

49 check_type(int, value, name) 

50 

51 

52@check_function 

53def check_valid_bound(value, name): 

54 """Checks that value is either unspecified, or a valid interval bound. 

55 

56 Otherwise raises InvalidArgument. 

57 """ 

58 if value is None or isinstance(value, (int, Rational)): 

59 return 

60 if not isinstance(value, (Real, decimal.Decimal)): 

61 raise InvalidArgument(f"{name}={value!r} must be a real number.") 

62 if math.isnan(value): 

63 raise InvalidArgument(f"Invalid end point {name}={value!r}") 

64 

65 

66@check_function 

67def check_valid_magnitude(value, name): 

68 """Checks that value is either unspecified, or a non-negative valid 

69 interval bound. 

70 

71 Otherwise raises InvalidArgument. 

72 """ 

73 check_valid_bound(value, name) 

74 if value is not None and value < 0: 

75 raise InvalidArgument(f"{name}={value!r} must not be negative.") 

76 elif value is None and name == "min_magnitude": 

77 raise InvalidArgument("Use min_magnitude=0 or omit the argument entirely.") 

78 

79 

80@check_function 

81def try_convert(typ, value, name): 

82 if value is None: 

83 return None 

84 if isinstance(value, typ): 

85 return value 

86 try: 

87 return typ(value) 

88 except (TypeError, ValueError, ArithmeticError) as err: 

89 raise InvalidArgument( 

90 f"Cannot convert {name}={value!r} of type " 

91 f"{type(value).__name__} to type {typ.__name__}" 

92 ) from err 

93 

94 

95@check_function 

96def check_valid_size(value, name): 

97 """Checks that value is either unspecified, or a valid non-negative size 

98 expressed as an integer. 

99 

100 Otherwise raises InvalidArgument. 

101 """ 

102 if value is None and name not in ("min_size", "size"): 

103 return 

104 check_type(int, value, name) 

105 if value < 0: 

106 raise InvalidArgument(f"Invalid size {name}={value!r} < 0") 

107 

108 

109@check_function 

110def check_valid_interval(lower_bound, upper_bound, lower_name, upper_name): 

111 """Checks that lower_bound and upper_bound are either unspecified, or they 

112 define a valid interval on the number line. 

113 

114 Otherwise raises InvalidArgument. 

115 """ 

116 if lower_bound is None or upper_bound is None: 

117 return 

118 if upper_bound < lower_bound: 

119 raise InvalidArgument( 

120 f"Cannot have {upper_name}={upper_bound!r} < {lower_name}={lower_bound!r}" 

121 ) 

122 

123 

124@check_function 

125def check_valid_sizes(min_size, max_size): 

126 check_valid_size(min_size, "min_size") 

127 check_valid_size(max_size, "max_size") 

128 check_valid_interval(min_size, max_size, "min_size", "max_size")