safeshield 1.3.2__py3-none-any.whl → 1.4.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
validator/rules/string.py CHANGED
@@ -1,4 +1,4 @@
1
- from .base import ValidationRule
1
+ from .base import Rule
2
2
  from typing import Any, Dict, List, Optional, Set, Union, Tuple, Type
3
3
  import re
4
4
 
@@ -6,49 +6,56 @@ import re
6
6
  # STRING VALIDATION RULES
7
7
  # =============================================
8
8
 
9
- class AlphaRule(ValidationRule):
9
+ class StringRule(Rule):
10
+ def validate(self, field: str, value: Any, params: List[str]) -> bool:
11
+ return isinstance(value, str)
12
+
13
+ def message(self, field: str, params: List[str]) -> str:
14
+ return f"The :attribute must be a string."
15
+
16
+ class AlphaRule(Rule):
10
17
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
11
18
  return isinstance(value, str) and value.isalpha()
12
19
 
13
20
  def message(self, field: str, params: List[str]) -> str:
14
21
  return f"The :attribute may only contain letters."
15
22
 
16
- class AlphaDashRule(ValidationRule):
23
+ class AlphaDashRule(Rule):
17
24
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
18
25
  return isinstance(value, str) and bool(re.match(r'^[a-zA-Z0-9_-]+$', value))
19
26
 
20
27
  def message(self, field: str, params: List[str]) -> str:
21
28
  return f"The :attribute may only contain letters, numbers, dashes and underscores."
22
29
 
23
- class AlphaNumRule(ValidationRule):
30
+ class AlphaNumRule(Rule):
24
31
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
25
32
  return isinstance(value, str) and value.isalnum()
26
33
 
27
34
  def message(self, field: str, params: List[str]) -> str:
28
35
  return f"The :attribute may only contain letters and numbers."
29
36
 
30
- class UppercaseRule(ValidationRule):
37
+ class UppercaseRule(Rule):
31
38
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
32
39
  return isinstance(value, str) and value == value.upper()
33
40
 
34
41
  def message(self, field: str, params: List[str]) -> str:
35
42
  return f"The :attribute must be uppercase."
36
43
 
37
- class LowercaseRule(ValidationRule):
44
+ class LowercaseRule(Rule):
38
45
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
39
46
  return isinstance(value, str) and value == value.lower()
40
47
 
41
48
  def message(self, field: str, params: List[str]) -> str:
42
49
  return f"The :attribute must be lowercase."
43
50
 
44
- class AsciiRule(ValidationRule):
51
+ class AsciiRule(Rule):
45
52
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
46
53
  return isinstance(value, str) and all(ord(c) < 128 for c in value)
47
54
 
48
55
  def message(self, field: str, params: List[str]) -> str:
49
56
  return f"The :attribute must only contain ASCII characters."
50
57
 
51
- class StartsWithRule(ValidationRule):
58
+ class StartsWithRule(Rule):
52
59
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
53
60
  if not isinstance(value, str):
54
61
  return False
@@ -56,8 +63,17 @@ class StartsWithRule(ValidationRule):
56
63
 
57
64
  def message(self, field: str, params: List[str]) -> str:
58
65
  return f"The :attribute must start with one of the following: {', '.join(params)}."
66
+
67
+ class DoesntStartWithRule(Rule):
68
+ def validate(self, field: str, value: Any, params: List[str]) -> bool:
69
+ if not isinstance(value, str) or not params:
70
+ return False
71
+ return all(not value.startswith(prefix) for prefix in params)
72
+
73
+ def message(self, field: str, params: List[str]) -> str:
74
+ return f"The :attribute must not start with any of: {', '.join(params)}"
59
75
 
60
- class EndsWithRule(ValidationRule):
76
+ class EndsWithRule(Rule):
61
77
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
62
78
  if not isinstance(value, str):
63
79
  return False
@@ -65,3 +81,46 @@ class EndsWithRule(ValidationRule):
65
81
 
66
82
  def message(self, field: str, params: List[str]) -> str:
67
83
  return f"The :attribute must end with one of the following: {', '.join(params)}."
