otsuvalidator 1.1.2.312__tar.gz → 2.0.2__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,143 +1,113 @@
1
- Metadata-Version: 2.4
2
- Name: otsuvalidator
3
- Version: 1.1.2.312
4
- Summary: 単体でもディスクリプタとしても使用できるバリデータライブラリ
5
- Home-page: https://github.com/Otsuhachi/OtsuValidator
6
- Author: Otsuhachi
7
- Author-email: agequodagis.tufuiegoeris@gmail.com
8
- License: MIT License
9
-
10
- Copyright (c) 2021 Otsuhachi
11
-
12
- Permission is hereby granted, free of charge, to any person obtaining a copy
13
- of this software and associated documentation files (the "Software"), to deal
14
- in the Software without restriction, including without limitation the rights
15
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
- copies of the Software, and to permit persons to whom the Software is
17
- furnished to do so, subject to the following conditions:
18
-
19
- The above copyright notice and this permission notice shall be included in all
20
- copies or substantial portions of the Software.
21
-
22
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
- SOFTWARE.
29
-
30
- Keywords: Python validator descriptor converter
31
- Requires-Python: >=3.12
32
- Description-Content-Type: text/markdown
33
- License-File: LICENSE.txt
34
- Dynamic: author
35
- Dynamic: author-email
36
- Dynamic: description
37
- Dynamic: description-content-type
38
- Dynamic: home-page
39
- Dynamic: keywords
40
- Dynamic: license
41
- Dynamic: license-file
42
- Dynamic: requires-python
43
- Dynamic: summary
44
-
45
- - [概要](#概要)
46
- - [インストール](#インストール)
47
- - [モジュール](#モジュール)
48
- - [basesモジュールのクラス](#basesモジュールのクラス)
49
- - [validatorsモジュールのクラス](#validatorsモジュールのクラス)
50
- - [convertersモジュールのクラス](#convertersモジュールのクラス)
51
- - [継承規則](#継承規則)
52
- - [Validator継承規則](#validator継承規則)
53
- - [VContainer継承規則](#vcontainer継承規則)
54
- - [Converter継承規則](#converter継承規則)
55
-
56
- ---
57
- # 概要
58
-
59
- このライブラリは、値の正常性を検証するバリデータ群と、検証前に型変換を試みるコンバータ群を提供するユーティリティです。
60
- ディスクリプタとしてクラス属性に使用することで不適切な値の代入を防止できるほか、単独の関数・オブジェクトとして値を検証・変換することも可能です。
61
-
62
- ---
63
- ## インストール
64
-
65
- **インストール**
66
- ```bash
67
- pip install otsuvalidator
68
- ```
69
-
70
- **アップデート**
71
- ```bash
72
- pip install -U otsuvalidator
73
- ```
74
-
75
- **アンインストール**
76
- ```bash
77
- pip uninstall otsuvalidator
78
- ```
79
-
80
- ## モジュール
81
- 本ライブラリは主に以下の3つのモジュールで構成されています。
82
-
83
- モジュール名|概要
84
- :--:|:--:
85
- `bases`|バリデータ・コンバータの基底クラスを定義。自作のバリデータを作成する際に使用します。
86
- `validators`|値の検証のみを行うバリデータ群が定義されています。
87
- `converters`|型変換を試みた上で検証を行うコンバータ群が定義されています。
88
-
89
-
90
- ### basesモジュールのクラス
91
- - `Validator`: すべてのバリデータおよびコンバータの基底クラス。
92
- - `VContainer`: コンテナ(リストや辞書など)用バリデータの基底クラス。要素が可変なオブジェクトを検証する際に使用します。
93
- - `Converter`: コンバータの基底クラス。
94
- - `VChain`: バリデータ・コンバータの連結をサポートします。
95
-
96
- ### validatorsモジュールのクラス
97
- ※破線されたクラスは非推奨です。
98
- クラス|概要|期待する型
99
- :--:|:--:|:--:
100
- VBool|真偽値オブジェクトか検証|bool
101
- VChoice|規定の選択肢の中から1つが選択されているか検証|Any
102
- VNumerical / ~~VNumber~~|適切な数値か検証|int / float
103
- VFloat|適切な浮動小数点数か検証|float
104
- VInt|適切な整数か検証|int
105
- VPath|適切なパスか検証|pathlib.Path
106
- VString|適切な文字列か検証|str
107
- ~~VRegex~~|適切な正規表現か検証。`VString(pattern=...)`に合併。|str
108
- VDict|適切な構造の辞書か検証|dict
109
- VList|適切なリストか検証|list
110
- VTuple|適切なタプルか検証|tuple
111
- VTimedelta|適切なtimedelta型か検証|datetime.timedelta
112
-
113
- ### convertersモジュールのクラス
114
- ※破線されたクラスは非推奨です。
115
- クラス|概要
116
- :--:|:--:
117
- CBool|Yes / Noとして解釈できる値に対し`bool`型への変換を試みて検証
118
- CNumerical / ~~CNumber~~|`int` / `float`型への自動変換を試みて検証
119
- CFloat|`float`型への自動変換を試みて検証
120
- CInt|`int`型への自動変換を試みて検証
121
- CPath|`pathlib.Path`型への自動変換を試みて検証
122
- CString|`str`型への返還を試みて検証
123
- CTimedelta|`datetime.timedelta`型への自動変換を試みて検証
124
-
125
- ## 継承規則
126
- 自作のバリデータやコンバータを正しく定義するための規則です。
127
-
128
- ### Validator継承規則
129
- 1. 命名: クラス名は`V{検証したいクラス名}`とします(例: `VString`)。
130
- 2. 継承: `Validator`クラスを継承します。
131
- 3. 定義: `validate`メソッドを定義し、検証が成功した場合は受け取った`value`を返します。
132
- 4. 変換: `validate`内で`value`の型変換を行ってはいけません(変換を行う場合は`Converter`を使用)。
133
-
134
- ### VContainer継承規則
135
- 1. 命名: クラス名は`V{検証したいクラス名}`とします(例: `VList`)。
136
- 2. 継承: `VContainer`クラスを継承します。
137
- 3. 定義: `validate`メソッドを定義し、検証通過時は`value`を返します。中身の各要素への検証規則を設定します。
138
- 4. 変換: コンテナ自体の型変換は行いません。ただし要素に対してはオプション設定に応じます。
139
-
140
- ### Converter継承規則
141
- 1. 命名: `C{変換検証したいクラス名}`とします(例: `CInt`)。
142
- 2. 継承: `(対象クラスのバリデータ, Converter)`の順で多重継承します。
143
- 3. 定義: `validate`内で型変換を行い、`return super().validate(value)`で検証して返します。
1
+ Metadata-Version: 2.5
2
+ Name: otsuvalidator
3
+ Version: 2.0.2
4
+ Summary: 単体でもディスクリプタとしても使用できるバリデータライブラリ
5
+ Author-email: Otsuhachi <agequodagis.tufuiegoeris@gmail.com>
6
+ License: MIT License
7
+ License-File: LICENSE.txt
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Programming Language :: Python :: 3.13
11
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
12
+ Requires-Python: >=3.13
13
+ Description-Content-Type: text/markdown
14
+
15
+ - [概要](#概要)
16
+ - [インストール](#インストール)
17
+ - [モジュール](#モジュール)
18
+ - [basesモジュールのクラス](#basesモジュールのクラス)
19
+ - [validatorsモジュールのクラス](#validatorsモジュールのクラス)
20
+ - [convertersモジュールのクラス](#convertersモジュールのクラス)
21
+ - [継承規則](#継承規則)
22
+ - [Validator継承規則](#validator継承規則)
23
+ - [VContainer継承規則](#vcontainer継承規則)
24
+ - [Converter継承規則](#converter継承規則)
25
+
26
+ ---
27
+ # 概要
28
+
29
+ このライブラリは、値の正常性を検証するバリデータ群と、検証前に型変換を試みるコンバータ群を提供するユーティリティです。
30
+ ディスクリプタとしてクラス属性に使用することで不適切な値の代入を防止できるほか、単独の関数・オブジェクトとして値を検証・変換することも可能です。
31
+
32
+ ---
33
+ ## インストール
34
+
35
+ **インストール**
36
+ ```bash
37
+ pip install otsuvalidator
38
+ ```
39
+
40
+ **アップデート**
41
+ ```bash
42
+ pip install -U otsuvalidator
43
+ ```
44
+
45
+ **アンインストール**
46
+ ```bash
47
+ pip uninstall otsuvalidator
48
+ ```
49
+
50
+ ## モジュール
51
+ 本ライブラリは主に以下の3つのモジュールで構成されています。
52
+
53
+ モジュール名|概要
54
+ :--:|:--:
55
+ `bases`|バリデータ・コンバータの基底クラスを定義。自作のバリデータを作成する際に使用します。
56
+ `validators`|値の検証のみを行うバリデータ群が定義されています。
57
+ `converters`|型変換を試みた上で検証を行うコンバータ群が定義されています。
58
+
59
+
60
+ ### basesモジュールのクラス
61
+ - `Validator`: すべてのバリデータおよびコンバータの基底クラス。
62
+ - `VContainer`: コンテナ(リストや辞書など)用バリデータの基底クラス。要素が可変なオブジェクトを検証する際に使用します。
63
+ - `Converter`: コンバータの基底クラス。
64
+ - `VChain`: バリデータ・コンバータの連結をサポートします。
65
+
66
+ ### validatorsモジュールのクラス
67
+ ※破線されたクラスは非推奨です。
68
+ クラス|概要|期待する型
69
+ :--:|:--:|:--:
70
+ VBool|真偽値オブジェクトか検証|bool
71
+ VChoice|規定の選択肢の中から1つが選択されているか検証|Any
72
+ VNumerical / ~~VNumber~~|適切な数値か検証|int / float
73
+ VFloat|適切な浮動小数点数か検証|float
74
+ VInt|適切な整数か検証|int
75
+ VPath|適切なパスか検証|pathlib.Path
76
+ VString|適切な文字列か検証|str
77
+ ~~VRegex~~|適切な正規表現か検証。`VString(pattern=...)`に合併。|str
78
+ VDict|適切な構造の辞書か検証|dict
79
+ VList|適切なリストか検証|list
80
+ VTuple|適切なタプルか検証|tuple
81
+ VTimedelta|適切なtimedelta型か検証|datetime.timedelta
82
+
83
+ ### convertersモジュールのクラス
84
+ ※破線されたクラスは非推奨です。
85
+ クラス|概要
86
+ :--:|:--:
87
+ CBool|Yes / Noとして解釈できる値に対し`bool`型への変換を試みて検証
88
+ CNumerical / ~~CNumber~~|`int` / `float`型への自動変換を試みて検証
89
+ CFloat|`float`型への自動変換を試みて検証
90
+ CInt|`int`型への自動変換を試みて検証
91
+ CPath|`pathlib.Path`型への自動変換を試みて検証
92
+ CString|`str`型への返還を試みて検証
93
+ CTimedelta|`datetime.timedelta`型への自動変換を試みて検証
94
+
95
+ ## 継承規則
96
+ 自作のバリデータやコンバータを正しく定義するための規則です。
97
+
98
+ ### Validator継承規則
99
+ 1. 命名: クラス名は`V{検証したいクラス名}`とします(例: `VString`)。
100
+ 2. 継承: `Validator`クラスを継承します。
101
+ 3. 定義: `validate`メソッドを定義し、検証が成功した場合は受け取った`value`を返します。
102
+ 4. 変換: `validate`内で`value`の型変換を行ってはいけません(変換を行う場合は`Converter`を使用)。
103
+
104
+ ### VContainer継承規則
105
+ 1. 命名: クラス名は`V{検証したいクラス名}`とします(例: `VList`)。
106
+ 2. 継承: `VContainer`クラスを継承します。
107
+ 3. 定義: `validate`メソッドを定義し、検証通過時は`value`を返します。中身の各要素への検証規則を設定します。
108
+ 4. 変換: コンテナ自体の型変換は行いません。ただし要素に対してはオプション設定に応じます。
109
+
110
+ ### Converter継承規則
111
+ 1. 命名: `C{変換検証したいクラス名}`とします(例: `CInt`)。
112
+ 2. 継承: `(対象クラスのバリデータ, Converter)`の順で多重継承します。
113
+ 3. 定義: `validate`内で型変換を行い、`return super().validate(value)`で検証して返します。
@@ -0,0 +1,15 @@
1
+ [[source]]
2
+ url = "https://pypi.org/simple"
3
+ verify_ssl = true
4
+ name = "pypi"
5
+
6
+ [packages]
7
+
8
+ [dev-packages]
9
+
10
+ [requires]
11
+ python_version = "3.13"
12
+
13
+ [scripts]
14
+ reset = "pwsh -Command Remove-Item .venv -Force -Recurse && py -m pipenv update -d"
15
+ test = "pwsh -Command pipenv run py -m unittest discover -s tests -p \"test_*.py\" -v"
@@ -0,0 +1,20 @@
1
+ {
2
+ "_meta": {
3
+ "hash": {
4
+ "sha256": "494d5b4f482f0ef471f49afe28f00ec1a2ff75da2ce65060d8cabaeb3da2f100"
5
+ },
6
+ "pipfile-spec": 6,
7
+ "requires": {
8
+ "python_version": "3.13"
9
+ },
10
+ "sources": [
11
+ {
12
+ "name": "pypi",
13
+ "url": "https://pypi.org/simple",
14
+ "verify_ssl": true
15
+ }
16
+ ]
17
+ },
18
+ "default": {},
19
+ "develop": {}
20
+ }
@@ -1,33 +1,4 @@
1
- __VERSION__ = "1.1.2.312"
2
-
3
-
4
- __all__ = (
5
- "CBool",
6
- "CFloat",
7
- "CInt",
8
- "CNumerical",
9
- "CPath",
10
- "CString",
11
- "CTimedelta",
12
- "VAny",
13
- "VBool",
14
- "VChain",
15
- "VChoice",
16
- "VDict",
17
- "VFloat",
18
- "VInt",
19
- "VList",
20
- "VNone",
21
- "VNumerical",
22
- "VPath",
23
- "VRange",
24
- "VSequence",
25
- "VString",
26
- "VTimedelta",
27
- "VTuple",
28
- "VType",
29
- )
30
-
1
+ import logging
31
2
 
32
3
  from .bases import VChain
33
4
  from .converters import (
@@ -57,3 +28,35 @@ from .validators import (
57
28
  VTuple,
58
29
  VType,
59
30
  )
31
+
32
+ __all__ = [
33
+ "CBool",
34
+ "CFloat",
35
+ "CInt",
36
+ "CNumerical",
37
+ "CPath",
38
+ "CString",
39
+ "CTimedelta",
40
+ "VAny",
41
+ "VBool",
42
+ "VChain",
43
+ "VChoice",
44
+ "VDict",
45
+ "VFloat",
46
+ "VInt",
47
+ "VList",
48
+ "VNone",
49
+ "VNumerical",
50
+ "VPath",
51
+ "VRange",
52
+ "VSequence",
53
+ "VString",
54
+ "VTimedelta",
55
+ "VTuple",
56
+ "VType",
57
+ ]
58
+
59
+
60
+ logging.getLogger(__name__).addHandler(logging.NullHandler())
61
+
62
+ __version__ = "2.0.2"
@@ -1,13 +1,16 @@
1
- __all__ = (
1
+ import logging
2
+ from abc import ABC, abstractmethod
3
+ from typing import Any, Literal, Self, overload
4
+
5
+ __all__ = [
2
6
  "Converter",
3
7
  "VChain",
4
8
  "VContainer",
5
9
  "Validator",
6
- )
10
+ ]
7
11
 
8
12
 
9
- from abc import ABC, abstractmethod
10
- from typing import Any, Literal, Self, overload
13
+ logger = logging.getLogger(__name__)
11
14
 
12
15
 
13
16
  class Validator[OutT](ABC):
@@ -104,6 +107,7 @@ class VChain[OutT](Validator[OutT]):
104
107
  except Exception as ex:
105
108
  exceptions.append(ex)
106
109
  if not passed:
110
+ logger.error(f"全てのバリデータでの検証に失敗しました: {value}")
107
111
  raise ValueError(*exceptions)
108
112
  return current_value
109
113
 
@@ -1,4 +1,15 @@
1
- __all__ = (
1
+ import logging
2
+ import re
3
+ import warnings
4
+ from collections.abc import Callable
5
+ from datetime import timedelta
6
+ from pathlib import Path
7
+ from typing import Any, Literal, override
8
+
9
+ from .bases import Converter
10
+ from .validators import VBool, VNumerical, VPath, VString, VTimedelta
11
+
12
+ __all__ = [
2
13
  "CBool",
3
14
  "CFloat",
4
15
  "CInt",
@@ -7,18 +18,10 @@ __all__ = (
7
18
  "CPath",
8
19
  "CString",
9
20
  "CTimedelta",
10
- )
21
+ ]
11
22
 
12
23
 
13
- import re
14
- import warnings
15
- from collections.abc import Callable
16
- from datetime import timedelta
17
- from pathlib import Path
18
- from typing import Any, Literal, override
19
-
20
- from .bases import Converter
21
- from .validators import VBool, VNumerical, VPath, VString, VTimedelta
24
+ logger = logging.getLogger(__name__)
22
25
 
23
26
 
24
27
  class CBool(VBool, Converter[Any, bool]):
@@ -86,27 +89,31 @@ class CBool(VBool, Converter[Any, bool]):
86
89
  elif tmp_value in (no := ("false", "no", "n", "0", "0.0")):
87
90
  tmp_value = False # type: ignore
88
91
  else:
89
- msg = f"{yes}または{no}のいずれかである必要があります。\n{tmp_value=}"
90
- raise ValueError(msg)
92
+ msg = "クラス定義の検証に失敗しました"
93
+ logger.error(f"{msg}: {value}\n\tTrue: {yes}\n\tFalse: {no}")
94
+ raise ValueError(f"{msg}。")
91
95
  elif tv is int:
92
96
  if tmp_value == 1:
93
97
  tmp_value = True # type: ignore
94
98
  elif tmp_value == 0:
95
99
  tmp_value = False # type: ignore
96
100
  else:
97
- msg = f"1または0である必要があります。\n{tmp_value=}"
98
- raise ValueError(msg)
101
+ msg = "1または0である必要があります"
102
+ logger.error(f"{msg}: {tmp_value}")
103
+ raise ValueError(f"{msg}。")
99
104
  elif tv is float:
100
105
  if tmp_value == 1.0:
101
106
  tmp_value = True # type: ignore
102
107
  elif tmp_value == 0.0:
103
108
  tmp_value = False # type: ignore
104
109
  else:
105
- msg = f"1.0または0.0である必要があります。\n{tmp_value=}"
106
- raise ValueError(msg)
110
+ msg = "1.0または0.0である必要があります"
111
+ logger.error(f"{msg}: {tmp_value}")
112
+ raise ValueError(f"{msg}。")
107
113
  else:
108
- msg = f"Yes/Noとして解釈できる必要があります。\n{tmp_value=}"
109
- raise TypeError(msg)
114
+ msg = "Yes/Noとして解釈できる必要があります"
115
+ logger.error(f"{msg}: {tmp_value}")
116
+ raise TypeError(f"{msg}。")
110
117
  return super().validate(tmp_value)
111
118
 
112
119
 
@@ -143,12 +150,14 @@ class CNumerical[OutT: float | int](VNumerical[OutT], Converter[Any, OutT]):
143
150
  if t_type is not float:
144
151
  converted = t_type(tmp_value)
145
152
  if converted != tmp_value:
146
- msg = f"変換後の数値が元の数値と等価ではありません。{value} != {converted}"
147
- raise ValueError(msg)
153
+ msg = "変換後の数値が元の数値と等価ではありません"
154
+ logger.error(f"{msg}: {value} -> {tmp_value}")
155
+ raise ValueError(f"{msg}。")
148
156
  except (TypeError, ValueError):
149
157
  type_name = t_type.__name__ if t_type else "number"
150
- msg = f"'{self.public_name}'を{type_name}に変換できませんでした: {value!r}。"
151
- raise ValueError(msg) from None
158
+ msg = f"`{self.public_name}`を`{type_name}型`に変換できませんでした"
159
+ logger.exception(f"{msg}: {value!r}")
160
+ raise ValueError(f"{msg}。") from None
152
161
  return super().validate(converted)
153
162
 
154
163
 
@@ -214,8 +223,9 @@ class CPath(VPath, Converter[str | Path, Path]):
214
223
  try:
215
224
  converted = Path(value)
216
225
  except (TypeError, ValueError):
217
- msg = f"'{self.public_name}'をpathlib.Pathオブジェクトに変換できませんでした: {value!r}。"
218
- raise TypeError(msg) from None
226
+ msg = f"`{self.public_name}`を`pathlib.Path`オブジェクトに変換できませんでした"
227
+ logger.exception(f"{msg}: {value!r}")
228
+ raise TypeError(f"{msg}。") from None
219
229
  return super().validate(converted)
220
230
 
221
231
 
@@ -231,8 +241,9 @@ class CString(VString, Converter[Any, str]):
231
241
  try:
232
242
  tmp_value = str(tmp_value)
233
243
  except Exception:
234
- msg = f"'{self.public_name}'はstr型に変換可能な値である必要があります: {tmp_value!r}。"
235
- raise TypeError(msg) from None
244
+ msg = f"`{self.public_name}`は`str型`に変換可能な値である必要があります"
245
+ logger.exception(f"{msg}: {tmp_value!r}")
246
+ raise TypeError(f"{msg}。") from None
236
247
  return super().validate(tmp_value)
237
248
 
238
249
 
@@ -257,8 +268,9 @@ class CTimedelta(VTimedelta, Converter[Any, timedelta]):
257
268
  if f is not None:
258
269
  tmp_value = f(tmp_value)
259
270
  except Exception:
260
- msg = f"'{self.public_name}'はtimedelta型に変換可能な値である必要があります: {tmp_value!r}。"
261
- raise TypeError(msg) from None
271
+ msg = f"`{self.public_name}`は`timedelta型`に変換可能な値である必要があります"
272
+ logger.exception(f"{msg}: {tmp_value!r}")
273
+ raise TypeError(f"{msg}") from None
262
274
  return super().validate(tmp_value)
263
275
 
264
276
  def __try_convert_container(self, value: list | tuple) -> timedelta:
@@ -279,5 +291,6 @@ class CTimedelta(VTimedelta, Converter[Any, timedelta]):
279
291
  v = int(v)
280
292
  d[k] = v
281
293
  return self.__try_convert_dict(d)
282
- msg = f"'{value}'をtimedelta型に変換できませんでした。"
283
- raise ValueError(msg)
294
+ msg = "timedelta型に変換できませんでした"
295
+ logger.error(f"{msg}: `{value!r}`")
296
+ raise ValueError(f"{msg}。")