super-easy-validator-python 0.1.0__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.
- super_easy_validator_python/__init__.py +55 -0
- super_easy_validator_python/checks.py +525 -0
- super_easy_validator_python/codes.py +143 -0
- super_easy_validator_python/formats.py +316 -0
- super_easy_validator_python/paths.py +162 -0
- super_easy_validator_python/py.typed +0 -0
- super_easy_validator_python/rules.py +205 -0
- super_easy_validator_python/types.py +136 -0
- super_easy_validator_python/validator.py +685 -0
- super_easy_validator_python-0.1.0.dist-info/METADATA +280 -0
- super_easy_validator_python-0.1.0.dist-info/RECORD +14 -0
- super_easy_validator_python-0.1.0.dist-info/WHEEL +5 -0
- super_easy_validator_python-0.1.0.dist-info/licenses/LICENSE +21 -0
- super_easy_validator_python-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"""Stable error codes.
|
|
2
|
+
|
|
3
|
+
Message text is for humans and may be reworded between releases. Codes are
|
|
4
|
+
meant to be compared against, so they do not change.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
REQUIRED = "REQUIRED"
|
|
8
|
+
DATA_REQUIRED = "DATA_REQUIRED"
|
|
9
|
+
DATA_NOT_OBJECT = "DATA_NOT_OBJECT"
|
|
10
|
+
UNEXPECTED_FIELD = "UNEXPECTED_FIELD"
|
|
11
|
+
|
|
12
|
+
NOT_STRING = "NOT_STRING"
|
|
13
|
+
NOT_NUMBER = "NOT_NUMBER"
|
|
14
|
+
NOT_NUMERIC_STRING = "NOT_NUMERIC_STRING"
|
|
15
|
+
NOT_BOOLEAN = "NOT_BOOLEAN"
|
|
16
|
+
NOT_BOOLEAN_STRING = "NOT_BOOLEAN_STRING"
|
|
17
|
+
NOT_ARRAY = "NOT_ARRAY"
|
|
18
|
+
NOT_OBJECT = "NOT_OBJECT"
|
|
19
|
+
|
|
20
|
+
NOT_EMAIL = "NOT_EMAIL"
|
|
21
|
+
NOT_URL = "NOT_URL"
|
|
22
|
+
NOT_DOMAIN = "NOT_DOMAIN"
|
|
23
|
+
NOT_NAME = "NOT_NAME"
|
|
24
|
+
NOT_FULLNAME = "NOT_FULLNAME"
|
|
25
|
+
NOT_USERNAME = "NOT_USERNAME"
|
|
26
|
+
NOT_ALPHA = "NOT_ALPHA"
|
|
27
|
+
NOT_ALPHANUMERIC = "NOT_ALPHANUMERIC"
|
|
28
|
+
NOT_PHONE = "NOT_PHONE"
|
|
29
|
+
NOT_PHONECODE = "NOT_PHONECODE"
|
|
30
|
+
NOT_OBJECTID = "NOT_OBJECTID"
|
|
31
|
+
NOT_UUID = "NOT_UUID"
|
|
32
|
+
NOT_DATE = "NOT_DATE"
|
|
33
|
+
NOT_DATEONLY = "NOT_DATEONLY"
|
|
34
|
+
NOT_TIME = "NOT_TIME"
|
|
35
|
+
NOT_IP = "NOT_IP"
|
|
36
|
+
|
|
37
|
+
NOT_LOWERCASE = "NOT_LOWERCASE"
|
|
38
|
+
NOT_UPPERCASE = "NOT_UPPERCASE"
|
|
39
|
+
|
|
40
|
+
NOT_INTEGER = "NOT_INTEGER"
|
|
41
|
+
NOT_POSITIVE = "NOT_POSITIVE"
|
|
42
|
+
NOT_NEGATIVE = "NOT_NEGATIVE"
|
|
43
|
+
NOT_NATURAL = "NOT_NATURAL"
|
|
44
|
+
NOT_WHOLE = "NOT_WHOLE"
|
|
45
|
+
|
|
46
|
+
LENGTH_MISMATCH = "LENGTH_MISMATCH"
|
|
47
|
+
DIGITS_MISMATCH = "DIGITS_MISMATCH"
|
|
48
|
+
TOO_SHORT = "TOO_SHORT"
|
|
49
|
+
TOO_LONG = "TOO_LONG"
|
|
50
|
+
TOO_SMALL = "TOO_SMALL"
|
|
51
|
+
TOO_LARGE = "TOO_LARGE"
|
|
52
|
+
DATE_TOO_EARLY = "DATE_TOO_EARLY"
|
|
53
|
+
DATE_TOO_LATE = "DATE_TOO_LATE"
|
|
54
|
+
NOT_EQUAL = "NOT_EQUAL"
|
|
55
|
+
|
|
56
|
+
DECIMAL_SIZE_MISMATCH = "DECIMAL_SIZE_MISMATCH"
|
|
57
|
+
DECIMAL_TOO_FEW = "DECIMAL_TOO_FEW"
|
|
58
|
+
DECIMAL_TOO_MANY = "DECIMAL_TOO_MANY"
|
|
59
|
+
NOT_A_NUMBER = "NOT_A_NUMBER"
|
|
60
|
+
|
|
61
|
+
ENUM_MISMATCH = "ENUM_MISMATCH"
|
|
62
|
+
REGEX_MISMATCH = "REGEX_MISMATCH"
|
|
63
|
+
|
|
64
|
+
ATLEAST_NOT_MET = "ATLEAST_NOT_MET"
|
|
65
|
+
ATMOST_EXCEEDED = "ATMOST_EXCEEDED"
|
|
66
|
+
|
|
67
|
+
NO_BRANCH_MATCHED = "NO_BRANCH_MATCHED"
|
|
68
|
+
CUSTOM_RULE_FAILED = "CUSTOM_RULE_FAILED"
|
|
69
|
+
NO_CASE_MATCHED = "NO_CASE_MATCHED"
|
|
70
|
+
|
|
71
|
+
INVALID_RULE = "INVALID_RULE"
|
|
72
|
+
INTERNAL_ERROR = "INTERNAL_ERROR"
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class ErrorCodes:
|
|
76
|
+
"""Namespace for the codes, so `ErrorCodes.REQUIRED` reads naturally."""
|
|
77
|
+
|
|
78
|
+
REQUIRED = REQUIRED
|
|
79
|
+
DATA_REQUIRED = DATA_REQUIRED
|
|
80
|
+
DATA_NOT_OBJECT = DATA_NOT_OBJECT
|
|
81
|
+
UNEXPECTED_FIELD = UNEXPECTED_FIELD
|
|
82
|
+
|
|
83
|
+
NOT_STRING = NOT_STRING
|
|
84
|
+
NOT_NUMBER = NOT_NUMBER
|
|
85
|
+
NOT_NUMERIC_STRING = NOT_NUMERIC_STRING
|
|
86
|
+
NOT_BOOLEAN = NOT_BOOLEAN
|
|
87
|
+
NOT_BOOLEAN_STRING = NOT_BOOLEAN_STRING
|
|
88
|
+
NOT_ARRAY = NOT_ARRAY
|
|
89
|
+
NOT_OBJECT = NOT_OBJECT
|
|
90
|
+
|
|
91
|
+
NOT_EMAIL = NOT_EMAIL
|
|
92
|
+
NOT_URL = NOT_URL
|
|
93
|
+
NOT_DOMAIN = NOT_DOMAIN
|
|
94
|
+
NOT_NAME = NOT_NAME
|
|
95
|
+
NOT_FULLNAME = NOT_FULLNAME
|
|
96
|
+
NOT_USERNAME = NOT_USERNAME
|
|
97
|
+
NOT_ALPHA = NOT_ALPHA
|
|
98
|
+
NOT_ALPHANUMERIC = NOT_ALPHANUMERIC
|
|
99
|
+
NOT_PHONE = NOT_PHONE
|
|
100
|
+
NOT_PHONECODE = NOT_PHONECODE
|
|
101
|
+
NOT_OBJECTID = NOT_OBJECTID
|
|
102
|
+
NOT_UUID = NOT_UUID
|
|
103
|
+
NOT_DATE = NOT_DATE
|
|
104
|
+
NOT_DATEONLY = NOT_DATEONLY
|
|
105
|
+
NOT_TIME = NOT_TIME
|
|
106
|
+
NOT_IP = NOT_IP
|
|
107
|
+
|
|
108
|
+
NOT_LOWERCASE = NOT_LOWERCASE
|
|
109
|
+
NOT_UPPERCASE = NOT_UPPERCASE
|
|
110
|
+
|
|
111
|
+
NOT_INTEGER = NOT_INTEGER
|
|
112
|
+
NOT_POSITIVE = NOT_POSITIVE
|
|
113
|
+
NOT_NEGATIVE = NOT_NEGATIVE
|
|
114
|
+
NOT_NATURAL = NOT_NATURAL
|
|
115
|
+
NOT_WHOLE = NOT_WHOLE
|
|
116
|
+
|
|
117
|
+
LENGTH_MISMATCH = LENGTH_MISMATCH
|
|
118
|
+
DIGITS_MISMATCH = DIGITS_MISMATCH
|
|
119
|
+
TOO_SHORT = TOO_SHORT
|
|
120
|
+
TOO_LONG = TOO_LONG
|
|
121
|
+
TOO_SMALL = TOO_SMALL
|
|
122
|
+
TOO_LARGE = TOO_LARGE
|
|
123
|
+
DATE_TOO_EARLY = DATE_TOO_EARLY
|
|
124
|
+
DATE_TOO_LATE = DATE_TOO_LATE
|
|
125
|
+
NOT_EQUAL = NOT_EQUAL
|
|
126
|
+
|
|
127
|
+
DECIMAL_SIZE_MISMATCH = DECIMAL_SIZE_MISMATCH
|
|
128
|
+
DECIMAL_TOO_FEW = DECIMAL_TOO_FEW
|
|
129
|
+
DECIMAL_TOO_MANY = DECIMAL_TOO_MANY
|
|
130
|
+
NOT_A_NUMBER = NOT_A_NUMBER
|
|
131
|
+
|
|
132
|
+
ENUM_MISMATCH = ENUM_MISMATCH
|
|
133
|
+
REGEX_MISMATCH = REGEX_MISMATCH
|
|
134
|
+
|
|
135
|
+
ATLEAST_NOT_MET = ATLEAST_NOT_MET
|
|
136
|
+
ATMOST_EXCEEDED = ATMOST_EXCEEDED
|
|
137
|
+
|
|
138
|
+
NO_BRANCH_MATCHED = NO_BRANCH_MATCHED
|
|
139
|
+
CUSTOM_RULE_FAILED = CUSTOM_RULE_FAILED
|
|
140
|
+
NO_CASE_MATCHED = NO_CASE_MATCHED
|
|
141
|
+
|
|
142
|
+
INVALID_RULE = INVALID_RULE
|
|
143
|
+
INTERNAL_ERROR = INTERNAL_ERROR
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
"""Built-in format patterns.
|
|
2
|
+
|
|
3
|
+
Python's ``re`` has no ``\\p{L}`` / ``\\p{M}`` escapes, which the name and
|
|
4
|
+
fullname rules need in order to accept every script. The equivalent character
|
|
5
|
+
ranges are embedded below, derived from ``unicodedata`` categories, so the
|
|
6
|
+
package keeps its zero-dependency promise without paying a 0.12s Unicode scan
|
|
7
|
+
on every import.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import re
|
|
13
|
+
|
|
14
|
+
# Unicode categories L* (letters) and M* (marks), as code-point ranges.
|
|
15
|
+
_LETTER_RANGES: tuple[tuple[int, int], ...] = (
|
|
16
|
+
(0x00041, 0x0005a), (0x00061, 0x0007a), (0x000aa, 0x000aa), (0x000b5, 0x000b5), (0x000ba, 0x000ba), (0x000c0, 0x000d6),
|
|
17
|
+
(0x000d8, 0x000f6), (0x000f8, 0x002c1), (0x002c6, 0x002d1), (0x002e0, 0x002e4), (0x002ec, 0x002ec), (0x002ee, 0x002ee),
|
|
18
|
+
(0x00370, 0x00374), (0x00376, 0x00377), (0x0037a, 0x0037d), (0x0037f, 0x0037f), (0x00386, 0x00386), (0x00388, 0x0038a),
|
|
19
|
+
(0x0038c, 0x0038c), (0x0038e, 0x003a1), (0x003a3, 0x003f5), (0x003f7, 0x00481), (0x0048a, 0x0052f), (0x00531, 0x00556),
|
|
20
|
+
(0x00559, 0x00559), (0x00560, 0x00588), (0x005d0, 0x005ea), (0x005ef, 0x005f2), (0x00620, 0x0064a), (0x0066e, 0x0066f),
|
|
21
|
+
(0x00671, 0x006d3), (0x006d5, 0x006d5), (0x006e5, 0x006e6), (0x006ee, 0x006ef), (0x006fa, 0x006fc), (0x006ff, 0x006ff),
|
|
22
|
+
(0x00710, 0x00710), (0x00712, 0x0072f), (0x0074d, 0x007a5), (0x007b1, 0x007b1), (0x007ca, 0x007ea), (0x007f4, 0x007f5),
|
|
23
|
+
(0x007fa, 0x007fa), (0x00800, 0x00815), (0x0081a, 0x0081a), (0x00824, 0x00824), (0x00828, 0x00828), (0x00840, 0x00858),
|
|
24
|
+
(0x00860, 0x0086a), (0x00870, 0x00887), (0x00889, 0x0088e), (0x008a0, 0x008c9), (0x00904, 0x00939), (0x0093d, 0x0093d),
|
|
25
|
+
(0x00950, 0x00950), (0x00958, 0x00961), (0x00971, 0x00980), (0x00985, 0x0098c), (0x0098f, 0x00990), (0x00993, 0x009a8),
|
|
26
|
+
(0x009aa, 0x009b0), (0x009b2, 0x009b2), (0x009b6, 0x009b9), (0x009bd, 0x009bd), (0x009ce, 0x009ce), (0x009dc, 0x009dd),
|
|
27
|
+
(0x009df, 0x009e1), (0x009f0, 0x009f1), (0x009fc, 0x009fc), (0x00a05, 0x00a0a), (0x00a0f, 0x00a10), (0x00a13, 0x00a28),
|
|
28
|
+
(0x00a2a, 0x00a30), (0x00a32, 0x00a33), (0x00a35, 0x00a36), (0x00a38, 0x00a39), (0x00a59, 0x00a5c), (0x00a5e, 0x00a5e),
|
|
29
|
+
(0x00a72, 0x00a74), (0x00a85, 0x00a8d), (0x00a8f, 0x00a91), (0x00a93, 0x00aa8), (0x00aaa, 0x00ab0), (0x00ab2, 0x00ab3),
|
|
30
|
+
(0x00ab5, 0x00ab9), (0x00abd, 0x00abd), (0x00ad0, 0x00ad0), (0x00ae0, 0x00ae1), (0x00af9, 0x00af9), (0x00b05, 0x00b0c),
|
|
31
|
+
(0x00b0f, 0x00b10), (0x00b13, 0x00b28), (0x00b2a, 0x00b30), (0x00b32, 0x00b33), (0x00b35, 0x00b39), (0x00b3d, 0x00b3d),
|
|
32
|
+
(0x00b5c, 0x00b5d), (0x00b5f, 0x00b61), (0x00b71, 0x00b71), (0x00b83, 0x00b83), (0x00b85, 0x00b8a), (0x00b8e, 0x00b90),
|
|
33
|
+
(0x00b92, 0x00b95), (0x00b99, 0x00b9a), (0x00b9c, 0x00b9c), (0x00b9e, 0x00b9f), (0x00ba3, 0x00ba4), (0x00ba8, 0x00baa),
|
|
34
|
+
(0x00bae, 0x00bb9), (0x00bd0, 0x00bd0), (0x00c05, 0x00c0c), (0x00c0e, 0x00c10), (0x00c12, 0x00c28), (0x00c2a, 0x00c39),
|
|
35
|
+
(0x00c3d, 0x00c3d), (0x00c58, 0x00c5a), (0x00c5d, 0x00c5d), (0x00c60, 0x00c61), (0x00c80, 0x00c80), (0x00c85, 0x00c8c),
|
|
36
|
+
(0x00c8e, 0x00c90), (0x00c92, 0x00ca8), (0x00caa, 0x00cb3), (0x00cb5, 0x00cb9), (0x00cbd, 0x00cbd), (0x00cdd, 0x00cde),
|
|
37
|
+
(0x00ce0, 0x00ce1), (0x00cf1, 0x00cf2), (0x00d04, 0x00d0c), (0x00d0e, 0x00d10), (0x00d12, 0x00d3a), (0x00d3d, 0x00d3d),
|
|
38
|
+
(0x00d4e, 0x00d4e), (0x00d54, 0x00d56), (0x00d5f, 0x00d61), (0x00d7a, 0x00d7f), (0x00d85, 0x00d96), (0x00d9a, 0x00db1),
|
|
39
|
+
(0x00db3, 0x00dbb), (0x00dbd, 0x00dbd), (0x00dc0, 0x00dc6), (0x00e01, 0x00e30), (0x00e32, 0x00e33), (0x00e40, 0x00e46),
|
|
40
|
+
(0x00e81, 0x00e82), (0x00e84, 0x00e84), (0x00e86, 0x00e8a), (0x00e8c, 0x00ea3), (0x00ea5, 0x00ea5), (0x00ea7, 0x00eb0),
|
|
41
|
+
(0x00eb2, 0x00eb3), (0x00ebd, 0x00ebd), (0x00ec0, 0x00ec4), (0x00ec6, 0x00ec6), (0x00edc, 0x00edf), (0x00f00, 0x00f00),
|
|
42
|
+
(0x00f40, 0x00f47), (0x00f49, 0x00f6c), (0x00f88, 0x00f8c), (0x01000, 0x0102a), (0x0103f, 0x0103f), (0x01050, 0x01055),
|
|
43
|
+
(0x0105a, 0x0105d), (0x01061, 0x01061), (0x01065, 0x01066), (0x0106e, 0x01070), (0x01075, 0x01081), (0x0108e, 0x0108e),
|
|
44
|
+
(0x010a0, 0x010c5), (0x010c7, 0x010c7), (0x010cd, 0x010cd), (0x010d0, 0x010fa), (0x010fc, 0x01248), (0x0124a, 0x0124d),
|
|
45
|
+
(0x01250, 0x01256), (0x01258, 0x01258), (0x0125a, 0x0125d), (0x01260, 0x01288), (0x0128a, 0x0128d), (0x01290, 0x012b0),
|
|
46
|
+
(0x012b2, 0x012b5), (0x012b8, 0x012be), (0x012c0, 0x012c0), (0x012c2, 0x012c5), (0x012c8, 0x012d6), (0x012d8, 0x01310),
|
|
47
|
+
(0x01312, 0x01315), (0x01318, 0x0135a), (0x01380, 0x0138f), (0x013a0, 0x013f5), (0x013f8, 0x013fd), (0x01401, 0x0166c),
|
|
48
|
+
(0x0166f, 0x0167f), (0x01681, 0x0169a), (0x016a0, 0x016ea), (0x016f1, 0x016f8), (0x01700, 0x01711), (0x0171f, 0x01731),
|
|
49
|
+
(0x01740, 0x01751), (0x01760, 0x0176c), (0x0176e, 0x01770), (0x01780, 0x017b3), (0x017d7, 0x017d7), (0x017dc, 0x017dc),
|
|
50
|
+
(0x01820, 0x01878), (0x01880, 0x01884), (0x01887, 0x018a8), (0x018aa, 0x018aa), (0x018b0, 0x018f5), (0x01900, 0x0191e),
|
|
51
|
+
(0x01950, 0x0196d), (0x01970, 0x01974), (0x01980, 0x019ab), (0x019b0, 0x019c9), (0x01a00, 0x01a16), (0x01a20, 0x01a54),
|
|
52
|
+
(0x01aa7, 0x01aa7), (0x01b05, 0x01b33), (0x01b45, 0x01b4c), (0x01b83, 0x01ba0), (0x01bae, 0x01baf), (0x01bba, 0x01be5),
|
|
53
|
+
(0x01c00, 0x01c23), (0x01c4d, 0x01c4f), (0x01c5a, 0x01c7d), (0x01c80, 0x01c8a), (0x01c90, 0x01cba), (0x01cbd, 0x01cbf),
|
|
54
|
+
(0x01ce9, 0x01cec), (0x01cee, 0x01cf3), (0x01cf5, 0x01cf6), (0x01cfa, 0x01cfa), (0x01d00, 0x01dbf), (0x01e00, 0x01f15),
|
|
55
|
+
(0x01f18, 0x01f1d), (0x01f20, 0x01f45), (0x01f48, 0x01f4d), (0x01f50, 0x01f57), (0x01f59, 0x01f59), (0x01f5b, 0x01f5b),
|
|
56
|
+
(0x01f5d, 0x01f5d), (0x01f5f, 0x01f7d), (0x01f80, 0x01fb4), (0x01fb6, 0x01fbc), (0x01fbe, 0x01fbe), (0x01fc2, 0x01fc4),
|
|
57
|
+
(0x01fc6, 0x01fcc), (0x01fd0, 0x01fd3), (0x01fd6, 0x01fdb), (0x01fe0, 0x01fec), (0x01ff2, 0x01ff4), (0x01ff6, 0x01ffc),
|
|
58
|
+
(0x02071, 0x02071), (0x0207f, 0x0207f), (0x02090, 0x0209c), (0x02102, 0x02102), (0x02107, 0x02107), (0x0210a, 0x02113),
|
|
59
|
+
(0x02115, 0x02115), (0x02119, 0x0211d), (0x02124, 0x02124), (0x02126, 0x02126), (0x02128, 0x02128), (0x0212a, 0x0212d),
|
|
60
|
+
(0x0212f, 0x02139), (0x0213c, 0x0213f), (0x02145, 0x02149), (0x0214e, 0x0214e), (0x02183, 0x02184), (0x02c00, 0x02ce4),
|
|
61
|
+
(0x02ceb, 0x02cee), (0x02cf2, 0x02cf3), (0x02d00, 0x02d25), (0x02d27, 0x02d27), (0x02d2d, 0x02d2d), (0x02d30, 0x02d67),
|
|
62
|
+
(0x02d6f, 0x02d6f), (0x02d80, 0x02d96), (0x02da0, 0x02da6), (0x02da8, 0x02dae), (0x02db0, 0x02db6), (0x02db8, 0x02dbe),
|
|
63
|
+
(0x02dc0, 0x02dc6), (0x02dc8, 0x02dce), (0x02dd0, 0x02dd6), (0x02dd8, 0x02dde), (0x02e2f, 0x02e2f), (0x03005, 0x03006),
|
|
64
|
+
(0x03031, 0x03035), (0x0303b, 0x0303c), (0x03041, 0x03096), (0x0309d, 0x0309f), (0x030a1, 0x030fa), (0x030fc, 0x030ff),
|
|
65
|
+
(0x03105, 0x0312f), (0x03131, 0x0318e), (0x031a0, 0x031bf), (0x031f0, 0x031ff), (0x03400, 0x04dbf), (0x04e00, 0x0a48c),
|
|
66
|
+
(0x0a4d0, 0x0a4fd), (0x0a500, 0x0a60c), (0x0a610, 0x0a61f), (0x0a62a, 0x0a62b), (0x0a640, 0x0a66e), (0x0a67f, 0x0a69d),
|
|
67
|
+
(0x0a6a0, 0x0a6e5), (0x0a717, 0x0a71f), (0x0a722, 0x0a788), (0x0a78b, 0x0a7cd), (0x0a7d0, 0x0a7d1), (0x0a7d3, 0x0a7d3),
|
|
68
|
+
(0x0a7d5, 0x0a7dc), (0x0a7f2, 0x0a801), (0x0a803, 0x0a805), (0x0a807, 0x0a80a), (0x0a80c, 0x0a822), (0x0a840, 0x0a873),
|
|
69
|
+
(0x0a882, 0x0a8b3), (0x0a8f2, 0x0a8f7), (0x0a8fb, 0x0a8fb), (0x0a8fd, 0x0a8fe), (0x0a90a, 0x0a925), (0x0a930, 0x0a946),
|
|
70
|
+
(0x0a960, 0x0a97c), (0x0a984, 0x0a9b2), (0x0a9cf, 0x0a9cf), (0x0a9e0, 0x0a9e4), (0x0a9e6, 0x0a9ef), (0x0a9fa, 0x0a9fe),
|
|
71
|
+
(0x0aa00, 0x0aa28), (0x0aa40, 0x0aa42), (0x0aa44, 0x0aa4b), (0x0aa60, 0x0aa76), (0x0aa7a, 0x0aa7a), (0x0aa7e, 0x0aaaf),
|
|
72
|
+
(0x0aab1, 0x0aab1), (0x0aab5, 0x0aab6), (0x0aab9, 0x0aabd), (0x0aac0, 0x0aac0), (0x0aac2, 0x0aac2), (0x0aadb, 0x0aadd),
|
|
73
|
+
(0x0aae0, 0x0aaea), (0x0aaf2, 0x0aaf4), (0x0ab01, 0x0ab06), (0x0ab09, 0x0ab0e), (0x0ab11, 0x0ab16), (0x0ab20, 0x0ab26),
|
|
74
|
+
(0x0ab28, 0x0ab2e), (0x0ab30, 0x0ab5a), (0x0ab5c, 0x0ab69), (0x0ab70, 0x0abe2), (0x0ac00, 0x0d7a3), (0x0d7b0, 0x0d7c6),
|
|
75
|
+
(0x0d7cb, 0x0d7fb), (0x0f900, 0x0fa6d), (0x0fa70, 0x0fad9), (0x0fb00, 0x0fb06), (0x0fb13, 0x0fb17), (0x0fb1d, 0x0fb1d),
|
|
76
|
+
(0x0fb1f, 0x0fb28), (0x0fb2a, 0x0fb36), (0x0fb38, 0x0fb3c), (0x0fb3e, 0x0fb3e), (0x0fb40, 0x0fb41), (0x0fb43, 0x0fb44),
|
|
77
|
+
(0x0fb46, 0x0fbb1), (0x0fbd3, 0x0fd3d), (0x0fd50, 0x0fd8f), (0x0fd92, 0x0fdc7), (0x0fdf0, 0x0fdfb), (0x0fe70, 0x0fe74),
|
|
78
|
+
(0x0fe76, 0x0fefc), (0x0ff21, 0x0ff3a), (0x0ff41, 0x0ff5a), (0x0ff66, 0x0ffbe), (0x0ffc2, 0x0ffc7), (0x0ffca, 0x0ffcf),
|
|
79
|
+
(0x0ffd2, 0x0ffd7), (0x0ffda, 0x0ffdc), (0x10000, 0x1000b), (0x1000d, 0x10026), (0x10028, 0x1003a), (0x1003c, 0x1003d),
|
|
80
|
+
(0x1003f, 0x1004d), (0x10050, 0x1005d), (0x10080, 0x100fa), (0x10280, 0x1029c), (0x102a0, 0x102d0), (0x10300, 0x1031f),
|
|
81
|
+
(0x1032d, 0x10340), (0x10342, 0x10349), (0x10350, 0x10375), (0x10380, 0x1039d), (0x103a0, 0x103c3), (0x103c8, 0x103cf),
|
|
82
|
+
(0x10400, 0x1049d), (0x104b0, 0x104d3), (0x104d8, 0x104fb), (0x10500, 0x10527), (0x10530, 0x10563), (0x10570, 0x1057a),
|
|
83
|
+
(0x1057c, 0x1058a), (0x1058c, 0x10592), (0x10594, 0x10595), (0x10597, 0x105a1), (0x105a3, 0x105b1), (0x105b3, 0x105b9),
|
|
84
|
+
(0x105bb, 0x105bc), (0x105c0, 0x105f3), (0x10600, 0x10736), (0x10740, 0x10755), (0x10760, 0x10767), (0x10780, 0x10785),
|
|
85
|
+
(0x10787, 0x107b0), (0x107b2, 0x107ba), (0x10800, 0x10805), (0x10808, 0x10808), (0x1080a, 0x10835), (0x10837, 0x10838),
|
|
86
|
+
(0x1083c, 0x1083c), (0x1083f, 0x10855), (0x10860, 0x10876), (0x10880, 0x1089e), (0x108e0, 0x108f2), (0x108f4, 0x108f5),
|
|
87
|
+
(0x10900, 0x10915), (0x10920, 0x10939), (0x10980, 0x109b7), (0x109be, 0x109bf), (0x10a00, 0x10a00), (0x10a10, 0x10a13),
|
|
88
|
+
(0x10a15, 0x10a17), (0x10a19, 0x10a35), (0x10a60, 0x10a7c), (0x10a80, 0x10a9c), (0x10ac0, 0x10ac7), (0x10ac9, 0x10ae4),
|
|
89
|
+
(0x10b00, 0x10b35), (0x10b40, 0x10b55), (0x10b60, 0x10b72), (0x10b80, 0x10b91), (0x10c00, 0x10c48), (0x10c80, 0x10cb2),
|
|
90
|
+
(0x10cc0, 0x10cf2), (0x10d00, 0x10d23), (0x10d4a, 0x10d65), (0x10d6f, 0x10d85), (0x10e80, 0x10ea9), (0x10eb0, 0x10eb1),
|
|
91
|
+
(0x10ec2, 0x10ec4), (0x10f00, 0x10f1c), (0x10f27, 0x10f27), (0x10f30, 0x10f45), (0x10f70, 0x10f81), (0x10fb0, 0x10fc4),
|
|
92
|
+
(0x10fe0, 0x10ff6), (0x11003, 0x11037), (0x11071, 0x11072), (0x11075, 0x11075), (0x11083, 0x110af), (0x110d0, 0x110e8),
|
|
93
|
+
(0x11103, 0x11126), (0x11144, 0x11144), (0x11147, 0x11147), (0x11150, 0x11172), (0x11176, 0x11176), (0x11183, 0x111b2),
|
|
94
|
+
(0x111c1, 0x111c4), (0x111da, 0x111da), (0x111dc, 0x111dc), (0x11200, 0x11211), (0x11213, 0x1122b), (0x1123f, 0x11240),
|
|
95
|
+
(0x11280, 0x11286), (0x11288, 0x11288), (0x1128a, 0x1128d), (0x1128f, 0x1129d), (0x1129f, 0x112a8), (0x112b0, 0x112de),
|
|
96
|
+
(0x11305, 0x1130c), (0x1130f, 0x11310), (0x11313, 0x11328), (0x1132a, 0x11330), (0x11332, 0x11333), (0x11335, 0x11339),
|
|
97
|
+
(0x1133d, 0x1133d), (0x11350, 0x11350), (0x1135d, 0x11361), (0x11380, 0x11389), (0x1138b, 0x1138b), (0x1138e, 0x1138e),
|
|
98
|
+
(0x11390, 0x113b5), (0x113b7, 0x113b7), (0x113d1, 0x113d1), (0x113d3, 0x113d3), (0x11400, 0x11434), (0x11447, 0x1144a),
|
|
99
|
+
(0x1145f, 0x11461), (0x11480, 0x114af), (0x114c4, 0x114c5), (0x114c7, 0x114c7), (0x11580, 0x115ae), (0x115d8, 0x115db),
|
|
100
|
+
(0x11600, 0x1162f), (0x11644, 0x11644), (0x11680, 0x116aa), (0x116b8, 0x116b8), (0x11700, 0x1171a), (0x11740, 0x11746),
|
|
101
|
+
(0x11800, 0x1182b), (0x118a0, 0x118df), (0x118ff, 0x11906), (0x11909, 0x11909), (0x1190c, 0x11913), (0x11915, 0x11916),
|
|
102
|
+
(0x11918, 0x1192f), (0x1193f, 0x1193f), (0x11941, 0x11941), (0x119a0, 0x119a7), (0x119aa, 0x119d0), (0x119e1, 0x119e1),
|
|
103
|
+
(0x119e3, 0x119e3), (0x11a00, 0x11a00), (0x11a0b, 0x11a32), (0x11a3a, 0x11a3a), (0x11a50, 0x11a50), (0x11a5c, 0x11a89),
|
|
104
|
+
(0x11a9d, 0x11a9d), (0x11ab0, 0x11af8), (0x11bc0, 0x11be0), (0x11c00, 0x11c08), (0x11c0a, 0x11c2e), (0x11c40, 0x11c40),
|
|
105
|
+
(0x11c72, 0x11c8f), (0x11d00, 0x11d06), (0x11d08, 0x11d09), (0x11d0b, 0x11d30), (0x11d46, 0x11d46), (0x11d60, 0x11d65),
|
|
106
|
+
(0x11d67, 0x11d68), (0x11d6a, 0x11d89), (0x11d98, 0x11d98), (0x11ee0, 0x11ef2), (0x11f02, 0x11f02), (0x11f04, 0x11f10),
|
|
107
|
+
(0x11f12, 0x11f33), (0x11fb0, 0x11fb0), (0x12000, 0x12399), (0x12480, 0x12543), (0x12f90, 0x12ff0), (0x13000, 0x1342f),
|
|
108
|
+
(0x13441, 0x13446), (0x13460, 0x143fa), (0x14400, 0x14646), (0x16100, 0x1611d), (0x16800, 0x16a38), (0x16a40, 0x16a5e),
|
|
109
|
+
(0x16a70, 0x16abe), (0x16ad0, 0x16aed), (0x16b00, 0x16b2f), (0x16b40, 0x16b43), (0x16b63, 0x16b77), (0x16b7d, 0x16b8f),
|
|
110
|
+
(0x16d40, 0x16d6c), (0x16e40, 0x16e7f), (0x16f00, 0x16f4a), (0x16f50, 0x16f50), (0x16f93, 0x16f9f), (0x16fe0, 0x16fe1),
|
|
111
|
+
(0x16fe3, 0x16fe3), (0x17000, 0x187f7), (0x18800, 0x18cd5), (0x18cff, 0x18d08), (0x1aff0, 0x1aff3), (0x1aff5, 0x1affb),
|
|
112
|
+
(0x1affd, 0x1affe), (0x1b000, 0x1b122), (0x1b132, 0x1b132), (0x1b150, 0x1b152), (0x1b155, 0x1b155), (0x1b164, 0x1b167),
|
|
113
|
+
(0x1b170, 0x1b2fb), (0x1bc00, 0x1bc6a), (0x1bc70, 0x1bc7c), (0x1bc80, 0x1bc88), (0x1bc90, 0x1bc99), (0x1d400, 0x1d454),
|
|
114
|
+
(0x1d456, 0x1d49c), (0x1d49e, 0x1d49f), (0x1d4a2, 0x1d4a2), (0x1d4a5, 0x1d4a6), (0x1d4a9, 0x1d4ac), (0x1d4ae, 0x1d4b9),
|
|
115
|
+
(0x1d4bb, 0x1d4bb), (0x1d4bd, 0x1d4c3), (0x1d4c5, 0x1d505), (0x1d507, 0x1d50a), (0x1d50d, 0x1d514), (0x1d516, 0x1d51c),
|
|
116
|
+
(0x1d51e, 0x1d539), (0x1d53b, 0x1d53e), (0x1d540, 0x1d544), (0x1d546, 0x1d546), (0x1d54a, 0x1d550), (0x1d552, 0x1d6a5),
|
|
117
|
+
(0x1d6a8, 0x1d6c0), (0x1d6c2, 0x1d6da), (0x1d6dc, 0x1d6fa), (0x1d6fc, 0x1d714), (0x1d716, 0x1d734), (0x1d736, 0x1d74e),
|
|
118
|
+
(0x1d750, 0x1d76e), (0x1d770, 0x1d788), (0x1d78a, 0x1d7a8), (0x1d7aa, 0x1d7c2), (0x1d7c4, 0x1d7cb), (0x1df00, 0x1df1e),
|
|
119
|
+
(0x1df25, 0x1df2a), (0x1e030, 0x1e06d), (0x1e100, 0x1e12c), (0x1e137, 0x1e13d), (0x1e14e, 0x1e14e), (0x1e290, 0x1e2ad),
|
|
120
|
+
(0x1e2c0, 0x1e2eb), (0x1e4d0, 0x1e4eb), (0x1e5d0, 0x1e5ed), (0x1e5f0, 0x1e5f0), (0x1e7e0, 0x1e7e6), (0x1e7e8, 0x1e7eb),
|
|
121
|
+
(0x1e7ed, 0x1e7ee), (0x1e7f0, 0x1e7fe), (0x1e800, 0x1e8c4), (0x1e900, 0x1e943), (0x1e94b, 0x1e94b), (0x1ee00, 0x1ee03),
|
|
122
|
+
(0x1ee05, 0x1ee1f), (0x1ee21, 0x1ee22), (0x1ee24, 0x1ee24), (0x1ee27, 0x1ee27), (0x1ee29, 0x1ee32), (0x1ee34, 0x1ee37),
|
|
123
|
+
(0x1ee39, 0x1ee39), (0x1ee3b, 0x1ee3b), (0x1ee42, 0x1ee42), (0x1ee47, 0x1ee47), (0x1ee49, 0x1ee49), (0x1ee4b, 0x1ee4b),
|
|
124
|
+
(0x1ee4d, 0x1ee4f), (0x1ee51, 0x1ee52), (0x1ee54, 0x1ee54), (0x1ee57, 0x1ee57), (0x1ee59, 0x1ee59), (0x1ee5b, 0x1ee5b),
|
|
125
|
+
(0x1ee5d, 0x1ee5d), (0x1ee5f, 0x1ee5f), (0x1ee61, 0x1ee62), (0x1ee64, 0x1ee64), (0x1ee67, 0x1ee6a), (0x1ee6c, 0x1ee72),
|
|
126
|
+
(0x1ee74, 0x1ee77), (0x1ee79, 0x1ee7c), (0x1ee7e, 0x1ee7e), (0x1ee80, 0x1ee89), (0x1ee8b, 0x1ee9b), (0x1eea1, 0x1eea3),
|
|
127
|
+
(0x1eea5, 0x1eea9), (0x1eeab, 0x1eebb), (0x20000, 0x2a6df), (0x2a700, 0x2b739), (0x2b740, 0x2b81d), (0x2b820, 0x2cea1),
|
|
128
|
+
(0x2ceb0, 0x2ebe0), (0x2ebf0, 0x2ee5d), (0x2f800, 0x2fa1d), (0x30000, 0x3134a), (0x31350, 0x323af),
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
_MARK_RANGES: tuple[tuple[int, int], ...] = (
|
|
132
|
+
(0x00300, 0x0036f), (0x00483, 0x00489), (0x00591, 0x005bd), (0x005bf, 0x005bf), (0x005c1, 0x005c2), (0x005c4, 0x005c5),
|
|
133
|
+
(0x005c7, 0x005c7), (0x00610, 0x0061a), (0x0064b, 0x0065f), (0x00670, 0x00670), (0x006d6, 0x006dc), (0x006df, 0x006e4),
|
|
134
|
+
(0x006e7, 0x006e8), (0x006ea, 0x006ed), (0x00711, 0x00711), (0x00730, 0x0074a), (0x007a6, 0x007b0), (0x007eb, 0x007f3),
|
|
135
|
+
(0x007fd, 0x007fd), (0x00816, 0x00819), (0x0081b, 0x00823), (0x00825, 0x00827), (0x00829, 0x0082d), (0x00859, 0x0085b),
|
|
136
|
+
(0x00897, 0x0089f), (0x008ca, 0x008e1), (0x008e3, 0x00903), (0x0093a, 0x0093c), (0x0093e, 0x0094f), (0x00951, 0x00957),
|
|
137
|
+
(0x00962, 0x00963), (0x00981, 0x00983), (0x009bc, 0x009bc), (0x009be, 0x009c4), (0x009c7, 0x009c8), (0x009cb, 0x009cd),
|
|
138
|
+
(0x009d7, 0x009d7), (0x009e2, 0x009e3), (0x009fe, 0x009fe), (0x00a01, 0x00a03), (0x00a3c, 0x00a3c), (0x00a3e, 0x00a42),
|
|
139
|
+
(0x00a47, 0x00a48), (0x00a4b, 0x00a4d), (0x00a51, 0x00a51), (0x00a70, 0x00a71), (0x00a75, 0x00a75), (0x00a81, 0x00a83),
|
|
140
|
+
(0x00abc, 0x00abc), (0x00abe, 0x00ac5), (0x00ac7, 0x00ac9), (0x00acb, 0x00acd), (0x00ae2, 0x00ae3), (0x00afa, 0x00aff),
|
|
141
|
+
(0x00b01, 0x00b03), (0x00b3c, 0x00b3c), (0x00b3e, 0x00b44), (0x00b47, 0x00b48), (0x00b4b, 0x00b4d), (0x00b55, 0x00b57),
|
|
142
|
+
(0x00b62, 0x00b63), (0x00b82, 0x00b82), (0x00bbe, 0x00bc2), (0x00bc6, 0x00bc8), (0x00bca, 0x00bcd), (0x00bd7, 0x00bd7),
|
|
143
|
+
(0x00c00, 0x00c04), (0x00c3c, 0x00c3c), (0x00c3e, 0x00c44), (0x00c46, 0x00c48), (0x00c4a, 0x00c4d), (0x00c55, 0x00c56),
|
|
144
|
+
(0x00c62, 0x00c63), (0x00c81, 0x00c83), (0x00cbc, 0x00cbc), (0x00cbe, 0x00cc4), (0x00cc6, 0x00cc8), (0x00cca, 0x00ccd),
|
|
145
|
+
(0x00cd5, 0x00cd6), (0x00ce2, 0x00ce3), (0x00cf3, 0x00cf3), (0x00d00, 0x00d03), (0x00d3b, 0x00d3c), (0x00d3e, 0x00d44),
|
|
146
|
+
(0x00d46, 0x00d48), (0x00d4a, 0x00d4d), (0x00d57, 0x00d57), (0x00d62, 0x00d63), (0x00d81, 0x00d83), (0x00dca, 0x00dca),
|
|
147
|
+
(0x00dcf, 0x00dd4), (0x00dd6, 0x00dd6), (0x00dd8, 0x00ddf), (0x00df2, 0x00df3), (0x00e31, 0x00e31), (0x00e34, 0x00e3a),
|
|
148
|
+
(0x00e47, 0x00e4e), (0x00eb1, 0x00eb1), (0x00eb4, 0x00ebc), (0x00ec8, 0x00ece), (0x00f18, 0x00f19), (0x00f35, 0x00f35),
|
|
149
|
+
(0x00f37, 0x00f37), (0x00f39, 0x00f39), (0x00f3e, 0x00f3f), (0x00f71, 0x00f84), (0x00f86, 0x00f87), (0x00f8d, 0x00f97),
|
|
150
|
+
(0x00f99, 0x00fbc), (0x00fc6, 0x00fc6), (0x0102b, 0x0103e), (0x01056, 0x01059), (0x0105e, 0x01060), (0x01062, 0x01064),
|
|
151
|
+
(0x01067, 0x0106d), (0x01071, 0x01074), (0x01082, 0x0108d), (0x0108f, 0x0108f), (0x0109a, 0x0109d), (0x0135d, 0x0135f),
|
|
152
|
+
(0x01712, 0x01715), (0x01732, 0x01734), (0x01752, 0x01753), (0x01772, 0x01773), (0x017b4, 0x017d3), (0x017dd, 0x017dd),
|
|
153
|
+
(0x0180b, 0x0180d), (0x0180f, 0x0180f), (0x01885, 0x01886), (0x018a9, 0x018a9), (0x01920, 0x0192b), (0x01930, 0x0193b),
|
|
154
|
+
(0x01a17, 0x01a1b), (0x01a55, 0x01a5e), (0x01a60, 0x01a7c), (0x01a7f, 0x01a7f), (0x01ab0, 0x01ace), (0x01b00, 0x01b04),
|
|
155
|
+
(0x01b34, 0x01b44), (0x01b6b, 0x01b73), (0x01b80, 0x01b82), (0x01ba1, 0x01bad), (0x01be6, 0x01bf3), (0x01c24, 0x01c37),
|
|
156
|
+
(0x01cd0, 0x01cd2), (0x01cd4, 0x01ce8), (0x01ced, 0x01ced), (0x01cf4, 0x01cf4), (0x01cf7, 0x01cf9), (0x01dc0, 0x01dff),
|
|
157
|
+
(0x020d0, 0x020f0), (0x02cef, 0x02cf1), (0x02d7f, 0x02d7f), (0x02de0, 0x02dff), (0x0302a, 0x0302f), (0x03099, 0x0309a),
|
|
158
|
+
(0x0a66f, 0x0a672), (0x0a674, 0x0a67d), (0x0a69e, 0x0a69f), (0x0a6f0, 0x0a6f1), (0x0a802, 0x0a802), (0x0a806, 0x0a806),
|
|
159
|
+
(0x0a80b, 0x0a80b), (0x0a823, 0x0a827), (0x0a82c, 0x0a82c), (0x0a880, 0x0a881), (0x0a8b4, 0x0a8c5), (0x0a8e0, 0x0a8f1),
|
|
160
|
+
(0x0a8ff, 0x0a8ff), (0x0a926, 0x0a92d), (0x0a947, 0x0a953), (0x0a980, 0x0a983), (0x0a9b3, 0x0a9c0), (0x0a9e5, 0x0a9e5),
|
|
161
|
+
(0x0aa29, 0x0aa36), (0x0aa43, 0x0aa43), (0x0aa4c, 0x0aa4d), (0x0aa7b, 0x0aa7d), (0x0aab0, 0x0aab0), (0x0aab2, 0x0aab4),
|
|
162
|
+
(0x0aab7, 0x0aab8), (0x0aabe, 0x0aabf), (0x0aac1, 0x0aac1), (0x0aaeb, 0x0aaef), (0x0aaf5, 0x0aaf6), (0x0abe3, 0x0abea),
|
|
163
|
+
(0x0abec, 0x0abed), (0x0fb1e, 0x0fb1e), (0x0fe00, 0x0fe0f), (0x0fe20, 0x0fe2f), (0x101fd, 0x101fd), (0x102e0, 0x102e0),
|
|
164
|
+
(0x10376, 0x1037a), (0x10a01, 0x10a03), (0x10a05, 0x10a06), (0x10a0c, 0x10a0f), (0x10a38, 0x10a3a), (0x10a3f, 0x10a3f),
|
|
165
|
+
(0x10ae5, 0x10ae6), (0x10d24, 0x10d27), (0x10d69, 0x10d6d), (0x10eab, 0x10eac), (0x10efc, 0x10eff), (0x10f46, 0x10f50),
|
|
166
|
+
(0x10f82, 0x10f85), (0x11000, 0x11002), (0x11038, 0x11046), (0x11070, 0x11070), (0x11073, 0x11074), (0x1107f, 0x11082),
|
|
167
|
+
(0x110b0, 0x110ba), (0x110c2, 0x110c2), (0x11100, 0x11102), (0x11127, 0x11134), (0x11145, 0x11146), (0x11173, 0x11173),
|
|
168
|
+
(0x11180, 0x11182), (0x111b3, 0x111c0), (0x111c9, 0x111cc), (0x111ce, 0x111cf), (0x1122c, 0x11237), (0x1123e, 0x1123e),
|
|
169
|
+
(0x11241, 0x11241), (0x112df, 0x112ea), (0x11300, 0x11303), (0x1133b, 0x1133c), (0x1133e, 0x11344), (0x11347, 0x11348),
|
|
170
|
+
(0x1134b, 0x1134d), (0x11357, 0x11357), (0x11362, 0x11363), (0x11366, 0x1136c), (0x11370, 0x11374), (0x113b8, 0x113c0),
|
|
171
|
+
(0x113c2, 0x113c2), (0x113c5, 0x113c5), (0x113c7, 0x113ca), (0x113cc, 0x113d0), (0x113d2, 0x113d2), (0x113e1, 0x113e2),
|
|
172
|
+
(0x11435, 0x11446), (0x1145e, 0x1145e), (0x114b0, 0x114c3), (0x115af, 0x115b5), (0x115b8, 0x115c0), (0x115dc, 0x115dd),
|
|
173
|
+
(0x11630, 0x11640), (0x116ab, 0x116b7), (0x1171d, 0x1172b), (0x1182c, 0x1183a), (0x11930, 0x11935), (0x11937, 0x11938),
|
|
174
|
+
(0x1193b, 0x1193e), (0x11940, 0x11940), (0x11942, 0x11943), (0x119d1, 0x119d7), (0x119da, 0x119e0), (0x119e4, 0x119e4),
|
|
175
|
+
(0x11a01, 0x11a0a), (0x11a33, 0x11a39), (0x11a3b, 0x11a3e), (0x11a47, 0x11a47), (0x11a51, 0x11a5b), (0x11a8a, 0x11a99),
|
|
176
|
+
(0x11c2f, 0x11c36), (0x11c38, 0x11c3f), (0x11c92, 0x11ca7), (0x11ca9, 0x11cb6), (0x11d31, 0x11d36), (0x11d3a, 0x11d3a),
|
|
177
|
+
(0x11d3c, 0x11d3d), (0x11d3f, 0x11d45), (0x11d47, 0x11d47), (0x11d8a, 0x11d8e), (0x11d90, 0x11d91), (0x11d93, 0x11d97),
|
|
178
|
+
(0x11ef3, 0x11ef6), (0x11f00, 0x11f01), (0x11f03, 0x11f03), (0x11f34, 0x11f3a), (0x11f3e, 0x11f42), (0x11f5a, 0x11f5a),
|
|
179
|
+
(0x13440, 0x13440), (0x13447, 0x13455), (0x1611e, 0x1612f), (0x16af0, 0x16af4), (0x16b30, 0x16b36), (0x16f4f, 0x16f4f),
|
|
180
|
+
(0x16f51, 0x16f87), (0x16f8f, 0x16f92), (0x16fe4, 0x16fe4), (0x16ff0, 0x16ff1), (0x1bc9d, 0x1bc9e), (0x1cf00, 0x1cf2d),
|
|
181
|
+
(0x1cf30, 0x1cf46), (0x1d165, 0x1d169), (0x1d16d, 0x1d172), (0x1d17b, 0x1d182), (0x1d185, 0x1d18b), (0x1d1aa, 0x1d1ad),
|
|
182
|
+
(0x1d242, 0x1d244), (0x1da00, 0x1da36), (0x1da3b, 0x1da6c), (0x1da75, 0x1da75), (0x1da84, 0x1da84), (0x1da9b, 0x1da9f),
|
|
183
|
+
(0x1daa1, 0x1daaf), (0x1e000, 0x1e006), (0x1e008, 0x1e018), (0x1e01b, 0x1e021), (0x1e023, 0x1e024), (0x1e026, 0x1e02a),
|
|
184
|
+
(0x1e08f, 0x1e08f), (0x1e130, 0x1e136), (0x1e2ae, 0x1e2ae), (0x1e2ec, 0x1e2ef), (0x1e4ec, 0x1e4ef), (0x1e5ee, 0x1e5ef),
|
|
185
|
+
(0x1e8d0, 0x1e8d6), (0x1e944, 0x1e94a), (0xe0100, 0xe01ef),
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def _char_class(ranges: tuple[tuple[int, int], ...]) -> str:
|
|
190
|
+
parts = []
|
|
191
|
+
for lo, hi in ranges:
|
|
192
|
+
parts.append(f"\\U{lo:08x}" if lo == hi else f"\\U{lo:08x}-\\U{hi:08x}")
|
|
193
|
+
return "".join(parts)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
_L = _char_class(_LETTER_RANGES)
|
|
197
|
+
_M = _char_class(_MARK_RANGES)
|
|
198
|
+
|
|
199
|
+
#: One name word: a letter, then letters or combining marks, optional period.
|
|
200
|
+
_WORD = f"[{_L}][{_L}{_M}]*\\.?"
|
|
201
|
+
|
|
202
|
+
RE_EMAIL = re.compile(
|
|
203
|
+
r"^[A-Z0-9_'%=+!`#~$*?^{}&|-]+([.][A-Z0-9_'%=+!`#~$*?^{}&|-]+)*"
|
|
204
|
+
r"@[A-Z0-9-]+(\.[A-Z0-9-]+)+$",
|
|
205
|
+
re.IGNORECASE,
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
RE_URL = re.compile(
|
|
209
|
+
r"^(https?://(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}"
|
|
210
|
+
r"|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}"
|
|
211
|
+
r"|https?://(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}"
|
|
212
|
+
r"|www\.[a-zA-Z0-9]+\.[^\s]{2,})$"
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
RE_DOMAIN = re.compile(
|
|
216
|
+
r"^[a-zA-Z0-9][a-zA-Z0-9-_]{0,61}[a-zA-Z0-9]{0,1}"
|
|
217
|
+
r"\.([a-zA-Z]{1,6}|[a-zA-Z0-9-]{1,30}\.[a-zA-Z]{2,3})$"
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
RE_NAME = re.compile(f"^{_WORD}(?:[ '\u2019\\-]{_WORD})*$")
|
|
221
|
+
|
|
222
|
+
RE_FULLNAME = re.compile(
|
|
223
|
+
f"^{_WORD}(?:['\u2019\\-]{_WORD})*(?: {_WORD}(?:['\u2019\\-]{_WORD})*)+$"
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
RE_USERNAME = re.compile(r"^[^\W_](?!.*?[._]{2})[\w.]{6,18}[^\W_]$")
|
|
227
|
+
|
|
228
|
+
RE_ALPHA = re.compile(r"^[A-Za-z]{1,}$")
|
|
229
|
+
|
|
230
|
+
RE_ALPHANUMERIC = re.compile(r"^[A-Za-z0-9]{1,}$")
|
|
231
|
+
|
|
232
|
+
RE_PHONE = re.compile(r"^(?:\+\d{1,3}\s?)?(?:\(\d+\))?(?:\d+\s?)+(?:\d{1,4})$")
|
|
233
|
+
|
|
234
|
+
RE_PHONECODE = re.compile(r"^\+\d{1,3}$")
|
|
235
|
+
|
|
236
|
+
RE_OBJECTID = re.compile(r"^[0-9a-fA-F]{24}$")
|
|
237
|
+
|
|
238
|
+
RE_UUID = re.compile(
|
|
239
|
+
r"^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b"
|
|
240
|
+
r"-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$"
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
RE_DATE = re.compile(
|
|
244
|
+
r"^(\d{4})(?:-?(0[1-9]|1[0-2])(?:-?([12]\d|0[1-9]|3[01]))?"
|
|
245
|
+
r"|(?:-?([12]\d|0[1-9]|3[01]))?-(0[1-9]|1[0-2]))"
|
|
246
|
+
r"(?:[T ](\d{2}):([0-5]\d):([0-5]\d)(?:\.(\d{1,4}))?)?"
|
|
247
|
+
r"(?:Z|([+-])([01]\d|2[0-3])(?::?([0-5]\d))?)?$"
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
RE_DATEONLY = re.compile(r"^(\d{4})-(0[1-9]|1[0-2])-([12]\d|0[1-9]|3[01])$")
|
|
251
|
+
|
|
252
|
+
RE_TIME = re.compile(r"^(?:[01]\d|2[0-3]):([0-5]\d)(?::([0-5]\d))?(?:\.\d{1,4})?$")
|
|
253
|
+
|
|
254
|
+
RE_LOWER = re.compile(r"^[^A-Z]+$")
|
|
255
|
+
|
|
256
|
+
RE_UPPER = re.compile(r"^[^a-z]+$")
|
|
257
|
+
|
|
258
|
+
RE_IP = re.compile(
|
|
259
|
+
r"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}"
|
|
260
|
+
r"(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
#: Patterns keyed by rule name, for the format rules.
|
|
264
|
+
FORMAT_PATTERNS = {
|
|
265
|
+
"email": RE_EMAIL,
|
|
266
|
+
"url": RE_URL,
|
|
267
|
+
"domain": RE_DOMAIN,
|
|
268
|
+
"name": RE_NAME,
|
|
269
|
+
"fullname": RE_FULLNAME,
|
|
270
|
+
"username": RE_USERNAME,
|
|
271
|
+
"alpha": RE_ALPHA,
|
|
272
|
+
"alphanumeric": RE_ALPHANUMERIC,
|
|
273
|
+
"phone": RE_PHONE,
|
|
274
|
+
"phonecode": RE_PHONECODE,
|
|
275
|
+
"objectid": RE_OBJECTID,
|
|
276
|
+
"uuid": RE_UUID,
|
|
277
|
+
"date": RE_DATE,
|
|
278
|
+
"dateonly": RE_DATEONLY,
|
|
279
|
+
"time": RE_TIME,
|
|
280
|
+
"lower": RE_LOWER,
|
|
281
|
+
"upper": RE_UPPER,
|
|
282
|
+
"ip": RE_IP,
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def translate_user_regex(pattern: str) -> re.Pattern[str]:
|
|
287
|
+
"""Accept a pattern in literal form, ``/pattern/flags``, or plain form.
|
|
288
|
+
|
|
289
|
+
Flags ``i``, ``m`` and ``s`` map to the matching ``re`` flags. ``g``, ``y``
|
|
290
|
+
and ``u`` are accepted and ignored: they are iteration or encoding flags
|
|
291
|
+
with no meaning for a full-string test.
|
|
292
|
+
"""
|
|
293
|
+
body = pattern
|
|
294
|
+
flags = 0
|
|
295
|
+
|
|
296
|
+
if body.startswith("/"):
|
|
297
|
+
end = body.rfind("/")
|
|
298
|
+
if end == 0:
|
|
299
|
+
raise ValueError(f"has an unterminated regex literal: {pattern}")
|
|
300
|
+
body, raw_flags = body[1:end], body[end + 1 :]
|
|
301
|
+
for f in raw_flags:
|
|
302
|
+
if f == "i":
|
|
303
|
+
flags |= re.IGNORECASE
|
|
304
|
+
elif f == "m":
|
|
305
|
+
flags |= re.MULTILINE
|
|
306
|
+
elif f == "s":
|
|
307
|
+
flags |= re.DOTALL
|
|
308
|
+
elif f in ("g", "y", "u"):
|
|
309
|
+
continue
|
|
310
|
+
else:
|
|
311
|
+
raise ValueError(f"has an unsupported regex flag '{f}'")
|
|
312
|
+
|
|
313
|
+
try:
|
|
314
|
+
return re.compile(body, flags)
|
|
315
|
+
except re.error as exc:
|
|
316
|
+
raise ValueError(f"has an invalid regex: {exc}") from exc
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"""Rule-key resolution: dotted paths, and bracket/slice indexing."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
from typing import Any, Optional
|
|
7
|
+
|
|
8
|
+
from .types import Data
|
|
9
|
+
|
|
10
|
+
_BRACKET = re.compile(r"\[(-?\d*)(:?)(-?\d*)\]")
|
|
11
|
+
_HAS_BRACKET = re.compile(r"\[-?\d*:?-?\d*\]")
|
|
12
|
+
_SLICE_BRACKET = re.compile(r"\[-?\d*:-?\d*\]")
|
|
13
|
+
_TRAILING_INDEX = re.compile(r"\[-?\d+\]$")
|
|
14
|
+
|
|
15
|
+
_MISSING = object()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def has_index_syntax(key: str) -> bool:
|
|
19
|
+
return bool(_HAS_BRACKET.search(key))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def is_slice_key(key: str) -> bool:
|
|
23
|
+
return bool(_SLICE_BRACKET.search(key))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def ends_with_index(key: str) -> bool:
|
|
27
|
+
return bool(_TRAILING_INDEX.search(key))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def is_object(value: Any) -> bool:
|
|
31
|
+
"""Objects are dicts. Nothing else counts."""
|
|
32
|
+
return isinstance(value, dict)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def is_array(value: Any) -> bool:
|
|
36
|
+
"""Arrays are lists. A string is iterable but is not an array."""
|
|
37
|
+
return isinstance(value, list)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def get_prop_by_string(data: Data, prop_string: str) -> Any:
|
|
41
|
+
"""Walk a dotted path.
|
|
42
|
+
|
|
43
|
+
Mirrors the reference implementation: the walk stops at the first segment
|
|
44
|
+
that is not an object, and the final segment is then read from the last
|
|
45
|
+
object reached.
|
|
46
|
+
"""
|
|
47
|
+
if not prop_string:
|
|
48
|
+
return data
|
|
49
|
+
|
|
50
|
+
props = prop_string.split(".")
|
|
51
|
+
obj: Any = data
|
|
52
|
+
i = 0
|
|
53
|
+
for i in range(len(props) - 1):
|
|
54
|
+
if not is_object(obj):
|
|
55
|
+
break
|
|
56
|
+
candidate = obj.get(props[i], _MISSING)
|
|
57
|
+
if (
|
|
58
|
+
candidate is not _MISSING
|
|
59
|
+
and candidate is not None
|
|
60
|
+
and isinstance(candidate, (dict, list))
|
|
61
|
+
):
|
|
62
|
+
obj = candidate
|
|
63
|
+
else:
|
|
64
|
+
break
|
|
65
|
+
else:
|
|
66
|
+
# The whole chain was walked, so the leaf is the last segment.
|
|
67
|
+
i = len(props) - 1
|
|
68
|
+
|
|
69
|
+
if not is_object(obj):
|
|
70
|
+
return None
|
|
71
|
+
return obj.get(props[i])
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _at(container: list, raw: str) -> Any:
|
|
75
|
+
n = int(raw)
|
|
76
|
+
if n < 0:
|
|
77
|
+
n = len(container) + n
|
|
78
|
+
if n < 0 or n >= len(container):
|
|
79
|
+
return None
|
|
80
|
+
return container[n]
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def resolve_indexed_path(data: Data, key: str) -> tuple[Any, list[str]]:
|
|
84
|
+
"""Resolve a key containing bracket syntax.
|
|
85
|
+
|
|
86
|
+
Returns the selected value and, for slices, a label per selected element.
|
|
87
|
+
"""
|
|
88
|
+
current: Any = data
|
|
89
|
+
labels: Optional[list[str]] = None
|
|
90
|
+
prefix = ""
|
|
91
|
+
|
|
92
|
+
for segment in key.split("."):
|
|
93
|
+
bracket_start = segment.find("[")
|
|
94
|
+
base = segment if bracket_start == -1 else segment[:bracket_start]
|
|
95
|
+
|
|
96
|
+
if base:
|
|
97
|
+
if current is None or not isinstance(current, (dict, list)):
|
|
98
|
+
return None, []
|
|
99
|
+
if labels is not None:
|
|
100
|
+
picked: list[Any] = []
|
|
101
|
+
kept: list[str] = []
|
|
102
|
+
for i, el in enumerate(current):
|
|
103
|
+
if is_object(el):
|
|
104
|
+
picked.append(el.get(base))
|
|
105
|
+
kept.append(f"{labels[i]}.{base}")
|
|
106
|
+
current, labels, prefix = picked, kept, ""
|
|
107
|
+
continue
|
|
108
|
+
if not is_object(current):
|
|
109
|
+
return None, []
|
|
110
|
+
current = current.get(base)
|
|
111
|
+
|
|
112
|
+
prefix = f"{prefix}.{base}" if prefix else base
|
|
113
|
+
|
|
114
|
+
if bracket_start == -1:
|
|
115
|
+
continue
|
|
116
|
+
|
|
117
|
+
for m in _BRACKET.finditer(segment[bracket_start:]):
|
|
118
|
+
frm, colon, to = m.group(1), m.group(2), m.group(3)
|
|
119
|
+
if not is_array(current):
|
|
120
|
+
return None, []
|
|
121
|
+
if colon:
|
|
122
|
+
f = 0 if frm == "" else int(frm)
|
|
123
|
+
t = len(current) if to == "" else int(to)
|
|
124
|
+
start = max(len(current) + f, 0) if f < 0 else min(f, len(current))
|
|
125
|
+
# Python slicing already clamps and handles negative bounds
|
|
126
|
+
# the same way the reference implementation does.
|
|
127
|
+
picked_slice = current[f:t]
|
|
128
|
+
labels = [f"{prefix}[{start + i}]" for i in range(len(picked_slice))]
|
|
129
|
+
current = picked_slice
|
|
130
|
+
else:
|
|
131
|
+
current = _at(current, frm)
|
|
132
|
+
prefix = f"{prefix}[{frm}]"
|
|
133
|
+
|
|
134
|
+
return current, (labels if labels is not None else [])
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def lookup(data: Data, key: str) -> Any:
|
|
138
|
+
"""Resolve a plain (non-indexed) key."""
|
|
139
|
+
if "." not in key:
|
|
140
|
+
return data.get(key)
|
|
141
|
+
return get_prop_by_string(data, key)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def is_present(data: Data, key: str) -> bool:
|
|
145
|
+
"""Whether a key exists at all, which is distinct from holding None."""
|
|
146
|
+
if "." not in key:
|
|
147
|
+
return key in data
|
|
148
|
+
props = key.split(".")
|
|
149
|
+
obj: Any = data
|
|
150
|
+
for p in props[:-1]:
|
|
151
|
+
if not is_object(obj):
|
|
152
|
+
return False
|
|
153
|
+
obj = obj.get(p)
|
|
154
|
+
return is_object(obj) and props[-1] in obj
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def resolve(data: Data, key: str, array_indexing: bool = True) -> Any:
|
|
158
|
+
"""Return the value a rule key selects."""
|
|
159
|
+
if array_indexing and has_index_syntax(key):
|
|
160
|
+
value, _ = resolve_indexed_path(data, key)
|
|
161
|
+
return value
|
|
162
|
+
return lookup(data, key)
|
|
File without changes
|