enforce-rules 3.2.18__tar.gz → 3.2.20__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: enforce-rules
3
- Version: 3.2.18
3
+ Version: 3.2.20
4
4
  Summary: Runtime rule validation for Python using dictionary-based constraints.
5
5
  Author: Jake Loepker, Microsoft Copilot (AI Assistant)
6
6
  License: BSD 3-Clause License
@@ -40,6 +40,8 @@ Classifier: Intended Audience :: Developers
40
40
  Classifier: License :: OSI Approved :: BSD License
41
41
  Classifier: Programming Language :: Python
42
42
  Classifier: Programming Language :: Python :: 3
43
+ Classifier: Programming Language :: Python :: 3.10
44
+ Classifier: Programming Language :: Python :: 3.11
43
45
  Classifier: Programming Language :: Python :: 3.12
44
46
  Classifier: Programming Language :: Python :: 3.13
45
47
  Classifier: Topic :: Software Development
@@ -47,7 +49,7 @@ Classifier: Topic :: Software Development :: Libraries
47
49
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
48
50
  Classifier: Topic :: Utilities
49
51
  Classifier: Typing :: Typed
50
- Requires-Python: >=3.12
52
+ Requires-Python: >=3.10
51
53
  Description-Content-Type: text/markdown
52
54
  License-File: LICENSE
53
55
  Requires-Dist: python-chess>=1.11
@@ -63,7 +65,7 @@ MAJOR: 3
63
65
 
64
66
  MINOR: 2
65
67
 
66
- PATCH: 18
68
+ PATCH: 20
67
69
 