84
+
85
+ class DoesntEndWithRule(Rule):
86
+ def validate(self, field: str, value: Any, params: List[str]) -> bool:
87
+ if not isinstance(value, str) or not params:
88
+ return False
89
+ return all(not value.endswith(suffix) for suffix in params)
90
+
91
+ def message(self, field: str, params: List[str]) -> str:
92
+ return f"The :attribute must not end with any of: {', '.join(params)}"
93
+
94
+ class ConfirmedRule(Rule):
95
+ def validate(self, field: str, value: Any, params: List[str]) -> bool:
96
+ confirmation_field = f"{field}_confirmation"
97
+
98
+ return value == self.get_field_value(confirmation_field, '')
99
+
100
+ def message(self, field: str, params: List[str]) -> str:
101
+ return f"The :attribute confirmation does not match."
102
+
103
+ class RegexRule(Rule):
104
+ def validate(self, field: str, value: Any, params: List[str]) -> bool:
105
+ if not params or not isinstance(value, str):
106
+ return False
107
+ try:
108
+ return bool(re.fullmatch(params[0], value))
109
+ except re.error:
110
+ return False
111
+
112
+ def message(self, field: str, params: List[str]) -> str:
113
+ return f"The :attribute format is invalid."
114
+
115
+ class NotRegexRule(Rule):
116
+ def validate(self, field: str, value: Any, params: List[str]) -> bool:
117
+ if not params or not isinstance(value, str):
118
+ return True
119
+ print(not bool(re.search(params[0], value)))
120
+ try:
121
+ return not bool(re.search(params[0], value))
122
+ except re.error:
123
+ return True
124
+
125
+ def message(self, field: str, params: List[str]) -> str:
126
+ return f"The :attribute format is invalid."
@@ -1,7 +1,58 @@
1
- from .base import ValidationRule
1
+ from .base import Rule
2
2
  from typing import Any, Dict, List, Optional, Set, Union, Tuple, Type
3
- from .basic import AcceptedRule, DeclinedRule, ExcludeRule, RequiredRule, PresentRule, MissingRule, ProhibitedRule
3
+ from .basic import *
4
+ from .boolean import AcceptedRule, DeclinedRule
4
5
 
6
+ class RequiredIfRule(RequiredRule):
7
+ def validate(self, field: str, value: Any, params: List[str]) -> bool:
8
+ if len(params) == 1 and callable(params[0]):
9
+ condition_met = params[0](self.validator.data)
10
+ elif len(params) == 1 and isinstance(params[0], bool):
11
+ condition_met = params[0]
12
+ else:
13
+ conditions = list(zip(params[::2], params[1::2]))
14
+
15
+ condition_met = any(
16
+ str(self.get_field_value(field, '')) == str(expected_value)
17
+ for field, expected_value in conditions
18
+ if field and expected_value is not None
19
+ )
20
+
21
+ if condition_met:
22
+ return super().validate(field, value, params)
23
+
24
+ return True
25
+
26
+ class RequiredUnlessRule(RequiredRule):
27
+ def validate(self, field: str, value: Any, params: List[str]) -> bool:
28
+ if len(params) < 2:
29
+ return False
30
+
31
+ other_field, other_value = params[0], params[1]
32
+ actual_value = self.get_field_value(other_field, '')
33
+
34
+ if actual_value == other_value:
35
+ return True
36
+
37
+ return super().validate(field, value, params)
38
+
39
+ class RequiredAllIfRule(RequiredRule):
40
+ def validate(self, field: str, value: Any, params: List[str]) -> bool:
41
+ if len(params) < 2:
42
+ return False
43
+
44
+ conditions = [(f.strip(), v.strip()) for f, v in zip(params[::2], params[1::2])]
45
+
46
+ all_conditions_met = all(
47
+ self.get_field_value(f) == v
48
+ for f, v in conditions
49
+ )
50
+
51
+ if not all_conditions_met:
52
+ return True
53
+
54
+ return super().validate(field, value, params)
55
+
5
56
  class RequiredWithRule(RequiredRule):
6
57
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
7
58
  if not params:
@@ -38,101 +89,225 @@ class RequiredWithoutAllRule(RequiredRule):
38
89
  return super().validate(field, value, params)
39
90
  return True
40
91
 
