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.
- {enforce_rules-3.2.18/src/enforce_rules.egg-info → enforce_rules-3.2.20}/PKG-INFO +5 -3
- {enforce_rules-3.2.18 → enforce_rules-3.2.20}/README.md +1 -1
- {enforce_rules-3.2.18 → enforce_rules-3.2.20}/pyproject.toml +4 -2
- {enforce_rules-3.2.18 → enforce_rules-3.2.20}/src/enforce_rules/enforce_rules.py +29 -17
- {enforce_rules-3.2.18 → enforce_rules-3.2.20/src/enforce_rules.egg-info}/PKG-INFO +5 -3
- {enforce_rules-3.2.18 → enforce_rules-3.2.20}/LICENSE +0 -0
- {enforce_rules-3.2.18 → enforce_rules-3.2.20}/setup.cfg +0 -0
- {enforce_rules-3.2.18 → enforce_rules-3.2.20}/src/enforce_rules/__init__.py +0 -0
- {enforce_rules-3.2.18 → enforce_rules-3.2.20}/src/enforce_rules/py.typed +0 -0
- {enforce_rules-3.2.18 → enforce_rules-3.2.20}/src/enforce_rules.egg-info/SOURCES.txt +0 -0
- {enforce_rules-3.2.18 → enforce_rules-3.2.20}/src/enforce_rules.egg-info/dependency_links.txt +0 -0
- {enforce_rules-3.2.18 → enforce_rules-3.2.20}/src/enforce_rules.egg-info/requires.txt +0 -0
- {enforce_rules-3.2.18 → enforce_rules-3.2.20}/src/enforce_rules.egg-info/top_level.txt +0 -0
- {enforce_rules-3.2.18 → enforce_rules-3.2.20}/tests/test_enforce_rules.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: enforce-rules
|
|
3
|
-
Version: 3.2.
|
|
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.
|
|
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:
|
|
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
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "enforce-rules"
|
|
3
|
-
version = "3.2.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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 {[
|
|
144
|
+
raise ValueError(f"Value is not a {_PIECE_NAMES[piece_type - 1]}")
|
|
137
145
|
|
|
138
|
-
def _validate_chess_symbol(
|
|
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[[
|
|
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.
|
|
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.
|
|
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:
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{enforce_rules-3.2.18 → enforce_rules-3.2.20}/src/enforce_rules.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|