68
70
  If you need to catch up, you can see the full version history in the [CHANGELOG](https://github.com/Loepker-James/enforce-rules/blob/main/CHANGELOG.md).
69
71
 
@@ -7,7 +7,7 @@ MAJOR: 3
7
7
 
8
8
  MINOR: 2
9
9
 
10
- PATCH: 18
10
+ PATCH: 20
11
11
 
12
12
  If you need to catch up, you can see the full version history in the [CHANGELOG](https://github.com/Loepker-James/enforce-rules/blob/main/CHANGELOG.md).
13
13
 
@@ -1,9 +1,9 @@
1
1
  [project]
2
2
  name = "enforce-rules"
3
- version = "3.2.18"
3
+ version = "3.2.20"
4
4
  description = "Runtime rule validation for Python using dictionary-based constraints."
5
5
  readme = "README.md"
6
- requires-python = ">=3.12"
6
+ requires-python = ">=3.10"
7
7
  dependencies = [
8
8
  "python-chess>=1.11",
9
9
  "pydantic>=2",
@@ -20,6 +20,8 @@ classifiers = [
20
20
  "License :: OSI Approved :: BSD License",
21
21
  "Programming Language :: Python",
22
22
  "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
23
25
  "Programming Language :: Python :: 3.12",
24
26
  "Programming Language :: Python :: 3.13",
25
27
  "Topic :: Software Development",
@@ -1,4 +1,4 @@
1
- ffrom typing import Dict, Callable, Literal, TypeVar, TypedDict, TypeAlias
1
+ from typing import Annotated, Any, Callable, Literal, TypeVar, TypedDict, TypeAlias
2
2
  from collections.abc import Iterable, Sequence, Container
3
3
  import re
4
4
  from datetime import datetime
@@ -7,6 +7,9 @@ from pydantic import Field, validate_call
7
7
 
8
8
  Number: TypeAlias = int | float
9
9
  LengthType: TypeAlias = Annotated[int, Field(ge=0)]
10
+
11
+ _PIECE_NAMES = ("pawn", "knight", "bishop", "rook", "queen", "king")
12
+
10
13
  # -----------------------------
11
14
  # VALIDATOR FUNCTIONS (DEFINED FIRST)
12
15
  # -----------------------------
@@ -69,7 +72,8 @@ def _validate_no_nulls(value: Iterable, expected: bool) -> None:
69
72
 
70
73
  def _validate_sorted(value: Sequence, expected: bool) -> None:
71
74
  if expected:
72
- if value != sorted(value) and value != sorted(value, reverse=True):
75
+ items = list(value)
76
+ if items != sorted(items) and items != sorted(items, reverse=True):
73
77
  raise ValueError("List must be sorted increasing or decreasing")
74
78
 
75
79
 
@@ -115,6 +119,7 @@ def _validate_regex(value: str, pattern: str, flags: object) -> None:
115
119
  raise ValueError(f"Value '{value}' does not match regex '{pattern}'")
116
120
 
117
121
  T = TypeVar("T")
122
+
118
123
  def _validate_must_be_true(value: T, func: Callable[[T], bool]) -> None:
119
124
  if not func(value):
120
125
  raise ValueError("must_be_true rule failed")
@@ -125,17 +130,23 @@ def _validate_before_date(value: datetime, reference: datetime) -> None:
125
130
 
126
131
  def _validate_after_date(value: datetime, reference: datetime) -> None:
127
132
  if not value > reference:
128
- raise ValueError(f"{value} must be before {reference}.")
129
-
133
+ raise ValueError(f"{value} must be after {reference}.")
134
+
130
135
  def _validate_piece_color(value: Piece, color: bool) -> None:
131
136
  if value.color is not color:
132
- raise ValueError(f"{value}'s color is {'white' if value.color else 'black'} instead of {'white' if color else 'black'}.")
133
-
137
+ raise ValueError(
138
+ f"{value}'s color is {'white' if value.color else 'black'} "
139
+ f"instead of {'white' if color else 'black'}."
140
+ )
141
+
134
142
  def _validate_piece_type(value: Piece, piece_type: Literal[1, 2, 3, 4, 5, 6]) -> None:
135
143
  if value.piece_type != piece_type:
136
- raise ValueError(f"Value is not a {["pawn", "knight", "bishop", "rook", "queen", "king"][piece_type-1]}")
144
+ raise ValueError(f"Value is not a {_PIECE_NAMES[piece_type - 1]}")
137
145
 
138
- def _validate_chess_symbol(value: Piece, symbol: Literal["p", "n", "b", "r", "q", "k", "P", "N", "B", "R", "Q", "K"]) -> None:
146
+ def _validate_chess_symbol(
147
+ value: Piece,
148
+ symbol: Literal["p", "n", "b", "r", "q", "k", "P", "N", "B", "R", "Q", "K"],
149
+ ) -> None:
139
150
  if value.symbol() != symbol:
140
151
  raise ValueError(f"Value's symbol is not {symbol}")
141
152
 
@@ -146,13 +157,13 @@ def _validate_is_password(value: str, rule: bool) -> None:
146
157
  _validate_min_length(value, 8)
147
158
  except ValueError:
148
159
  raise ValueError("Password must be at least 8 characters.")
149
-
160
+
150
161
  if not any(char.isdigit() for char in value):
151
162
  raise ValueError("Password must have at least one digit.")
152
-
163
+
153
164
  if not any(char.isupper() for char in value):
154
165
  raise ValueError("Password must have at least one uppercase letter.")
155
-
166
+
156
167
  if not any(char.islower() for char in value):
157
168
  raise ValueError("Password must have at least one lowercase letter.")
158
169
 
@@ -162,10 +173,10 @@ def _validate_is_password(value: str, rule: bool) -> None:
162
173
  "[", "\\", "]", "^", "_", "`",
163
174
  "{", "|", "}", "~",
164
175
  }
165
-
176
+
166
177
  def is_symbol(char: str) -> bool:
167
- return char in symbols
168
-
178
+ return char in symbols
179
+
169
180
  if not any(is_symbol(char) for char in value):
170
181
  raise ValueError("Password must have at least one symbol.")
171
182
 
@@ -194,12 +205,13 @@ class ValidateDict(TypedDict, total=False):
194
205
  element_max: Number
195
206
  regex: str
196
207
  regex_flags: object
197
- must_be_true: Callable[[T], bool]
208
+ must_be_true: Callable[[Any], bool]
198
209
  before_date: datetime
199
210
  after_date: datetime
200
211
  piece_color: bool
201
212
  piece_type: Literal[1, 2, 3, 4, 5, 6]
202
213
  chess_symbol: Literal["p", "n", "b", "r", "q", "k", "P", "N", "B", "R", "Q", "K"]
214
+ is_password: bool
203
215
 
204
216
  def validate(value: T, rules: ValidateDict) -> T:
205
217
  # Do not mutate value
@@ -268,10 +280,10 @@ def validate(value: T, rules: ValidateDict) -> T:
268
280
  raise ValueError(f"Unknown rule: {key}")
269
281
 
270
282
  return value
271
-
283
+
272
284
  def is_valid(value: T, rules: ValidateDict) -> bool:
273
285
  try:
274
286
  validate(value, rules)
275
287
  return True
276
- except:
288
+ except Exception:
277
289
  return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: enforce-rules
3
- Version: 3.2.18
3
+ Version: 3.2.20
4
4
  Summary: Runtime rule validation for Python using dictionary-based constraints.
5
5
  Author: Jake Loepker, Microsoft Copilot (AI Assistant)
6
6
  License: BSD 3-Clause License
@@ -40,6 +40,8 @@ Classifier: Intended Audience :: Developers
40
40
  Classifier: License :: OSI Approved :: BSD License
41
41
  Classifier: Programming Language :: Python
42
42
  Classifier: Programming Language :: Python :: 3
43
+ Classifier: Programming Language :: Python :: 3.10
44
+ Classifier: Programming Language :: Python :: 3.11
43
45
  Classifier: Programming Language :: Python :: 3.12
44
46
  Classifier: Programming Language :: Python :: 3.13
45
47
  Classifier: Topic :: Software Development
@@ -47,7 +49,7 @@ Classifier: Topic :: Software Development :: Libraries
47
49
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
48
50
  Classifier: Topic :: Utilities
49
51
  Classifier: Typing :: Typed
50
- Requires-Python: >=3.12
52
+ Requires-Python: >=3.10
51
53
  Description-Content-Type: text/markdown
52
54
  License-File: LICENSE
53
55
  Requires-Dist: python-chess>=1.11
@@ -63,7 +65,7 @@ MAJOR: 3
63
65
 
64
66
  MINOR: 2
65
67
 
66
- PATCH: 18
68
+ PATCH: 20
67
69
 
68
70
  If you need to catch up, you can see the full version history in the [CHANGELOG](https://github.com/Loepker-James/enforce-rules/blob/main/CHANGELOG.md).
69
71
 
File without changes
File without changes