41
- class PresentWithRule(PresentRule):
92
+ class RequiredIfAcceptedRule(RequiredRule, AcceptedRule):
42
93
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
43
94
  if not params:
44
95
  return False
45
- if any(self.get_field_value(param, None) is not None for param in params):
96
+
97
+ if AcceptedRule.validate(self, field, params[0], params):
46
98
  return super().validate(field, value, params)
47
99
 
48
100
  return True
49
101
 
50
- class PresentWithAllRule(PresentRule):
102
+ class RequiredIfDeclinedRule(RequiredRule, DeclinedRule):
51
103
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
52
104
  if not params:
53
105
  return False
54
106
 
55
- if all(self.get_field_value(param, None) is not None for param in params):
107
+ if DeclinedRule.validate(self, field, params[0], params):
56
108
  return super().validate(field, value, params)
57
109
 
58
- class MissingWithRule(MissingRule):
110
+ return True
111
+
112
+ class RequiredArrayKeysRule(Rule):
59
113
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
60
- if not params:
114
+ if not isinstance(value, dict) or not params:
61
115
  return False
116
+ return all(key in value for key in params)
117
+
118
+ def message(self, field: str, params: List[str]) -> str:
119
+ return f"The :attribute must contain all required keys: {', '.join(params)}"
120
+
121
+ class ProhibitedIfRule(ProhibitedRule):
122
+ def validate(self, field: str, value: Any, params: List[str]) -> bool:
123
+ if len(params) == 1 and callable(params[0]):
124
+ condition_met = params[0](self.validator.data)
125
+ elif len(params) == 1 and isinstance(params[0], bool):
126
+ condition_met = params[0]
127
+ else:
128
+ other_field, other_value = params[0], params[1]
129
+ actual_value = self.get_field_value(other_field, '')
62
130
 
63
- if any(self.get_field_value(param, None) is not None for param in params):
131
+ condition_met = actual_value == other_value
132
+
133
+ if condition_met:
64
134
  return super().validate(field, value, params)
135
+ return True
136
+
137
+ class ProhibitedUnlessRule(ProhibitedRule):
138
+ def validate(self, field: str, value: Any, params: List[str]) -> bool:
139
+ if len(params) < 2:
140
+ return False
141
+
142
+ other_field, other_value = params[0], params[1]
143
+ actual_value = self.get_field_value(other_field, '')
65
144
 
66
- return True
145
+ if actual_value == other_value:
146
+ return True
147
+
148
+ return super().validate(field, value, params)
67
149
 
68
- class MissingWithAllRule(MissingRule):
150
+ class ProhibitedIfAcceptedRule(ProhibitedRule, AcceptedRule):
69
151
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
70
152
  if not params:
71
153
  return False
72
154
 
73
- if all(self.get_field_value(param, None) is not None for param in params):
155
+ if AcceptedRule.validate(self, field, params[0], params):
74
156
  return super().validate(field, value, params)
75
-
76
157
  return True
77
158
 
78
- class ExcludeWithRule(ExcludeRule):
159
+ class ProhibitedIfDeclinedRule(ProhibitedRule, DeclinedRule):
79
160
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
80
- if any(not self.is_empty(self.get_field_value(param, None)) for param in params):
161
+ if not params:
162
+ return False
163
+
164
+ if DeclinedRule.validate(self, field, params[0], params):
81
165
  return super().validate(field, value, params)
82
-
166
+
83
167
  return True
84
168
 
85
- class ExcludeWithoutRule(ExcludeRule):
169
+ class PresentIfRule(PresentRule):
86
170
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
87
- if any(self.is_empty(self.get_field_value(param, None)) for param in params):
88
- return super().validate(field, value, params)
171
+ condition_met = False
172
+
173
+ if len(params) == 1 and callable(params[0]):
174
+ condition_met = params[0](self.validator.data)
175
+ elif len(params) == 1 and isinstance(params[0], bool):
176
+ condition_met = params[0]
177
+ else:
178
+ conditions = list(zip(params[::2], params[1::2]))
179
+ for other_field, expected_value in conditions:
180
+ if self.get_field_value(other_field, None) == expected_value:
181
+ condition_met = True
182
+ break
89
183
 
184
+ if condition_met:
185
+ return super().validate(field, value, params)
186
+
90
187
  return True
91
188
 
92
- class ProhibitedIfAcceptedRule(ProhibitedRule, AcceptedRule):
189
+ class PresentUnlessRule(PresentRule):
93
190
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
94
- if not params:
191
+ if len(params) < 2:
95
192
  return False
193
+ other_field, other_value = params[0], params[1]
96
194
 
97
- if AcceptedRule.validate(self, field, params[0], params):
195
+ if self.get_field_value(other_field, None) != other_value:
98
196
  return super().validate(field, value, params)
197
+
99
198
  return True
100
-
101
- class ProhibitedIfDeclinedRule(ProhibitedRule, DeclinedRule):
199
+
200
+ class PresentWithRule(PresentRule):
102
201
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
103
202
  if not params:
104
203
  return False
105
-
106
- if DeclinedRule.validate(self, field, params[0], params):
204
+ if any(self.get_field_value(param, None) is not None for param in params):
107
205
  return super().validate(field, value, params)
108
206
 
109
207
  return True
110
208
 
111
- class RequiredIfAcceptedRule(RequiredRule, AcceptedRule):
209
+ class PresentWithAllRule(PresentRule):
112
210
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
113
211
  if not params:
114
212
  return False
115
213
 
116
- if AcceptedRule.validate(self, field, params[0], params):
214
+ if all(self.get_field_value(param, None) is not None for param in params):
215
+ return super().validate(field, value, params)
216
+
217
+ class MissingIfRule(MissingRule):
218
+ def validate(self, field: str, value: Any, params: List[str]) -> bool:
219
+ condition_met = False
220
+
221
+ if len(params) == 1 and callable(params[0]):
222
+ condition_met = params[0](self.validator.data)
223
+ elif len(params) == 1 and isinstance(params[0], bool):
224
+ condition_met = params[0]
225
+ else:
226
+ conditions = list(zip(params[::2], params[1::2]))
227
+ for other_field, expected_value in conditions:
228
+ if self.get_field_value(other_field, None) == expected_value:
229
+ condition_met = True
230
+ break
231
+
232
+ if condition_met:
117
233
  return super().validate(field, value, params)
118
234
 
119
235
  return True
120
236
 
121
- class RequiredIfDeclinedRule(RequiredRule, DeclinedRule):
237
+ class MissingUnlessRule(MissingRule):
238
+ def validate(self, field: str, value: Any, params: List[str]) -> bool:
239
+ if len(params) < 2:
240
+ return False
241
+ other_field, other_value = params[0], params[1]
242
+ if self.get_field_value(other_field, None) != other_value:
243
+ return super().validate(field, value, params)
244
+
245
+ return True
246
+
247
+ class MissingWithRule(MissingRule):
122
248
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
123
249
  if not params:
124
250
  return False
125
251
 
126
- if DeclinedRule.validate(self, field, params[0], params):
252
+ if any(self.get_field_value(param, None) is not None for param in params):
127
253
  return super().validate(field, value, params)
128
254
 
129
255
  return True
130
256
 
131
- class RequiredArrayKeysRule(ValidationRule):
257
+ class MissingWithAllRule(MissingRule):
132
258
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
133
- if not isinstance(value, dict) or not params:
259
+ if not params:
134
260
  return False
135
- return all(key in value for key in params)
261
+
262
+ if all(self.get_field_value(param, None) is not None for param in params):
263
+ return super().validate(field, value, params)
264
+
265
+ return True
136
266
 
267
+ class ExcludeIfRule(ExcludeRule):
268
+ def validate(self, field: str, value: Any, params: List[str]) -> bool:
269
+ if len(params) == 1 and callable(params[0]):
270
+ condition_met = params[0](self.validator.data)
271
+ elif len(params) == 1 and isinstance(params[0], bool):
272
+ condition_met = params[0]
273
+ else:
274
+ conditions = list(zip(params[::2], params[1::2]))
275
+ condition_met = all(
276
+ str(self.get_field_value(f)) == str(v)
277
+ for f, v in conditions
278
+ )
279
+
280
+ if condition_met:
281
+ return super().validate(field, value, params)
282
+ return True
283
+
284
+ class ExcludeUnlessRule(ExcludeRule):
285
+ def validate(self, field: str, value: Any, params: List[str]) -> bool:
286
+ conditions = [(f.strip(), v.strip()) for f, v in zip(params[::2], params[1::2])]
287
+
288
+ all_conditions_met = all(
289
+ self.get_field_value(f) == v
290
+ for f, v in conditions
291
+ )
292
+
293
+ if not all_conditions_met:
294
+ return super().validate(field, value, params)
295
+
296
+ return True
297
+
137
298
  def message(self, field: str, params: List[str]) -> str:
138
- return f"The :attribute must contain all required keys: {', '.join(params)}"
299
+ return f"The :attribute field is excluded unless {params[0]} is {params[1]}."
300
+
301
+ class ExcludeWithRule(ExcludeRule):
302
+ def validate(self, field: str, value: Any, params: List[str]) -> bool:
303
+ if any(not self.is_empty(self.get_field_value(param, None)) for param in params):
304
+ return super().validate(field, value, params)
305
+
306
+ return True
307
+
308
+ class ExcludeWithoutRule(ExcludeRule):
309
+ def validate(self, field: str, value: Any, params: List[str]) -> bool:
310
+ if any(self.is_empty(self.get_field_value(param, None)) for param in params):
311
+ return super().validate(field, value, params)
312
+
313
+ return True
@@ -58,11 +58,11 @@ class RuleConflictChecker:
58
58
  }
59
59
 
60
60
  @classmethod
61
- def check_conflicts(cls, rules: List['ValidationRule']) -> None:
61
+ def check_conflicts(cls, rules: List['Rule']) -> None:
62
62
  """Main method untuk mengecek semua jenis konflik.
63
63
 
64
64
  Args:
65
- rules: List of ValidationRule objects to check
65
+ rules: List of Rule objects to check
66
66
 
67
67
  Raises:
68
68
  ValueError: Untuk konflik kritis
@@ -114,7 +114,7 @@ class RuleErrorHandler:
114
114
  return []
115
115
 
116
116
  pairs = []
117
- params = self._current_params.copy()
117
+ params = list(self._current_params).copy()
118
118
 
119
119
  # Process parameters in pairs (field, value)
120
120
  while len(params) >= 2:
@@ -129,9 +129,11 @@ class RuleErrorHandler:
129
129
  for placeholder, replacement in replacements.items():
130
130
  if replacement is not None:
131
131
  # Use regex to avoid partial replacements
132
+ safe_replacement = re.escape(str(replacement))
133
+ safe_replacement = safe_replacement.replace('\\', r'')
132
134
  message = re.sub(
133
135
  re.escape(placeholder) + r'(?![a-zA-Z0-9_])',
134
- str(replacement),
136
+ safe_replacement,
135
137
  message
136
138
  )
137
139
  return message
@@ -1,6 +1,6 @@
1
1
  from validator.factory import RuleFactory
2
2
  from validator.services.rule_conflict import RuleConflictChecker
3
- from validator.rules import ValidationRule
3
+ from validator.rules import Rule
4
4
  from typing import Dict, List, Union, Tuple
5
5
  from validator.exceptions import RuleNotFoundException
6
6
  from collections.abc import Iterable, Sequence
@@ -14,7 +14,7 @@ class RulePreparer:
14
14
  def __init__(self, rule_factory: RuleFactory):
15
15
  self.rule_factory = rule_factory
16
16
 
17
- def prepare(self, raw_rules: Dict[str, Union[str, List[Union[str, ValidationRule]]]]) -> Dict[str, List[ValidationRule]]:
17
+ def prepare(self, raw_rules: Dict[str, Union[str, List[Union[str, Rule]]]]) -> Dict[str, List[Rule]]:
18
18
  """Convert raw rules to prepared validation rules"""
19
19
  prepared_rules = {}
20
20
  for field, rule_input in raw_rules.items():
@@ -25,18 +25,18 @@ class RulePreparer:
25
25
  prepared_rules[field] = self._deduplicate_rules(rules)
26
26
  return prepared_rules
27
27
 
28
- def _convert_to_rules(self, rule_input: Union[str, List[Union[str, ValidationRule]], ValidationRule, Tuple[Union[str, ValidationRule], str], Tuple[Union[str, ValidationRule], str]]) -> List[ValidationRule]:
29
- """Convert mixed rule input to list of ValidationRule objects"""
28
+ def _convert_to_rules(self, rule_input: Union[str, List[Union[str, Rule]], Rule, Tuple[Union[str, Rule], str], Tuple[Union[str, Rule], str]]) -> List[Rule]:
29
+ """Convert mixed rule input to list of Rule objects"""
30
30
  if rule_input is None:
31
31
  return []
32
- if isinstance(rule_input, ValidationRule):
32
+ if isinstance(rule_input, Rule):
33
33
  return [rule_input]
34
- if isinstance(rule_input, list):
34
+ if isinstance(rule_input, list | tuple):
35
35
  rules = []
36
36
  for r in rule_input:
37
37
  if isinstance(r, str):
38
38
  rules.extend(self._parse_rule_string(r))
39
- elif isinstance(r, ValidationRule):
39
+ elif isinstance(r, Rule):
40
40
  rules.append(r)
41
41
  elif isinstance(r, (tuple, list)):
42
42
  if len(r) == 0:
@@ -50,10 +50,10 @@ class RulePreparer:
50
50
  if isinstance(rule_name, str):
51
51
  rule = RuleFactory.create_rule(rule_name)
52
52
  rule.params = params
53
- elif isinstance(rule_name, ValidationRule):
53
+ elif isinstance(rule_name, Rule):
54
54
  rule = rule_name
55
55
  if params:
56
- warnings.warn(f"Parameters {params} are ignored for ValidationRule instance")
56
+ warnings.warn(f"Parameters {params} are ignored for Rule instance")
57
57
  else:
58
58
  raise ValueError(f"Invalid rule name type in {r}")
59
59
 
@@ -65,8 +65,8 @@ class RulePreparer:
65
65
  return self._parse_rule_string(rule_input)
66
66
  raise ValueError(f"Invalid rule input type: {type(rule_input)}")
67
67
 
68
- def _parse_rule_string(self, rule_str: str) -> List[ValidationRule]:
69
- """Parse rule string into ValidationRule objects"""
68
+ def _parse_rule_string(self, rule_str: str) -> List[Rule]:
69
+ """Parse rule string into Rule objects"""
70
70
  rules = []
71
71
  for rule_part in rule_str.split('|'):
72
72
  rule_part = rule_part.strip()
@@ -93,22 +93,9 @@ class RulePreparer:
93
93
  return rule_name, [p.strip() for p in param_str.split(',') if p.strip()]
94
94
 
95
95
  def _parse_params(self, params: Union[Tuple, List, str, Enum]):
96
- all_params = []
97
- # seen = set()
98
- # for param in params:
99
- # if isinstance(param, Iterable) and not isinstance(param, str | bytes) and not inspect.isclass(param):
100
- # for item in param:
101
- # if item not in seen and item not in (None, '', [], {}) and (isinstance(item, (Number, Sequence)) or inspect.isclass(item)):
102
- # seen.add(item)
103
- # all_params.append(item)
104
- # else:
105
- # if param not in seen and param not in (None, '', [], {}) and (isinstance(param, (Number, Sequence)) or inspect.isclass(param)):
106
- # seen.add(param)
107
- # all_params.append(param)
108
-
109
96
  return set(tuple(x) if isinstance(x, list) else x for x in params)
110
97
 
111
- def _deduplicate_rules(self, rules: List[ValidationRule]) -> List[ValidationRule]:
98
+ def _deduplicate_rules(self, rules: List[Rule]) -> List[Rule]:
112
99
  """Remove duplicate rules based on name and parameters"""
113
100
  seen = set()
114
101
  unique = []
@@ -1,31 +0,0 @@
1
- validator/__init__.py,sha256=udxDzUicPfxBOAQvzsnl3pHur9VUppKbWMgg35hpiww,244
2
- validator/exceptions.py,sha256=y2v7CaXmeGFHWcnigtLl4U-sFta_jMiXkGKXWIIVglY,366
3
- validator/factory.py,sha256=bImQNLhEJg5VTxtHiMYVb2EbHWvimTDqHq-UcA8uolw,812
4
- validator/core/__init__.py,sha256=ZcqlXJSk03i_CVzmIN-nVe1UOyvwwO5jhbEj7f62Y_o,59
5
- validator/core/validator.py,sha256=Yaw7__Hf-PuKcXaJ6yaARPEyeofEaoqt5-N3tJZ_jtg,12741
6
- validator/database/__init__.py,sha256=O-cB6-MhNapJ3iwe5jvifbMfr1dPjXLtEdfNTKIu0hc,171
7
- validator/database/detector.py,sha256=Vac7oVL26GjU6expGo01-6mgUtXqldr-jirzpYokZBM,9597
8
- validator/database/manager.py,sha256=XJM_I0WaWfZWV710duAc32p1gtiP2or-MAj75WPw1oM,6478
9
- validator/rules/__init__.py,sha256=nDE3qoI82qJTCbILLUWkXuwsMOmsDtB1m-3IGIvRfpY,919
10
- validator/rules/array.py,sha256=3hgD_b2K61fG-xT1UdssHMOdIQKWw5vkdpovNn-kc8E,2835
11
- validator/rules/base.py,sha256=hrGESfkdvqZrQ1yIK_ftVVOMUuyvNFoz-_qaqUucSy8,3474
12
- validator/rules/basic.py,sha256=rL9THt3OE5QgtuxGCM_dklNpPKOdmuDP30EiSmvkgP8,9656
13
- validator/rules/comparison.py,sha256=Tlg3AfjTd-W1RonmhT0PLP_mf4CSyhpl7EsmCEYzEAA,9446
14
- validator/rules/conditional.py,sha256=M4x9g2LQTXNaNfb7dHRMs6vUseDu3WC1RB41QGiNABQ,5965
15
- validator/rules/date.py,sha256=sPrq8OgHMyUxRAZch4yt7K3I0lInIIy0dUgRtAkcsMk,5313
16
- validator/rules/files.py,sha256=eCrarOtaRWv1UBQuv5Y6-CcyHuncyLau8V8Ocpw0NVQ,6565
17
- validator/rules/format.py,sha256=hyho3Cxcgjz4mqCkO_uvjrJPU1JEOK2IZL7F6Dh9oPg,3784
18
- validator/rules/string.py,sha256=5NToIDOqBhmUYCg1y2y2zdQ4MMLyJzL0FCTM5XhzAgc,2951
19
- validator/rules/type.py,sha256=B8YH1T1RBlRNNOmb-5uZKdwBc8Uk1Zj4h4xIzAtJC2M,1883
20
- validator/rules/utilities.py,sha256=xysxDWoP1hJQyBZhNvdzTyMsFOWsEIxFBvYPljW1coA,5340
21
- validator/services/__init__.py,sha256=zzKTmqL7v4niFGWHJBfWLqgJ0iTaW_69OzYZN8uInzQ,210
22
- validator/services/rule_conflict.py,sha256=s1RJNUY5d0WtSMHkrKulBCgJ2BZL2GE0Eu5pdAoiIbM,4943
23
- validator/services/rule_error_handler.py,sha256=MNgSxnakmc3f_nvGuapRmJ9woKt_-E8Wun39OCTrGB0,10273
24
- validator/services/rule_preparer.py,sha256=jRcMNjqq2xyZjO64Pim8jWmja5DmTzf0V_uuHG0lJTg,5621
25
- validator/utils/__init__.py,sha256=Yzo-xv285Be-a233M4duDdYtscuHiuBbPSX_C8yViJI,20
26
- validator/utils/string.py,sha256=0YACzeEaWNEOR9_7O9A8D1ItIbtWfOJ8IfrzcB8VMYA,515
27
- safeshield-1.3.2.dist-info/LICENSE,sha256=qugtRyKckyaks6hd2xyxOFSOYM6au1N80pMXuMTPvC4,1090
28
- safeshield-1.3.2.dist-info/METADATA,sha256=V17d3w6UPE698CGSm83-5C3NOm-lZrCqLJYAy8ozrHM,1984
29
- safeshield-1.3.2.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
30
- safeshield-1.3.2.dist-info/top_level.txt,sha256=iUtV3dlHOIiMfLuY4pruY00lFni8JzOkQ3Nh1II19OE,10
31
- safeshield-1.3.2.dist-info/RECORD,,