otsuvalidator


Nameotsuvalidator JSON
Version 2.0.1 PyPI version JSON
download
home_pagehttps://github.com/Otsuhachi/OtsuValidator
Summary単体でもディスクリプタとしても使用できるバリデータライブラリ
upload_time2023-01-13 14:10:38
maintainer
docs_urlNone
authorOtsuhachi
requires_python>=3.8
licenseMIT License Copyright (c) 2021 Otsuhachi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords python validator descriptor converter
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            - [概要](#概要)
  - [インストール](#インストール)
  - [モジュール](#モジュール)
  - [継承規則](#継承規則)
  - [実行例-バリデータ](#実行例-バリデータ)
  - [コンバータの変換](#コンバータの変換)
    - [実行例-コンバータ](#実行例-コンバータ)

# 概要

このライブラリは値の正常性を検証するバリデータ群と、検証前に型変換を試みるコンバータ群です。  
ディスクリプタとして使用することで属性に不正な値が代入されるのを防止します。  
また、単独で使用することも可能です。  

このライブラリは以下の環境で作成されています。  
`Windows10(64bit)`, `Python3.8.10`  

## インストール

インストール

`pip install otsuvalidator`

アップデート

`pip install -U otsuvalidator`

アンインストール

`pip uninstall otsuvalidator`

## モジュール

モジュールは以下の3つが存在します。

モジュール名|概要
:--:|--
[bases](#basesモジュールのクラス)|バリデータ、コンバータの基底クラスが定義されいる<br>自作のバリデータを定義するときに使用できる
[validators](#validatorsモジュールのクラス)|バリデータが定義されている
[converters](#convertersモジュールのクラス)|コンバータが定義されている


omit in toc
<!-- omit in toc -->
### basesモジュールのクラス

`Validator`と表記されている部分に関しては、バリデータ、コンバータ両方を指します。

クラス|概要
:--:|:--
Validator|すべてのバリデータ、コンバータの基底クラス
VContainer|コンテナ用のバリデータの基底クラス<br>中身が可変なクラスのバリデータを定義するときに使用する
Converter|コンバータの基底クラス<br>セキュアさが重視される場面では使用しない
CNoneable|`Validator`既定のバリデーションに加え、`None`を許可する<br>変換の可否は以下の2点に依存する<br>-渡した`Validator`がコンバータか否か<br>-所属する`VContainer`の`allow_convert`オプション
CNumerical|数値型用コンバータの基底クラス<br>`value`に対し、`int`変換、`float`変換を試みるメソッドが定義されている<br>`complex`は想定されていない

<!-- omit in toc -->
### validatorsモジュールのクラス

スーパークラスの表記がないものは`Validator`を継承しています。

クラス|スーパークラス|概要|期待する型
:--:|:--:|:--|:--:
VBool||真偽値オブジェクトか|bool
VChoice||選択肢の中から1つが選択されているか|Any
VNumber||適切な数値か|int,flaot
VFloat|VNumber|適切な浮動小数点数か|flaot
VInt|VNumber|適切な整数か|int
VPath||適切なパスか|pathlib.Path
VString||適切な文字列か|str
VRegex|VString|正規表現にマッチする適切な文字列か|str
VDict|VContainer|適切な辞書か|dict
VList|VContainer|適切なリストか|list
VTuple|VContaner|適切なタプルか|tuple
VTimedelta||適切な経過時間型か|datetime.timedelta

<!-- omit in toc -->
### convertersモジュールのクラス

スーパークラスにコンバータが記載されていないクラスは`Converter`を継承しています。

クラス|スーパークラス|概要
:--:|:--:|:--
CBool|VBool,Converter|一般に**Yes/Noとして解釈できる値**に対し、bool変換を試み、検証を行う<br>`bool(value)`では`True`になるものが`False`になったり例外が発生したりする
CNumber|VNumber, CNumerical|`int`,`float`型への変換を試み、検証を行う
CFloat|VFloat, CNumerical|`float`型への変換を試み、検証を行う
CInt|VInt, CNumerical|`int`型への変換を試み、検証を行う
CPath|VPath, Converter|`Path`型への変換を試み、検証を行う
CString|VString, Converter|`str`型への変換を試み、検証を行う
CTimedelta|VTimedelta, Converter|`datetime.timedelta`型への変換を試み、検証を行う

## 継承規則

きちんと動作するバリデータ、コンバータを定義するための規則です。  
`CNoneable`は**継承しないでください。**

<!-- no toc -->
-   [Validator継承規則](#validator継承規則)
-   [VContainer継承規則](#vcontainer継承規則)
-   [Converter継承規則](#converter継承規則)

<!-- omit in toc -->
### Validator継承規則

規則|概要|理由
:--:|:--|:--
命名|クラス名は`V{検証したいクラス名}`とする|管理のしやすさ
継承|`Validator`を継承する|
定義|`validate`メソッドを定義し、検証が通った場合には`value`を返す|拡張してコンバータを定義するときに必要
変換|`value`の型を変換しない|変換と検証を行う場合はコンバータを使用する

<!-- omit in toc -->
### VContainer継承規則

規則|概要|理由|
:--:|:--|:--
命名|クラス名は`V<検証したいクラス名>`とする|管理のしやすさ<br>本質的にはValidatorと変わらないので規則もそのまま適用
継承|`VContainer`を継承する|
定義|`validate`メソッドを定義し、検証が通った場合には`value`を返す<br>変換を許可する場合、`TEMPLATE`が`Validator`以外の場合など細かな違いを設定する必要がある|コンテナそのものの検証と中身の検証が必要
変換|`value`の型を変換しない<br>`value`の各要素`v`に対してはオプション次第|`TEMPLATE`にコンバータを渡している場合、禁止されていない限り変換を行うのが自然なため

<!-- omit in toc -->
### Converter継承規則

`CNumerical`についてもここに従ってください。

規則|概要|理由
:--:|:--|:--
命名|クラス名は`C<変換検証したいクラス名>`とする|一目で変換を行うクラスと認識するため
継承|`(検証したいクラスのバリデータ,コンバータ)`を継承する|`検証したいクラスのバリデータ.validate`メソッドを`validate`メソッド内で呼び出すため
定義|`validate`メソッドを定義し、変換検証が通った場合には変換された`value`を返す<br>`super_validate`メソッドを定義し、`検証したいクラス.validate`メソッドを行えるようにする|VContainerなど、変換を許可したくない状況では`super_validate`を使用するため
変換|`validate`メソッド内で変換を試みる<br>`super_validate`メソッドでは変換しない|定義で書いた通り無変換が必要になる場面もあるため

## 実行例-バリデータ

<!-- omit in toc -->
### バリデータの実行例

バリデータをディスクリプタとして使用している`Student`クラスを試しに使用します。
<!-- omit in toc -->
#### バリデータの実行例目次

<!-- no toc -->
- [前提コード](#バリデータ実行例-前提コード)
- [nameの操作](#バリデータ実行例-nameの操作)
- [ageの操作](#バリデータ実行例-ageの操作)
- [genderの操作](#バリデータ実行例-genderの操作)
- [gradesの操作](#バリデータ実行例-gradesの操作)
- [hobbyの操作](#バリデータ実行例-hobbyの操作)
- [addressの操作](#バリデータ実行例-addressの操作)
- [成功](#バリデータ実行例-成功)

<!-- omit in toc -->
#### バリデータ実行例-前提コード

[目次](#バリデータの実行例目次)に戻る

説明は以下の条件を満たした環境で実行されることを想定しています。

1. Python3.8以上がインストールされたWindows
2. 本ライブラリがインストールされている
3. 以下の`test.py`ファイルを生成し、`py -i test.py`、または`対話モード`で以下のコードが入力されている

```python
# test.py
from otsuvalidator import (CNoneable, VChoice, VDict, VInt, VList, VRegex, VString)


class Student:
    name = VString(1, 50, checker=str.istitle)  # 1文字以上50文字以下, str.istitleがTrueになる文字列
    age = VInt(0, 150)  # 0以上150以下の整数
    gender = VChoice('male', 'female', 'others')  # (male, female, others)のいずれか
    grades = VDict(
        # 以下の構造を持つ辞書, キー欠落不可, アクセス時に再検証を行わない
        {
            'Japanese':
            VInt(0, 100),  # 0以上100以下の整数
            'Social Studies':
            VInt(0, 100),
            'Math':
            VDict(
                # 以下のキーを持つ辞書, キー欠落可, アクセス時に再検証を行う
                {
                    'Math1': VInt(0, 100),
                    'Math2': VInt(0, 100)
                },
                allow_missing_key=True,
                monitoring_overwrite=True,
            )
        },
        allow_missing_key=False,
        monitoring_overwrite=False,
    )
    # 1文字以上の文字列だけのリスト Noneで無回答可 要素数は無制限
    hobby = CNoneable(VList(VString(1)))
    # [郵便番号, 都道府県, 市町村群]のリスト Noneで無回答可
    address = CNoneable(VList([VRegex('^\\d{3}-?\\d{4}$'), VRegex('(?!.*\\d.*)'), VRegex('(?!.*\\d.*)')]))

    def show_profile(self):
        name = self.name
        age = self.age
        gender = self.gender
        grades = self.grades
        japanese = grades['Japanese']
        social = grades['Social Studies']
        math = grades['Math']
        hobby = self.hobby
        address = self.address
        profiles = ('名前', '年齢', '性別', '国語', '社会', '数学', '趣味', '住所')
        profile_values = (name, age, gender, japanese, social, math, hobby, address)
        for title, value in zip(profiles, profile_values):
            print(f'{title}: {value}')


otsuhachi = Student()
```

<!-- omit in toc -->
#### バリデータ実行例-nameの操作

[目次](#バリデータの実行例目次)に戻る

`otsuhachi.name`を操作します。  
`Student`の`name`属性は`VString(1, checker=str.istitle)`によって検証されます。

```python

# 失敗 (型が異なる)
>>> otsuhachi.name = 28
Traceback (most recent call last):
...
TypeError: 属性'name'はstr型である必要があります。(28: int)

# 失敗 (最低文字数を満たしていない)
>>> otsuhachi.name = ''
Traceback (most recent call last):
...
ValueError: 属性'name'は1文字以上である必要があります。('': str)

# 失敗 (最大文字数を超過している)
>>> otsuhachi.name = 'A' + ('a' * 100)
Traceback (most recent call last):
...
ValueError: 属性'name'は50文字以下である必要があります。('Aaaaaaaaa...aaaaaaaaa': str)

# 失敗 (checkerがTrueを返さない)
>>> otsuhachi.name = 'otsuhachi'
Traceback (most recent call last):
...
ValueError: 属性'name'は指定した形式に対応している必要があります。<method 'istitle' of 'str' objects>。('otsuhachi': str)

# 成功
>>> otsuhachi.name = 'Otsuhachi'
>>> otsuhachi.name
'Otsuhachi'
```

<!-- omit in toc -->
#### バリデータ実行例-ageの操作

[目次](#バリデータの実行例目次)に戻る

`otsuhachi.age`を操作します。  
`Student`の`age`属性は`VInt(0)`によって検証されます。

```python

#失敗 (型が異なる)
>>> otsuhachi.age = 28.8
Traceback (most recent call last):
...
TypeError: 属性'age'はint型である必要があります。(28.8: float)

# 失敗 (最小値未満)
>>> otsuhachi.age = -1
...
ValueError: 属性'age'は0より小さい値を設定することはできません。(-1: int)

# 失敗 (最大値超過)
>>> otsuhachi.age = 280
Traceback (most recent call last):
...
ValueError: 属性'age'は150より大きい値を設定することはできません。(280: int)

# 成功
>>> otsuhachi.age = 28
>>> otsuhachi.age
28
```

<!-- omit in toc -->
#### バリデータ実行例-genderの操作

[目次](#バリデータの実行例目次)に戻る

`otsuhachi.gender`を操作します。  
`Student`の`gender`属性は`VChoice('male', 'female', 'others')`によって検証されます。


```python

# 失敗 (選択肢にない値)
>>> otsuhachi.gender = None
Traceback (most recent call last):
...
ValueError: 属性'gender'は{'male', 'others', 'female'}のいずれかである必要があります。(None: NoneType)

# 失敗 (選択肢にない値)
>>> otsuhachi.gender = 'mal'
Traceback (most recent call last):
...
ValueError: 属性'gender'は{'male', 'others', 'female'}のいずれかである必要があります。('mal': str)

# 成功
>>> otsuhachi.gender = 'others'
>>> otsuhachi.gender
'others'
>>> otsuhachi.gender = 'female'
>>> otsuhachi.gender
'female'
>>> otsuhachi.gender = 'male'
>>> otsuhachi.gender
'male'
```

<!-- omit in toc -->
#### バリデータ実行例-gradesの操作

[目次](#バリデータの実行例目次)に戻る

<!-- no toc -->
- [gradesの概要](#gradesの概要)
- [gradesの基本的な失敗と成功の例](#gradesの基本的な失敗と成功の例)
- [gradesで起こりえる不正](#gradesで起こりえる不正)
- [gradesで起こりえる不正の防止](#gradesで起こりえる不正の防止)

`otsuhachi.garades`を操作します。  
`Student`の`grades`は以下のように定義されたバリデータによって検証されます。

```python

VDict(
    {
        'Japanese': VInt(0, 100),
        'Social Studies': VInt(0, 100),
        'Math': VDict(
            {
                'Math1': VInt(0, 100),
                'Math2': VInt(0, 100)
            },
            allow_missing_key=True,
            monitoring_overwrite=True,
        )
    },
    allow_missing_key=False,
    monitoring_overwrite=False,
)
```

<!-- omit in toc -->
##### gradesの概要


分解して考えてみます。

- gradesが持つべきキーは(`Japanese`, `Social Studies`, `Math`)の3つ
   - `Japanese`と`Social Studies`は`0~100`の整数値
   - `Math`は(`Math1`, `Math2`)のキーを持つ辞書
      - `Math1`と`Math2`は`0~100`の整数値
      - `allow_missing_key`が`True`なのでキーを持たない辞書でも可
      - `monitoring_overwrite`は`True`でも実質無関係
- `allow_missing_key`が`False`なので、キーすべてが含まれている必要がある
- `monitoring_overwrite`が`False`なので`otsuhachi.grades`をしても再検証が行われない

以上のような設定のバリデータになっています。

<!-- omit in toc -->
##### gradesの基本的な失敗と成功の例

```python

# 失敗 (型が異なる)
>>> otsuhachi.grades = ['Japanese', 'Social Studies', 'Math']
Traceback (most recent call last):
...
TypeError: 属性'grades'はdict型である必要があります。(['Japanese', 'Social Studies', 'Math']: list)

# 失敗 (必須キーの欠落)
>>> otsuhachi.grades = {'Japanese': 68}
Traceback (most recent call last):
...
ValueError: 属性'grades'は以下のキーを設定する必要があります。({'Math', 'Social Studies'})。({'Japanese': 68}: dict)

# 失敗 (不正な値)
>>> otsuhachi.grades = {'Japanese': 68, 'Social Studies': 28, 'Math': 66}
Traceback (most recent call last):
...
TypeError: dict型である必要があります。(66: int)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
...
TypeError: キー'Math'は不正な値です。(66: int)

# 失敗 (不正な値: 入れ子構造)
>>> otsuhachi.grades = {'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 2.8}}
Traceback (most recent call last):
...
TypeError: int型である必要があります。(2.8: float)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
...
TypeError: キー'Math1'は不正な値です。(2.8: float)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
...
TypeError: キー'Math'は不正な値です。({'Math1': 2.8}: dict)

# 失敗 (未定義のキー)
>>> otsuhachi.grades = {'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66}, 'Science': 70}
Traceback (most recent call last):
...
ValueError: 属性'grades'は以下のキーを設定することはできません。({'Science'})。({'Japanese...ence': 70}: dict)

# 成功
>>> otsuhachi.grades = {'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66, 'Math2': 56}}
>>> otsuhachi.grades
{'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66, 'Math2': 56}}

# Math内はキー欠落可
>>> otsuhachi.grades = {'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66}}
>>> otsuhachi.grades
{'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66}}
```

<!-- omit in toc -->
##### gradesで起こりえる不正

この設定では書き換えに対して無力です。  
`otsuhachi.grades`が呼び出されたとき限定で検証が行われるので、以下のような操作では不正が行えます。

```python

# 正常な形式でgradesをセット
>>> otsuhachi.grades = {'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66, 'Math2': 56}}
>>> otsuhachi.grades
{'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66, 'Math2': 56}}

# grades['Math']を66にする
>>> otsuhachi.grades['Math'] = 66
>>> otsuhachi.grades
{'Japanese': 68, 'Social Studies': 28, 'Math': 66}
```

<!-- omit in toc -->
##### gradesで起こりえる不正の防止

不正の防止には主に2つの手段があります。

1. バリデータをクラス外で定義し、必要に応じて検証を行う
2. `monitoring_overwrite`を`True`にする

1.の方法では手間が掛かりますが、不要な時に検証されることがないので比較的高速な動作が期待されます。  
また`monitoring_overwrite`は`False`でなければ2の方法と変わりありません。  

2.の方法では`otsuhachi.grades`が呼ばれるたびに検証されるので手軽です。  

どちらも書き換えは許してしまいますが、最終的に値を利用するタイミングでは検証が行われます。

```python

# 1の方法
GRADES_VALIDATOR = VDict(
    {
        'Japanese': VInt(0, 100),
        'Social Studies': VInt(0, 100),
        'Math': VDict(
            {
                'Math1': VInt(0, 100),
                'Math2': VInt(0, 100)
            },
            allow_missing_key=True,
            monitoring_overwrite=True,
        )
    },
    allow_missing_key=False,
    monitoring_overwrite=False,
)

class Student:
    # ...部分は前提コード通りです。
    ...
    grades = GRADES_VALIDATOR
    ...

# 値のセット
otsuhachi = Student()
otsuhachi.grades = {'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66, 'Math2': 56}}
>>> otsuhachi.grades
{'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66, 'Math2': 56}}

# 不正な書き換え
>>> otsuhachi.grades['Math'] = 66
>>> otsuhachi.grades
{'Japanese': 68, 'Social Studies': 28, 'Math': 66}

# 不正が困る場面
>>> GRADES_VALIDATOR.validate(otsuhachi.grades)
Traceback (most recent call last):
...
TypeError: dict型である必要があります。(66: int)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
...
TypeError: キー'Math'は不正な値です。(66: int)

```

```python

# 2の方法
class Student:
    # ...部分は前提コード通りです。
    ...
    grades = VDict(
        ...
        monitoring_overwrite=True,
    )
    ...
    
# 値のセット
otsuhachi = Student()
>>> otsuhachi.grades = {'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66, 'Math2': 56}}
>>> otsuhachi.grades
{'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66, 'Math2': 56}}

# 不正な書き換え
>>> otsuhachi.grades['Math'] = 66
>>> otsuhachi.grades
Traceback (most recent call last):
...
TypeError: dict型である必要があります。(66: int)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
...
TypeError: キー'Math'は不正な値です。(66: int)
```

<!-- omit in toc -->
#### バリデータ実行例-hobbyの操作

[目次](#バリデータの実行例目次)に戻る

`otsuhachi.hobby`を操作します。  
`Student`の`hobby`属性は`CNoneable(VList(VString(1)))`によって検証されます。

`CNoneable`はバリデータに`None`を許可するクラスです。  
今回は`otsuhachi.hobby`が`None`または`VList(VString(1))`の条件を満たす時に検証を通過します。

```python

# 失敗 (CNoneableはNoneを許可するだけで、初期値をNoneにはしない)
>>> otsuhachi.hobby
Traceback (most recent call last):
...
AttributeError: 'Student' object has no attribute '_hobby'

# 失敗 (不正な値)
>>> otsuhachi.hobby = 1
Traceback (most recent call last):
...
TypeError: list型である必要があります。(1: int)

# 失敗 (リスト内の値が不正)
>>> otsuhachi.hobby = [1]
Traceback (most recent call last):
...
TypeError: str型である必要があります。(1: int)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
...
TypeError: インデックス0は不正な値です。(1: int)

# 成功
>>> otsuhachi.hobby = None
>>> print(otsuhachi.hobby)
None

# 成功
>>> otsuhachi.hobby = ['PC', 'game']
>>> otsuhachi.hobby
['PC', 'game']

# 失敗 (不正な値を追加後に参照)
>>> otsuhachi.hobby.append(1)
>>> otsuhachi.hobby
Traceback (most recent call last):
...
TypeError: str型である必要があります。(1: int)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
...
TypeError: インデックス2は不正な値です。(1: int)
```


<!-- omit in toc -->
#### バリデータ実行例-addressの操作

[目次](#バリデータの実行例目次)に戻る

`otsuhachi.address`を操作します。  
`Student`の`address`属性は`CNoneable(VList([VRegex('^\\d{3}-?\\d{4}$'), VRegex('(?!.*\\d.*)')`によって検証されます。  
基本的な失敗例、成功例は[hobby](#バリデータ実行例-hobbyの操作)を参照してください。  
`address`属性の特殊な点は`VList`の`TEMPLATE`が`list型`である点です。  

`value[i]`が`TEMPLATE[i]`でそれぞれ検証されます。

```python

# 失敗 (要素数が足りていない)
>>> otsuhachi.address = []
Traceback (most recent call last):
...
ValueError: あと3個設定する必要があります。([]: list)

# 失敗 (要素数が多い)
>>> otsuhachi.address = ['', '', '', '']
Traceback (most recent call last):
...
ValueError: あと1個減らす必要があります。(['', '', '', '']: list)

# 失敗 (不正な値)
>>> otsuhachi.address = ['0000000000', 'Otsu Prefecture2', 'OtsuCity']
Traceback (most recent call last):
...
ValueError: 正規表現'^\\d{3}-?\\d{4}$'に対応している必要があります。('0000000000': str)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
...
ValueError: インデックス0は不正な値です。('0000000000': str)

# 失敗 (不正な値)
>>> otsuhachi.address = ['282-2828', 'Otsu Prefecture2', 'OtsuCity']
Traceback (most recent call last):
...
ValueError: 正規表現'(?!.*\\d.*)'に対応している必要があります。('Otsu Prefecture2': str)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
...
ValueError: インデックス1は不正な値です。('Otsu Prefecture2': str)


# 成功
>>> otsuhachi.address = ['282-2828', 'Otsu Prefecture', 'OtsuCity']
>>> otsuhachi.address
['282-2828', 'Otsu Prefecture', 'OtsuCity']
```

<!-- omit in toc -->
#### バリデータ実行例-成功

[目次](#バリデータの実行例目次)に戻る

すべてのバリデータでの検証が終われば、設計通りにクラスが動作します。

```python

>>> otsuhachi.name = 'Otsuhachi'
>>> otsuhachi.age = 28
>>> otsuhachi.gender = 'male'
>>> otsuhachi.grades = {'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66, 'Math2': 56}}
>>> otsuhachi.hobby = ['PC', 'game']
>>> otsuhachi.address = ['282-2828', 'Otsu Prefecture', 'OtsuCity']
>>> otsuhachi.show_profile()
名前: Otsuhachi
年齢: 28
性別: male
国語: 68
社会: 28
数学: {'Math1': 66, 'Math2': 56}
趣味: ['PC', 'game']
住所: ['282-2828', 'Otsu Prefecture', 'OtsuCity']
```

## コンバータの変換

基本的にコンバータは`C<対象の型名>`で、`<対象の型>(value)`で変換できるかどうかを試すのが基本になります。  
たとえば`CString`ならば`str(value)`を試みてから検証を行います。
しかし、コンバータによってはその基本に従わないものがあります。  
`CInt`は、`int(value)`できなかった場合に`int(float(value))`を試します(`CFloat`はその逆の動作です)。  
これはまだ理解しやすい変換ですが、以下の2つのコンバータは若干特殊な挙動の変換を行います。  
これは`json`ファイルや`標準入力`などで受け取った場合の変換処理を容易に行うためです。

<!-- omit in toc -->
### CTimedelta

このコンバータは`str`, `dict`, `list`, `tuple`いずれかの型である場合に`Timedelta`型に変換を試みます。  
変換に必要な形式は以下の通りです。

型|形式
:--|:--
str|`(<日>( )day(s, ))<時>:<分>:<秒>(.<ミリ秒>)`<br>`()`で囲まれた部分の有無は任意<br>要は`str(<timedeltaインスタンス>)`で変換された後の形式(厳密には日と時間の間の空白を問わないなど若干異なる)
dict|`timedelta(**value)`でインスタンスを生成できる形式
list, tuple|`timedelta(*value)`でインスタンスを生成できる形式

<!-- omit in toc -->
### CBool

このコンバータは以下の標準定義の項目を`bool`に変換します。  
また、自分で`True`になる値、`False`になる値を設定することも可能です。  
さらに、`f(value)`が真偽値を返す関数`f`のタプルを渡して判定することも可能です。

以下が標準定義の真偽値対応表です。
`str`型は`value.lower()`されたあとで判定されるので、大文字小文字を問いません。

型|True|False
:--:|:--:|:--:
bool|True|False
str|'true', 'yes', 'y', '1'|'false', 'no', 'n', '0'
int|1|0
float|1.0|0.0

### 実行例-コンバータ


```python

from datetime import timedelta
from typing import cast

from otsuvalidator import CBool, CTimedelta


class SampleClass:
    bool_dflt: bool = cast(bool, CBool())
    bool_user: bool = cast(bool, CBool(true_data=('はい', ), false_data=('いいえ', )))
    td_timedelta: timedelta = cast(timedelta, CTimedelta())
    td_str: timedelta = cast(timedelta, CTimedelta())
    td_tuple: timedelta = cast(timedelta, CTimedelta())
    td_dict: timedelta = cast(timedelta, CTimedelta())

    def show(self):
        keys = (
            'bool_dflt',
            'bool_user',
            'td_timedelta',
            'td_str',
            'td_tuple',
            'td_dict',
        )
        for k in keys:
            v = getattr(self, k)
            print(f'{k}: {v}({type(v).__name__})')


s = SampleClass()
td = timedelta(days=1, seconds=2, microseconds=3, milliseconds=4, minutes=5, hours=6, weeks=7)
# s.bool_dflt = 'はい'  # Error

# 一般にYes/Noとして解釈されるものはboolに変換
s.bool_dflt = 'yes'

# ユーザ定義のTrueなのでTrueになる
s.bool_user = 'はい'

# 無変換でtimedelta
s.td_timedelta = td

# 特定形式の文字列をtimedeltaに変換
s.td_str = '50 days, 0:0:1'

# 特定形式のタプル、リストをtimedeltaに変換
s.td_tuple = (1, 2, 3, 4, 5, 7)

# 特定形式の辞書をtimedeltaに変換
s.td_dict = {'seconds': 2, 'microseconds': 3, 'milliseconds': 4, 'minutes': 5, 'hours': 6}

# 属性名: str(属性)(属性の型)を出力
s.show()
```

```console

bool_dflt: True(bool)
bool_user: True(bool)
td_timedelta: 50 days, 6:05:02.004003(timedelta)
td_str: 50 days, 0:00:01(timedelta)
td_tuple: 1 day, 7:05:02.004003(timedelta)
td_dict: 6:05:02.004003(timedelta)
```


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/Otsuhachi/OtsuValidator",
    "name": "otsuvalidator",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "",
    "keywords": "Python validator descriptor converter",
    "author": "Otsuhachi",
    "author_email": "agequodagis.tufuiegoeris@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/80/f9/d9f6305829e0153afd4cba320fed242e003c6c422dfaf9b3287eff2b00bb/otsuvalidator-2.0.1.tar.gz",
    "platform": null,
    "description": "- [\u6982\u8981](#\u6982\u8981)\r\n  - [\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb](#\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb)\r\n  - [\u30e2\u30b8\u30e5\u30fc\u30eb](#\u30e2\u30b8\u30e5\u30fc\u30eb)\r\n  - [\u7d99\u627f\u898f\u5247](#\u7d99\u627f\u898f\u5247)\r\n  - [\u5b9f\u884c\u4f8b-\u30d0\u30ea\u30c7\u30fc\u30bf](#\u5b9f\u884c\u4f8b-\u30d0\u30ea\u30c7\u30fc\u30bf)\r\n  - [\u30b3\u30f3\u30d0\u30fc\u30bf\u306e\u5909\u63db](#\u30b3\u30f3\u30d0\u30fc\u30bf\u306e\u5909\u63db)\r\n    - [\u5b9f\u884c\u4f8b-\u30b3\u30f3\u30d0\u30fc\u30bf](#\u5b9f\u884c\u4f8b-\u30b3\u30f3\u30d0\u30fc\u30bf)\r\n\r\n# \u6982\u8981\r\n\r\n\u3053\u306e\u30e9\u30a4\u30d6\u30e9\u30ea\u306f\u5024\u306e\u6b63\u5e38\u6027\u3092\u691c\u8a3c\u3059\u308b\u30d0\u30ea\u30c7\u30fc\u30bf\u7fa4\u3068\u3001\u691c\u8a3c\u524d\u306b\u578b\u5909\u63db\u3092\u8a66\u307f\u308b\u30b3\u30f3\u30d0\u30fc\u30bf\u7fa4\u3067\u3059\u3002  \r\n\u30c7\u30a3\u30b9\u30af\u30ea\u30d7\u30bf\u3068\u3057\u3066\u4f7f\u7528\u3059\u308b\u3053\u3068\u3067\u5c5e\u6027\u306b\u4e0d\u6b63\u306a\u5024\u304c\u4ee3\u5165\u3055\u308c\u308b\u306e\u3092\u9632\u6b62\u3057\u307e\u3059\u3002  \r\n\u307e\u305f\u3001\u5358\u72ec\u3067\u4f7f\u7528\u3059\u308b\u3053\u3068\u3082\u53ef\u80fd\u3067\u3059\u3002  \r\n\r\n\u3053\u306e\u30e9\u30a4\u30d6\u30e9\u30ea\u306f\u4ee5\u4e0b\u306e\u74b0\u5883\u3067\u4f5c\u6210\u3055\u308c\u3066\u3044\u307e\u3059\u3002  \r\n`Windows10(64bit)`, `Python3.8.10`  \r\n\r\n## \u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\r\n\r\n\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\r\n\r\n`pip install otsuvalidator`\r\n\r\n\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\r\n\r\n`pip install -U otsuvalidator`\r\n\r\n\u30a2\u30f3\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\r\n\r\n`pip uninstall otsuvalidator`\r\n\r\n## \u30e2\u30b8\u30e5\u30fc\u30eb\r\n\r\n\u30e2\u30b8\u30e5\u30fc\u30eb\u306f\u4ee5\u4e0b\u306e3\u3064\u304c\u5b58\u5728\u3057\u307e\u3059\u3002\r\n\r\n\u30e2\u30b8\u30e5\u30fc\u30eb\u540d|\u6982\u8981\r\n:--:|--\r\n[bases](#bases\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u30af\u30e9\u30b9)|\u30d0\u30ea\u30c7\u30fc\u30bf\u3001\u30b3\u30f3\u30d0\u30fc\u30bf\u306e\u57fa\u5e95\u30af\u30e9\u30b9\u304c\u5b9a\u7fa9\u3055\u308c\u3044\u308b<br>\u81ea\u4f5c\u306e\u30d0\u30ea\u30c7\u30fc\u30bf\u3092\u5b9a\u7fa9\u3059\u308b\u3068\u304d\u306b\u4f7f\u7528\u3067\u304d\u308b\r\n[validators](#validators\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u30af\u30e9\u30b9)|\u30d0\u30ea\u30c7\u30fc\u30bf\u304c\u5b9a\u7fa9\u3055\u308c\u3066\u3044\u308b\r\n[converters](#converters\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u30af\u30e9\u30b9)|\u30b3\u30f3\u30d0\u30fc\u30bf\u304c\u5b9a\u7fa9\u3055\u308c\u3066\u3044\u308b\r\n\r\n\r\nomit in toc\r\n<!-- omit in toc -->\r\n### bases\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u30af\u30e9\u30b9\r\n\r\n`Validator`\u3068\u8868\u8a18\u3055\u308c\u3066\u3044\u308b\u90e8\u5206\u306b\u95a2\u3057\u3066\u306f\u3001\u30d0\u30ea\u30c7\u30fc\u30bf\u3001\u30b3\u30f3\u30d0\u30fc\u30bf\u4e21\u65b9\u3092\u6307\u3057\u307e\u3059\u3002\r\n\r\n\u30af\u30e9\u30b9|\u6982\u8981\r\n:--:|:--\r\nValidator|\u3059\u3079\u3066\u306e\u30d0\u30ea\u30c7\u30fc\u30bf\u3001\u30b3\u30f3\u30d0\u30fc\u30bf\u306e\u57fa\u5e95\u30af\u30e9\u30b9\r\nVContainer|\u30b3\u30f3\u30c6\u30ca\u7528\u306e\u30d0\u30ea\u30c7\u30fc\u30bf\u306e\u57fa\u5e95\u30af\u30e9\u30b9<br>\u4e2d\u8eab\u304c\u53ef\u5909\u306a\u30af\u30e9\u30b9\u306e\u30d0\u30ea\u30c7\u30fc\u30bf\u3092\u5b9a\u7fa9\u3059\u308b\u3068\u304d\u306b\u4f7f\u7528\u3059\u308b\r\nConverter|\u30b3\u30f3\u30d0\u30fc\u30bf\u306e\u57fa\u5e95\u30af\u30e9\u30b9<br>\u30bb\u30ad\u30e5\u30a2\u3055\u304c\u91cd\u8996\u3055\u308c\u308b\u5834\u9762\u3067\u306f\u4f7f\u7528\u3057\u306a\u3044\r\nCNoneable|`Validator`\u65e2\u5b9a\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306b\u52a0\u3048\u3001`None`\u3092\u8a31\u53ef\u3059\u308b<br>\u5909\u63db\u306e\u53ef\u5426\u306f\u4ee5\u4e0b\u306e2\u70b9\u306b\u4f9d\u5b58\u3059\u308b<br>-\u6e21\u3057\u305f`Validator`\u304c\u30b3\u30f3\u30d0\u30fc\u30bf\u304b\u5426\u304b<br>-\u6240\u5c5e\u3059\u308b`VContainer`\u306e`allow_convert`\u30aa\u30d7\u30b7\u30e7\u30f3\r\nCNumerical|\u6570\u5024\u578b\u7528\u30b3\u30f3\u30d0\u30fc\u30bf\u306e\u57fa\u5e95\u30af\u30e9\u30b9<br>`value`\u306b\u5bfe\u3057\u3001`int`\u5909\u63db\u3001`float`\u5909\u63db\u3092\u8a66\u307f\u308b\u30e1\u30bd\u30c3\u30c9\u304c\u5b9a\u7fa9\u3055\u308c\u3066\u3044\u308b<br>`complex`\u306f\u60f3\u5b9a\u3055\u308c\u3066\u3044\u306a\u3044\r\n\r\n<!-- omit in toc -->\r\n### validators\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u30af\u30e9\u30b9\r\n\r\n\u30b9\u30fc\u30d1\u30fc\u30af\u30e9\u30b9\u306e\u8868\u8a18\u304c\u306a\u3044\u3082\u306e\u306f`Validator`\u3092\u7d99\u627f\u3057\u3066\u3044\u307e\u3059\u3002\r\n\r\n\u30af\u30e9\u30b9|\u30b9\u30fc\u30d1\u30fc\u30af\u30e9\u30b9|\u6982\u8981|\u671f\u5f85\u3059\u308b\u578b\r\n:--:|:--:|:--|:--:\r\nVBool||\u771f\u507d\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u304b|bool\r\nVChoice||\u9078\u629e\u80a2\u306e\u4e2d\u304b\u30891\u3064\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u308b\u304b|Any\r\nVNumber||\u9069\u5207\u306a\u6570\u5024\u304b|int,flaot\r\nVFloat|VNumber|\u9069\u5207\u306a\u6d6e\u52d5\u5c0f\u6570\u70b9\u6570\u304b|flaot\r\nVInt|VNumber|\u9069\u5207\u306a\u6574\u6570\u304b|int\r\nVPath||\u9069\u5207\u306a\u30d1\u30b9\u304b|pathlib.Path\r\nVString||\u9069\u5207\u306a\u6587\u5b57\u5217\u304b|str\r\nVRegex|VString|\u6b63\u898f\u8868\u73fe\u306b\u30de\u30c3\u30c1\u3059\u308b\u9069\u5207\u306a\u6587\u5b57\u5217\u304b|str\r\nVDict|VContainer|\u9069\u5207\u306a\u8f9e\u66f8\u304b|dict\r\nVList|VContainer|\u9069\u5207\u306a\u30ea\u30b9\u30c8\u304b|list\r\nVTuple|VContaner|\u9069\u5207\u306a\u30bf\u30d7\u30eb\u304b|tuple\r\nVTimedelta||\u9069\u5207\u306a\u7d4c\u904e\u6642\u9593\u578b\u304b|datetime.timedelta\r\n\r\n<!-- omit in toc -->\r\n### converters\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u30af\u30e9\u30b9\r\n\r\n\u30b9\u30fc\u30d1\u30fc\u30af\u30e9\u30b9\u306b\u30b3\u30f3\u30d0\u30fc\u30bf\u304c\u8a18\u8f09\u3055\u308c\u3066\u3044\u306a\u3044\u30af\u30e9\u30b9\u306f`Converter`\u3092\u7d99\u627f\u3057\u3066\u3044\u307e\u3059\u3002\r\n\r\n\u30af\u30e9\u30b9|\u30b9\u30fc\u30d1\u30fc\u30af\u30e9\u30b9|\u6982\u8981\r\n:--:|:--:|:--\r\nCBool|VBool,Converter|\u4e00\u822c\u306b**Yes/No\u3068\u3057\u3066\u89e3\u91c8\u3067\u304d\u308b\u5024**\u306b\u5bfe\u3057\u3001bool\u5909\u63db\u3092\u8a66\u307f\u3001\u691c\u8a3c\u3092\u884c\u3046<br>`bool(value)`\u3067\u306f`True`\u306b\u306a\u308b\u3082\u306e\u304c`False`\u306b\u306a\u3063\u305f\u308a\u4f8b\u5916\u304c\u767a\u751f\u3057\u305f\u308a\u3059\u308b\r\nCNumber|VNumber, CNumerical|`int`,`float`\u578b\u3078\u306e\u5909\u63db\u3092\u8a66\u307f\u3001\u691c\u8a3c\u3092\u884c\u3046\r\nCFloat|VFloat, CNumerical|`float`\u578b\u3078\u306e\u5909\u63db\u3092\u8a66\u307f\u3001\u691c\u8a3c\u3092\u884c\u3046\r\nCInt|VInt, CNumerical|`int`\u578b\u3078\u306e\u5909\u63db\u3092\u8a66\u307f\u3001\u691c\u8a3c\u3092\u884c\u3046\r\nCPath|VPath, Converter|`Path`\u578b\u3078\u306e\u5909\u63db\u3092\u8a66\u307f\u3001\u691c\u8a3c\u3092\u884c\u3046\r\nCString|VString, Converter|`str`\u578b\u3078\u306e\u5909\u63db\u3092\u8a66\u307f\u3001\u691c\u8a3c\u3092\u884c\u3046\r\nCTimedelta|VTimedelta, Converter|`datetime.timedelta`\u578b\u3078\u306e\u5909\u63db\u3092\u8a66\u307f\u3001\u691c\u8a3c\u3092\u884c\u3046\r\n\r\n## \u7d99\u627f\u898f\u5247\r\n\r\n\u304d\u3061\u3093\u3068\u52d5\u4f5c\u3059\u308b\u30d0\u30ea\u30c7\u30fc\u30bf\u3001\u30b3\u30f3\u30d0\u30fc\u30bf\u3092\u5b9a\u7fa9\u3059\u308b\u305f\u3081\u306e\u898f\u5247\u3067\u3059\u3002  \r\n`CNoneable`\u306f**\u7d99\u627f\u3057\u306a\u3044\u3067\u304f\u3060\u3055\u3044\u3002**\r\n\r\n<!-- no toc -->\r\n-   [Validator\u7d99\u627f\u898f\u5247](#validator\u7d99\u627f\u898f\u5247)\r\n-   [VContainer\u7d99\u627f\u898f\u5247](#vcontainer\u7d99\u627f\u898f\u5247)\r\n-   [Converter\u7d99\u627f\u898f\u5247](#converter\u7d99\u627f\u898f\u5247)\r\n\r\n<!-- omit in toc -->\r\n### Validator\u7d99\u627f\u898f\u5247\r\n\r\n\u898f\u5247|\u6982\u8981|\u7406\u7531\r\n:--:|:--|:--\r\n\u547d\u540d|\u30af\u30e9\u30b9\u540d\u306f`V{\u691c\u8a3c\u3057\u305f\u3044\u30af\u30e9\u30b9\u540d}`\u3068\u3059\u308b|\u7ba1\u7406\u306e\u3057\u3084\u3059\u3055\r\n\u7d99\u627f|`Validator`\u3092\u7d99\u627f\u3059\u308b|\r\n\u5b9a\u7fa9|`validate`\u30e1\u30bd\u30c3\u30c9\u3092\u5b9a\u7fa9\u3057\u3001\u691c\u8a3c\u304c\u901a\u3063\u305f\u5834\u5408\u306b\u306f`value`\u3092\u8fd4\u3059|\u62e1\u5f35\u3057\u3066\u30b3\u30f3\u30d0\u30fc\u30bf\u3092\u5b9a\u7fa9\u3059\u308b\u3068\u304d\u306b\u5fc5\u8981\r\n\u5909\u63db|`value`\u306e\u578b\u3092\u5909\u63db\u3057\u306a\u3044|\u5909\u63db\u3068\u691c\u8a3c\u3092\u884c\u3046\u5834\u5408\u306f\u30b3\u30f3\u30d0\u30fc\u30bf\u3092\u4f7f\u7528\u3059\u308b\r\n\r\n<!-- omit in toc -->\r\n### VContainer\u7d99\u627f\u898f\u5247\r\n\r\n\u898f\u5247|\u6982\u8981|\u7406\u7531|\r\n:--:|:--|:--\r\n\u547d\u540d|\u30af\u30e9\u30b9\u540d\u306f`V<\u691c\u8a3c\u3057\u305f\u3044\u30af\u30e9\u30b9\u540d>`\u3068\u3059\u308b|\u7ba1\u7406\u306e\u3057\u3084\u3059\u3055<br>\u672c\u8cea\u7684\u306b\u306fValidator\u3068\u5909\u308f\u3089\u306a\u3044\u306e\u3067\u898f\u5247\u3082\u305d\u306e\u307e\u307e\u9069\u7528\r\n\u7d99\u627f|`VContainer`\u3092\u7d99\u627f\u3059\u308b|\r\n\u5b9a\u7fa9|`validate`\u30e1\u30bd\u30c3\u30c9\u3092\u5b9a\u7fa9\u3057\u3001\u691c\u8a3c\u304c\u901a\u3063\u305f\u5834\u5408\u306b\u306f`value`\u3092\u8fd4\u3059<br>\u5909\u63db\u3092\u8a31\u53ef\u3059\u308b\u5834\u5408\u3001`TEMPLATE`\u304c`Validator`\u4ee5\u5916\u306e\u5834\u5408\u306a\u3069\u7d30\u304b\u306a\u9055\u3044\u3092\u8a2d\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b|\u30b3\u30f3\u30c6\u30ca\u305d\u306e\u3082\u306e\u306e\u691c\u8a3c\u3068\u4e2d\u8eab\u306e\u691c\u8a3c\u304c\u5fc5\u8981\r\n\u5909\u63db|`value`\u306e\u578b\u3092\u5909\u63db\u3057\u306a\u3044<br>`value`\u306e\u5404\u8981\u7d20`v`\u306b\u5bfe\u3057\u3066\u306f\u30aa\u30d7\u30b7\u30e7\u30f3\u6b21\u7b2c|`TEMPLATE`\u306b\u30b3\u30f3\u30d0\u30fc\u30bf\u3092\u6e21\u3057\u3066\u3044\u308b\u5834\u5408\u3001\u7981\u6b62\u3055\u308c\u3066\u3044\u306a\u3044\u9650\u308a\u5909\u63db\u3092\u884c\u3046\u306e\u304c\u81ea\u7136\u306a\u305f\u3081\r\n\r\n<!-- omit in toc -->\r\n### Converter\u7d99\u627f\u898f\u5247\r\n\r\n`CNumerical`\u306b\u3064\u3044\u3066\u3082\u3053\u3053\u306b\u5f93\u3063\u3066\u304f\u3060\u3055\u3044\u3002\r\n\r\n\u898f\u5247|\u6982\u8981|\u7406\u7531\r\n:--:|:--|:--\r\n\u547d\u540d|\u30af\u30e9\u30b9\u540d\u306f`C<\u5909\u63db\u691c\u8a3c\u3057\u305f\u3044\u30af\u30e9\u30b9\u540d>`\u3068\u3059\u308b|\u4e00\u76ee\u3067\u5909\u63db\u3092\u884c\u3046\u30af\u30e9\u30b9\u3068\u8a8d\u8b58\u3059\u308b\u305f\u3081\r\n\u7d99\u627f|`(\u691c\u8a3c\u3057\u305f\u3044\u30af\u30e9\u30b9\u306e\u30d0\u30ea\u30c7\u30fc\u30bf,\u30b3\u30f3\u30d0\u30fc\u30bf)`\u3092\u7d99\u627f\u3059\u308b|`\u691c\u8a3c\u3057\u305f\u3044\u30af\u30e9\u30b9\u306e\u30d0\u30ea\u30c7\u30fc\u30bf.validate`\u30e1\u30bd\u30c3\u30c9\u3092`validate`\u30e1\u30bd\u30c3\u30c9\u5185\u3067\u547c\u3073\u51fa\u3059\u305f\u3081\r\n\u5b9a\u7fa9|`validate`\u30e1\u30bd\u30c3\u30c9\u3092\u5b9a\u7fa9\u3057\u3001\u5909\u63db\u691c\u8a3c\u304c\u901a\u3063\u305f\u5834\u5408\u306b\u306f\u5909\u63db\u3055\u308c\u305f`value`\u3092\u8fd4\u3059<br>`super_validate`\u30e1\u30bd\u30c3\u30c9\u3092\u5b9a\u7fa9\u3057\u3001`\u691c\u8a3c\u3057\u305f\u3044\u30af\u30e9\u30b9.validate`\u30e1\u30bd\u30c3\u30c9\u3092\u884c\u3048\u308b\u3088\u3046\u306b\u3059\u308b|VContainer\u306a\u3069\u3001\u5909\u63db\u3092\u8a31\u53ef\u3057\u305f\u304f\u306a\u3044\u72b6\u6cc1\u3067\u306f`super_validate`\u3092\u4f7f\u7528\u3059\u308b\u305f\u3081\r\n\u5909\u63db|`validate`\u30e1\u30bd\u30c3\u30c9\u5185\u3067\u5909\u63db\u3092\u8a66\u307f\u308b<br>`super_validate`\u30e1\u30bd\u30c3\u30c9\u3067\u306f\u5909\u63db\u3057\u306a\u3044|\u5b9a\u7fa9\u3067\u66f8\u3044\u305f\u901a\u308a\u7121\u5909\u63db\u304c\u5fc5\u8981\u306b\u306a\u308b\u5834\u9762\u3082\u3042\u308b\u305f\u3081\r\n\r\n## \u5b9f\u884c\u4f8b-\u30d0\u30ea\u30c7\u30fc\u30bf\r\n\r\n<!-- omit in toc -->\r\n### \u30d0\u30ea\u30c7\u30fc\u30bf\u306e\u5b9f\u884c\u4f8b\r\n\r\n\u30d0\u30ea\u30c7\u30fc\u30bf\u3092\u30c7\u30a3\u30b9\u30af\u30ea\u30d7\u30bf\u3068\u3057\u3066\u4f7f\u7528\u3057\u3066\u3044\u308b`Student`\u30af\u30e9\u30b9\u3092\u8a66\u3057\u306b\u4f7f\u7528\u3057\u307e\u3059\u3002\r\n<!-- omit in toc -->\r\n#### \u30d0\u30ea\u30c7\u30fc\u30bf\u306e\u5b9f\u884c\u4f8b\u76ee\u6b21\r\n\r\n<!-- no toc -->\r\n- [\u524d\u63d0\u30b3\u30fc\u30c9](#\u30d0\u30ea\u30c7\u30fc\u30bf\u5b9f\u884c\u4f8b-\u524d\u63d0\u30b3\u30fc\u30c9)\r\n- [name\u306e\u64cd\u4f5c](#\u30d0\u30ea\u30c7\u30fc\u30bf\u5b9f\u884c\u4f8b-name\u306e\u64cd\u4f5c)\r\n- [age\u306e\u64cd\u4f5c](#\u30d0\u30ea\u30c7\u30fc\u30bf\u5b9f\u884c\u4f8b-age\u306e\u64cd\u4f5c)\r\n- [gender\u306e\u64cd\u4f5c](#\u30d0\u30ea\u30c7\u30fc\u30bf\u5b9f\u884c\u4f8b-gender\u306e\u64cd\u4f5c)\r\n- [grades\u306e\u64cd\u4f5c](#\u30d0\u30ea\u30c7\u30fc\u30bf\u5b9f\u884c\u4f8b-grades\u306e\u64cd\u4f5c)\r\n- [hobby\u306e\u64cd\u4f5c](#\u30d0\u30ea\u30c7\u30fc\u30bf\u5b9f\u884c\u4f8b-hobby\u306e\u64cd\u4f5c)\r\n- [address\u306e\u64cd\u4f5c](#\u30d0\u30ea\u30c7\u30fc\u30bf\u5b9f\u884c\u4f8b-address\u306e\u64cd\u4f5c)\r\n- [\u6210\u529f](#\u30d0\u30ea\u30c7\u30fc\u30bf\u5b9f\u884c\u4f8b-\u6210\u529f)\r\n\r\n<!-- omit in toc -->\r\n#### \u30d0\u30ea\u30c7\u30fc\u30bf\u5b9f\u884c\u4f8b-\u524d\u63d0\u30b3\u30fc\u30c9\r\n\r\n[\u76ee\u6b21](#\u30d0\u30ea\u30c7\u30fc\u30bf\u306e\u5b9f\u884c\u4f8b\u76ee\u6b21)\u306b\u623b\u308b\r\n\r\n\u8aac\u660e\u306f\u4ee5\u4e0b\u306e\u6761\u4ef6\u3092\u6e80\u305f\u3057\u305f\u74b0\u5883\u3067\u5b9f\u884c\u3055\u308c\u308b\u3053\u3068\u3092\u60f3\u5b9a\u3057\u3066\u3044\u307e\u3059\u3002\r\n\r\n1. Python3.8\u4ee5\u4e0a\u304c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u305fWindows\r\n2. \u672c\u30e9\u30a4\u30d6\u30e9\u30ea\u304c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u3066\u3044\u308b\r\n3. \u4ee5\u4e0b\u306e`test.py`\u30d5\u30a1\u30a4\u30eb\u3092\u751f\u6210\u3057\u3001`py -i test.py`\u3001\u307e\u305f\u306f`\u5bfe\u8a71\u30e2\u30fc\u30c9`\u3067\u4ee5\u4e0b\u306e\u30b3\u30fc\u30c9\u304c\u5165\u529b\u3055\u308c\u3066\u3044\u308b\r\n\r\n```python\r\n# test.py\r\nfrom otsuvalidator import (CNoneable, VChoice, VDict, VInt, VList, VRegex, VString)\r\n\r\n\r\nclass Student:\r\n    name = VString(1, 50, checker=str.istitle)  # 1\u6587\u5b57\u4ee5\u4e0a50\u6587\u5b57\u4ee5\u4e0b, str.istitle\u304cTrue\u306b\u306a\u308b\u6587\u5b57\u5217\r\n    age = VInt(0, 150)  # 0\u4ee5\u4e0a150\u4ee5\u4e0b\u306e\u6574\u6570\r\n    gender = VChoice('male', 'female', 'others')  # (male, female, others)\u306e\u3044\u305a\u308c\u304b\r\n    grades = VDict(\r\n        # \u4ee5\u4e0b\u306e\u69cb\u9020\u3092\u6301\u3064\u8f9e\u66f8, \u30ad\u30fc\u6b20\u843d\u4e0d\u53ef, \u30a2\u30af\u30bb\u30b9\u6642\u306b\u518d\u691c\u8a3c\u3092\u884c\u308f\u306a\u3044\r\n        {\r\n            'Japanese':\r\n            VInt(0, 100),  # 0\u4ee5\u4e0a100\u4ee5\u4e0b\u306e\u6574\u6570\r\n            'Social Studies':\r\n            VInt(0, 100),\r\n            'Math':\r\n            VDict(\r\n                # \u4ee5\u4e0b\u306e\u30ad\u30fc\u3092\u6301\u3064\u8f9e\u66f8, \u30ad\u30fc\u6b20\u843d\u53ef, \u30a2\u30af\u30bb\u30b9\u6642\u306b\u518d\u691c\u8a3c\u3092\u884c\u3046\r\n                {\r\n                    'Math1': VInt(0, 100),\r\n                    'Math2': VInt(0, 100)\r\n                },\r\n                allow_missing_key=True,\r\n                monitoring_overwrite=True,\r\n            )\r\n        },\r\n        allow_missing_key=False,\r\n        monitoring_overwrite=False,\r\n    )\r\n    # 1\u6587\u5b57\u4ee5\u4e0a\u306e\u6587\u5b57\u5217\u3060\u3051\u306e\u30ea\u30b9\u30c8 None\u3067\u7121\u56de\u7b54\u53ef \u8981\u7d20\u6570\u306f\u7121\u5236\u9650\r\n    hobby = CNoneable(VList(VString(1)))\r\n    # [\u90f5\u4fbf\u756a\u53f7, \u90fd\u9053\u5e9c\u770c, \u5e02\u753a\u6751\u7fa4]\u306e\u30ea\u30b9\u30c8 None\u3067\u7121\u56de\u7b54\u53ef\r\n    address = CNoneable(VList([VRegex('^\\\\d{3}-?\\\\d{4}$'), VRegex('(?!.*\\\\d.*)'), VRegex('(?!.*\\\\d.*)')]))\r\n\r\n    def show_profile(self):\r\n        name = self.name\r\n        age = self.age\r\n        gender = self.gender\r\n        grades = self.grades\r\n        japanese = grades['Japanese']\r\n        social = grades['Social Studies']\r\n        math = grades['Math']\r\n        hobby = self.hobby\r\n        address = self.address\r\n        profiles = ('\u540d\u524d', '\u5e74\u9f62', '\u6027\u5225', '\u56fd\u8a9e', '\u793e\u4f1a', '\u6570\u5b66', '\u8da3\u5473', '\u4f4f\u6240')\r\n        profile_values = (name, age, gender, japanese, social, math, hobby, address)\r\n        for title, value in zip(profiles, profile_values):\r\n            print(f'{title}: {value}')\r\n\r\n\r\notsuhachi = Student()\r\n```\r\n\r\n<!-- omit in toc -->\r\n#### \u30d0\u30ea\u30c7\u30fc\u30bf\u5b9f\u884c\u4f8b-name\u306e\u64cd\u4f5c\r\n\r\n[\u76ee\u6b21](#\u30d0\u30ea\u30c7\u30fc\u30bf\u306e\u5b9f\u884c\u4f8b\u76ee\u6b21)\u306b\u623b\u308b\r\n\r\n`otsuhachi.name`\u3092\u64cd\u4f5c\u3057\u307e\u3059\u3002  \r\n`Student`\u306e`name`\u5c5e\u6027\u306f`VString(1, checker=str.istitle)`\u306b\u3088\u3063\u3066\u691c\u8a3c\u3055\u308c\u307e\u3059\u3002\r\n\r\n```python\r\n\r\n# \u5931\u6557 (\u578b\u304c\u7570\u306a\u308b)\r\n>>> otsuhachi.name = 28\r\nTraceback (most recent call last):\r\n...\r\nTypeError: \u5c5e\u6027'name'\u306fstr\u578b\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002(28: int)\r\n\r\n# \u5931\u6557 (\u6700\u4f4e\u6587\u5b57\u6570\u3092\u6e80\u305f\u3057\u3066\u3044\u306a\u3044)\r\n>>> otsuhachi.name = ''\r\nTraceback (most recent call last):\r\n...\r\nValueError: \u5c5e\u6027'name'\u306f1\u6587\u5b57\u4ee5\u4e0a\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002('': str)\r\n\r\n# \u5931\u6557 (\u6700\u5927\u6587\u5b57\u6570\u3092\u8d85\u904e\u3057\u3066\u3044\u308b)\r\n>>> otsuhachi.name = 'A' + ('a' * 100)\r\nTraceback (most recent call last):\r\n...\r\nValueError: \u5c5e\u6027'name'\u306f50\u6587\u5b57\u4ee5\u4e0b\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002('Aaaaaaaaa...aaaaaaaaa': str)\r\n\r\n# \u5931\u6557 (checker\u304cTrue\u3092\u8fd4\u3055\u306a\u3044)\r\n>>> otsuhachi.name = 'otsuhachi'\r\nTraceback (most recent call last):\r\n...\r\nValueError: \u5c5e\u6027'name'\u306f\u6307\u5b9a\u3057\u305f\u5f62\u5f0f\u306b\u5bfe\u5fdc\u3057\u3066\u3044\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002<method 'istitle' of 'str' objects>\u3002('otsuhachi': str)\r\n\r\n# \u6210\u529f\r\n>>> otsuhachi.name = 'Otsuhachi'\r\n>>> otsuhachi.name\r\n'Otsuhachi'\r\n```\r\n\r\n<!-- omit in toc -->\r\n#### \u30d0\u30ea\u30c7\u30fc\u30bf\u5b9f\u884c\u4f8b-age\u306e\u64cd\u4f5c\r\n\r\n[\u76ee\u6b21](#\u30d0\u30ea\u30c7\u30fc\u30bf\u306e\u5b9f\u884c\u4f8b\u76ee\u6b21)\u306b\u623b\u308b\r\n\r\n`otsuhachi.age`\u3092\u64cd\u4f5c\u3057\u307e\u3059\u3002  \r\n`Student`\u306e`age`\u5c5e\u6027\u306f`VInt(0)`\u306b\u3088\u3063\u3066\u691c\u8a3c\u3055\u308c\u307e\u3059\u3002\r\n\r\n```python\r\n\r\n#\u5931\u6557 (\u578b\u304c\u7570\u306a\u308b)\r\n>>> otsuhachi.age = 28.8\r\nTraceback (most recent call last):\r\n...\r\nTypeError: \u5c5e\u6027'age'\u306fint\u578b\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002(28.8: float)\r\n\r\n# \u5931\u6557 (\u6700\u5c0f\u5024\u672a\u6e80)\r\n>>> otsuhachi.age = -1\r\n...\r\nValueError: \u5c5e\u6027'age'\u306f0\u3088\u308a\u5c0f\u3055\u3044\u5024\u3092\u8a2d\u5b9a\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002(-1: int)\r\n\r\n# \u5931\u6557 (\u6700\u5927\u5024\u8d85\u904e)\r\n>>> otsuhachi.age = 280\r\nTraceback (most recent call last):\r\n...\r\nValueError: \u5c5e\u6027'age'\u306f150\u3088\u308a\u5927\u304d\u3044\u5024\u3092\u8a2d\u5b9a\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002(280: int)\r\n\r\n# \u6210\u529f\r\n>>> otsuhachi.age = 28\r\n>>> otsuhachi.age\r\n28\r\n```\r\n\r\n<!-- omit in toc -->\r\n#### \u30d0\u30ea\u30c7\u30fc\u30bf\u5b9f\u884c\u4f8b-gender\u306e\u64cd\u4f5c\r\n\r\n[\u76ee\u6b21](#\u30d0\u30ea\u30c7\u30fc\u30bf\u306e\u5b9f\u884c\u4f8b\u76ee\u6b21)\u306b\u623b\u308b\r\n\r\n`otsuhachi.gender`\u3092\u64cd\u4f5c\u3057\u307e\u3059\u3002  \r\n`Student`\u306e`gender`\u5c5e\u6027\u306f`VChoice('male', 'female', 'others')`\u306b\u3088\u3063\u3066\u691c\u8a3c\u3055\u308c\u307e\u3059\u3002\r\n\r\n\r\n```python\r\n\r\n# \u5931\u6557 (\u9078\u629e\u80a2\u306b\u306a\u3044\u5024)\r\n>>> otsuhachi.gender = None\r\nTraceback (most recent call last):\r\n...\r\nValueError: \u5c5e\u6027'gender'\u306f{'male', 'others', 'female'}\u306e\u3044\u305a\u308c\u304b\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002(None: NoneType)\r\n\r\n# \u5931\u6557 (\u9078\u629e\u80a2\u306b\u306a\u3044\u5024)\r\n>>> otsuhachi.gender = 'mal'\r\nTraceback (most recent call last):\r\n...\r\nValueError: \u5c5e\u6027'gender'\u306f{'male', 'others', 'female'}\u306e\u3044\u305a\u308c\u304b\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002('mal': str)\r\n\r\n# \u6210\u529f\r\n>>> otsuhachi.gender = 'others'\r\n>>> otsuhachi.gender\r\n'others'\r\n>>> otsuhachi.gender = 'female'\r\n>>> otsuhachi.gender\r\n'female'\r\n>>> otsuhachi.gender = 'male'\r\n>>> otsuhachi.gender\r\n'male'\r\n```\r\n\r\n<!-- omit in toc -->\r\n#### \u30d0\u30ea\u30c7\u30fc\u30bf\u5b9f\u884c\u4f8b-grades\u306e\u64cd\u4f5c\r\n\r\n[\u76ee\u6b21](#\u30d0\u30ea\u30c7\u30fc\u30bf\u306e\u5b9f\u884c\u4f8b\u76ee\u6b21)\u306b\u623b\u308b\r\n\r\n<!-- no toc -->\r\n- [grades\u306e\u6982\u8981](#grades\u306e\u6982\u8981)\r\n- [grades\u306e\u57fa\u672c\u7684\u306a\u5931\u6557\u3068\u6210\u529f\u306e\u4f8b](#grades\u306e\u57fa\u672c\u7684\u306a\u5931\u6557\u3068\u6210\u529f\u306e\u4f8b)\r\n- [grades\u3067\u8d77\u3053\u308a\u3048\u308b\u4e0d\u6b63](#grades\u3067\u8d77\u3053\u308a\u3048\u308b\u4e0d\u6b63)\r\n- [grades\u3067\u8d77\u3053\u308a\u3048\u308b\u4e0d\u6b63\u306e\u9632\u6b62](#grades\u3067\u8d77\u3053\u308a\u3048\u308b\u4e0d\u6b63\u306e\u9632\u6b62)\r\n\r\n`otsuhachi.garades`\u3092\u64cd\u4f5c\u3057\u307e\u3059\u3002  \r\n`Student`\u306e`grades`\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u5b9a\u7fa9\u3055\u308c\u305f\u30d0\u30ea\u30c7\u30fc\u30bf\u306b\u3088\u3063\u3066\u691c\u8a3c\u3055\u308c\u307e\u3059\u3002\r\n\r\n```python\r\n\r\nVDict(\r\n    {\r\n        'Japanese': VInt(0, 100),\r\n        'Social Studies': VInt(0, 100),\r\n        'Math': VDict(\r\n            {\r\n                'Math1': VInt(0, 100),\r\n                'Math2': VInt(0, 100)\r\n            },\r\n            allow_missing_key=True,\r\n            monitoring_overwrite=True,\r\n        )\r\n    },\r\n    allow_missing_key=False,\r\n    monitoring_overwrite=False,\r\n)\r\n```\r\n\r\n<!-- omit in toc -->\r\n##### grades\u306e\u6982\u8981\r\n\r\n\r\n\u5206\u89e3\u3057\u3066\u8003\u3048\u3066\u307f\u307e\u3059\u3002\r\n\r\n- grades\u304c\u6301\u3064\u3079\u304d\u30ad\u30fc\u306f(`Japanese`, `Social Studies`, `Math`)\u306e3\u3064\r\n   - `Japanese`\u3068`Social Studies`\u306f`0\uff5e100`\u306e\u6574\u6570\u5024\r\n   - `Math`\u306f(`Math1`, `Math2`)\u306e\u30ad\u30fc\u3092\u6301\u3064\u8f9e\u66f8\r\n      - `Math1`\u3068`Math2`\u306f`0\uff5e100`\u306e\u6574\u6570\u5024\r\n      - `allow_missing_key`\u304c`True`\u306a\u306e\u3067\u30ad\u30fc\u3092\u6301\u305f\u306a\u3044\u8f9e\u66f8\u3067\u3082\u53ef\r\n      - `monitoring_overwrite`\u306f`True`\u3067\u3082\u5b9f\u8cea\u7121\u95a2\u4fc2\r\n- `allow_missing_key`\u304c`False`\u306a\u306e\u3067\u3001\u30ad\u30fc\u3059\u3079\u3066\u304c\u542b\u307e\u308c\u3066\u3044\u308b\u5fc5\u8981\u304c\u3042\u308b\r\n- `monitoring_overwrite`\u304c`False`\u306a\u306e\u3067`otsuhachi.grades`\u3092\u3057\u3066\u3082\u518d\u691c\u8a3c\u304c\u884c\u308f\u308c\u306a\u3044\r\n\r\n\u4ee5\u4e0a\u306e\u3088\u3046\u306a\u8a2d\u5b9a\u306e\u30d0\u30ea\u30c7\u30fc\u30bf\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u3002\r\n\r\n<!-- omit in toc -->\r\n##### grades\u306e\u57fa\u672c\u7684\u306a\u5931\u6557\u3068\u6210\u529f\u306e\u4f8b\r\n\r\n```python\r\n\r\n# \u5931\u6557 (\u578b\u304c\u7570\u306a\u308b)\r\n>>> otsuhachi.grades = ['Japanese', 'Social Studies', 'Math']\r\nTraceback (most recent call last):\r\n...\r\nTypeError: \u5c5e\u6027'grades'\u306fdict\u578b\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002(['Japanese', 'Social Studies', 'Math']: list)\r\n\r\n# \u5931\u6557 (\u5fc5\u9808\u30ad\u30fc\u306e\u6b20\u843d)\r\n>>> otsuhachi.grades = {'Japanese': 68}\r\nTraceback (most recent call last):\r\n...\r\nValueError: \u5c5e\u6027'grades'\u306f\u4ee5\u4e0b\u306e\u30ad\u30fc\u3092\u8a2d\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002({'Math', 'Social Studies'})\u3002({'Japanese': 68}: dict)\r\n\r\n# \u5931\u6557 (\u4e0d\u6b63\u306a\u5024)\r\n>>> otsuhachi.grades = {'Japanese': 68, 'Social Studies': 28, 'Math': 66}\r\nTraceback (most recent call last):\r\n...\r\nTypeError: dict\u578b\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002(66: int)\r\n\r\nDuring handling of the above exception, another exception occurred:\r\n\r\nTraceback (most recent call last):\r\n...\r\nTypeError: \u30ad\u30fc'Math'\u306f\u4e0d\u6b63\u306a\u5024\u3067\u3059\u3002(66: int)\r\n\r\n# \u5931\u6557 (\u4e0d\u6b63\u306a\u5024: \u5165\u308c\u5b50\u69cb\u9020)\r\n>>> otsuhachi.grades = {'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 2.8}}\r\nTraceback (most recent call last):\r\n...\r\nTypeError: int\u578b\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002(2.8: float)\r\n\r\nDuring handling of the above exception, another exception occurred:\r\n\r\nTraceback (most recent call last):\r\n...\r\nTypeError: \u30ad\u30fc'Math1'\u306f\u4e0d\u6b63\u306a\u5024\u3067\u3059\u3002(2.8: float)\r\n\r\nDuring handling of the above exception, another exception occurred:\r\n\r\nTraceback (most recent call last):\r\n...\r\nTypeError: \u30ad\u30fc'Math'\u306f\u4e0d\u6b63\u306a\u5024\u3067\u3059\u3002({'Math1': 2.8}: dict)\r\n\r\n# \u5931\u6557 (\u672a\u5b9a\u7fa9\u306e\u30ad\u30fc)\r\n>>> otsuhachi.grades = {'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66}, 'Science': 70}\r\nTraceback (most recent call last):\r\n...\r\nValueError: \u5c5e\u6027'grades'\u306f\u4ee5\u4e0b\u306e\u30ad\u30fc\u3092\u8a2d\u5b9a\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002({'Science'})\u3002({'Japanese...ence': 70}: dict)\r\n\r\n# \u6210\u529f\r\n>>> otsuhachi.grades = {'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66, 'Math2': 56}}\r\n>>> otsuhachi.grades\r\n{'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66, 'Math2': 56}}\r\n\r\n# Math\u5185\u306f\u30ad\u30fc\u6b20\u843d\u53ef\r\n>>> otsuhachi.grades = {'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66}}\r\n>>> otsuhachi.grades\r\n{'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66}}\r\n```\r\n\r\n<!-- omit in toc -->\r\n##### grades\u3067\u8d77\u3053\u308a\u3048\u308b\u4e0d\u6b63\r\n\r\n\u3053\u306e\u8a2d\u5b9a\u3067\u306f\u66f8\u304d\u63db\u3048\u306b\u5bfe\u3057\u3066\u7121\u529b\u3067\u3059\u3002  \r\n`otsuhachi.grades`\u304c\u547c\u3073\u51fa\u3055\u308c\u305f\u3068\u304d\u9650\u5b9a\u3067\u691c\u8a3c\u304c\u884c\u308f\u308c\u308b\u306e\u3067\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u64cd\u4f5c\u3067\u306f\u4e0d\u6b63\u304c\u884c\u3048\u307e\u3059\u3002\r\n\r\n```python\r\n\r\n# \u6b63\u5e38\u306a\u5f62\u5f0f\u3067grades\u3092\u30bb\u30c3\u30c8\r\n>>> otsuhachi.grades = {'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66, 'Math2': 56}}\r\n>>> otsuhachi.grades\r\n{'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66, 'Math2': 56}}\r\n\r\n# grades['Math']\u309266\u306b\u3059\u308b\r\n>>> otsuhachi.grades['Math'] = 66\r\n>>> otsuhachi.grades\r\n{'Japanese': 68, 'Social Studies': 28, 'Math': 66}\r\n```\r\n\r\n<!-- omit in toc -->\r\n##### grades\u3067\u8d77\u3053\u308a\u3048\u308b\u4e0d\u6b63\u306e\u9632\u6b62\r\n\r\n\u4e0d\u6b63\u306e\u9632\u6b62\u306b\u306f\u4e3b\u306b2\u3064\u306e\u624b\u6bb5\u304c\u3042\u308a\u307e\u3059\u3002\r\n\r\n1. \u30d0\u30ea\u30c7\u30fc\u30bf\u3092\u30af\u30e9\u30b9\u5916\u3067\u5b9a\u7fa9\u3057\u3001\u5fc5\u8981\u306b\u5fdc\u3058\u3066\u691c\u8a3c\u3092\u884c\u3046\r\n2. `monitoring_overwrite`\u3092`True`\u306b\u3059\u308b\r\n\r\n1.\u306e\u65b9\u6cd5\u3067\u306f\u624b\u9593\u304c\u639b\u304b\u308a\u307e\u3059\u304c\u3001\u4e0d\u8981\u306a\u6642\u306b\u691c\u8a3c\u3055\u308c\u308b\u3053\u3068\u304c\u306a\u3044\u306e\u3067\u6bd4\u8f03\u7684\u9ad8\u901f\u306a\u52d5\u4f5c\u304c\u671f\u5f85\u3055\u308c\u307e\u3059\u3002  \r\n\u307e\u305f`monitoring_overwrite`\u306f`False`\u3067\u306a\u3051\u308c\u30702\u306e\u65b9\u6cd5\u3068\u5909\u308f\u308a\u3042\u308a\u307e\u305b\u3093\u3002  \r\n\r\n2.\u306e\u65b9\u6cd5\u3067\u306f`otsuhachi.grades`\u304c\u547c\u3070\u308c\u308b\u305f\u3073\u306b\u691c\u8a3c\u3055\u308c\u308b\u306e\u3067\u624b\u8efd\u3067\u3059\u3002  \r\n\r\n\u3069\u3061\u3089\u3082\u66f8\u304d\u63db\u3048\u306f\u8a31\u3057\u3066\u3057\u307e\u3044\u307e\u3059\u304c\u3001\u6700\u7d42\u7684\u306b\u5024\u3092\u5229\u7528\u3059\u308b\u30bf\u30a4\u30df\u30f3\u30b0\u3067\u306f\u691c\u8a3c\u304c\u884c\u308f\u308c\u307e\u3059\u3002\r\n\r\n```python\r\n\r\n# 1\u306e\u65b9\u6cd5\r\nGRADES_VALIDATOR = VDict(\r\n    {\r\n        'Japanese': VInt(0, 100),\r\n        'Social Studies': VInt(0, 100),\r\n        'Math': VDict(\r\n            {\r\n                'Math1': VInt(0, 100),\r\n                'Math2': VInt(0, 100)\r\n            },\r\n            allow_missing_key=True,\r\n            monitoring_overwrite=True,\r\n        )\r\n    },\r\n    allow_missing_key=False,\r\n    monitoring_overwrite=False,\r\n)\r\n\r\nclass Student:\r\n    # ...\u90e8\u5206\u306f\u524d\u63d0\u30b3\u30fc\u30c9\u901a\u308a\u3067\u3059\u3002\r\n    ...\r\n    grades = GRADES_VALIDATOR\r\n    ...\r\n\r\n# \u5024\u306e\u30bb\u30c3\u30c8\r\notsuhachi = Student()\r\notsuhachi.grades = {'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66, 'Math2': 56}}\r\n>>> otsuhachi.grades\r\n{'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66, 'Math2': 56}}\r\n\r\n# \u4e0d\u6b63\u306a\u66f8\u304d\u63db\u3048\r\n>>> otsuhachi.grades['Math'] = 66\r\n>>> otsuhachi.grades\r\n{'Japanese': 68, 'Social Studies': 28, 'Math': 66}\r\n\r\n# \u4e0d\u6b63\u304c\u56f0\u308b\u5834\u9762\r\n>>> GRADES_VALIDATOR.validate(otsuhachi.grades)\r\nTraceback (most recent call last):\r\n...\r\nTypeError: dict\u578b\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002(66: int)\r\n\r\nDuring handling of the above exception, another exception occurred:\r\n\r\nTraceback (most recent call last):\r\n...\r\nTypeError: \u30ad\u30fc'Math'\u306f\u4e0d\u6b63\u306a\u5024\u3067\u3059\u3002(66: int)\r\n\r\n```\r\n\r\n```python\r\n\r\n# 2\u306e\u65b9\u6cd5\r\nclass Student:\r\n    # ...\u90e8\u5206\u306f\u524d\u63d0\u30b3\u30fc\u30c9\u901a\u308a\u3067\u3059\u3002\r\n    ...\r\n    grades = VDict(\r\n        ...\r\n        monitoring_overwrite=True,\r\n    )\r\n    ...\r\n    \r\n# \u5024\u306e\u30bb\u30c3\u30c8\r\notsuhachi = Student()\r\n>>> otsuhachi.grades = {'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66, 'Math2': 56}}\r\n>>> otsuhachi.grades\r\n{'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66, 'Math2': 56}}\r\n\r\n# \u4e0d\u6b63\u306a\u66f8\u304d\u63db\u3048\r\n>>> otsuhachi.grades['Math'] = 66\r\n>>> otsuhachi.grades\r\nTraceback (most recent call last):\r\n...\r\nTypeError: dict\u578b\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002(66: int)\r\n\r\nDuring handling of the above exception, another exception occurred:\r\n\r\nTraceback (most recent call last):\r\n...\r\nTypeError: \u30ad\u30fc'Math'\u306f\u4e0d\u6b63\u306a\u5024\u3067\u3059\u3002(66: int)\r\n```\r\n\r\n<!-- omit in toc -->\r\n#### \u30d0\u30ea\u30c7\u30fc\u30bf\u5b9f\u884c\u4f8b-hobby\u306e\u64cd\u4f5c\r\n\r\n[\u76ee\u6b21](#\u30d0\u30ea\u30c7\u30fc\u30bf\u306e\u5b9f\u884c\u4f8b\u76ee\u6b21)\u306b\u623b\u308b\r\n\r\n`otsuhachi.hobby`\u3092\u64cd\u4f5c\u3057\u307e\u3059\u3002  \r\n`Student`\u306e`hobby`\u5c5e\u6027\u306f`CNoneable(VList(VString(1)))`\u306b\u3088\u3063\u3066\u691c\u8a3c\u3055\u308c\u307e\u3059\u3002\r\n\r\n`CNoneable`\u306f\u30d0\u30ea\u30c7\u30fc\u30bf\u306b`None`\u3092\u8a31\u53ef\u3059\u308b\u30af\u30e9\u30b9\u3067\u3059\u3002  \r\n\u4eca\u56de\u306f`otsuhachi.hobby`\u304c`None`\u307e\u305f\u306f`VList(VString(1))`\u306e\u6761\u4ef6\u3092\u6e80\u305f\u3059\u6642\u306b\u691c\u8a3c\u3092\u901a\u904e\u3057\u307e\u3059\u3002\r\n\r\n```python\r\n\r\n# \u5931\u6557 (CNoneable\u306fNone\u3092\u8a31\u53ef\u3059\u308b\u3060\u3051\u3067\u3001\u521d\u671f\u5024\u3092None\u306b\u306f\u3057\u306a\u3044)\r\n>>> otsuhachi.hobby\r\nTraceback (most recent call last):\r\n...\r\nAttributeError: 'Student' object has no attribute '_hobby'\r\n\r\n# \u5931\u6557 (\u4e0d\u6b63\u306a\u5024)\r\n>>> otsuhachi.hobby = 1\r\nTraceback (most recent call last):\r\n...\r\nTypeError: list\u578b\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002(1: int)\r\n\r\n# \u5931\u6557 (\u30ea\u30b9\u30c8\u5185\u306e\u5024\u304c\u4e0d\u6b63)\r\n>>> otsuhachi.hobby = [1]\r\nTraceback (most recent call last):\r\n...\r\nTypeError: str\u578b\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002(1: int)\r\n\r\nDuring handling of the above exception, another exception occurred:\r\n\r\nTraceback (most recent call last):\r\n...\r\nTypeError: \u30a4\u30f3\u30c7\u30c3\u30af\u30b90\u306f\u4e0d\u6b63\u306a\u5024\u3067\u3059\u3002(1: int)\r\n\r\n# \u6210\u529f\r\n>>> otsuhachi.hobby = None\r\n>>> print(otsuhachi.hobby)\r\nNone\r\n\r\n# \u6210\u529f\r\n>>> otsuhachi.hobby = ['PC', 'game']\r\n>>> otsuhachi.hobby\r\n['PC', 'game']\r\n\r\n# \u5931\u6557 (\u4e0d\u6b63\u306a\u5024\u3092\u8ffd\u52a0\u5f8c\u306b\u53c2\u7167)\r\n>>> otsuhachi.hobby.append(1)\r\n>>> otsuhachi.hobby\r\nTraceback (most recent call last):\r\n...\r\nTypeError: str\u578b\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002(1: int)\r\n\r\nDuring handling of the above exception, another exception occurred:\r\n\r\nTraceback (most recent call last):\r\n...\r\nTypeError: \u30a4\u30f3\u30c7\u30c3\u30af\u30b92\u306f\u4e0d\u6b63\u306a\u5024\u3067\u3059\u3002(1: int)\r\n```\r\n\r\n\r\n<!-- omit in toc -->\r\n#### \u30d0\u30ea\u30c7\u30fc\u30bf\u5b9f\u884c\u4f8b-address\u306e\u64cd\u4f5c\r\n\r\n[\u76ee\u6b21](#\u30d0\u30ea\u30c7\u30fc\u30bf\u306e\u5b9f\u884c\u4f8b\u76ee\u6b21)\u306b\u623b\u308b\r\n\r\n`otsuhachi.address`\u3092\u64cd\u4f5c\u3057\u307e\u3059\u3002  \r\n`Student`\u306e`address`\u5c5e\u6027\u306f`CNoneable(VList([VRegex('^\\\\d{3}-?\\\\d{4}$'), VRegex('(?!.*\\\\d.*)')`\u306b\u3088\u3063\u3066\u691c\u8a3c\u3055\u308c\u307e\u3059\u3002  \r\n\u57fa\u672c\u7684\u306a\u5931\u6557\u4f8b\u3001\u6210\u529f\u4f8b\u306f[hobby](#\u30d0\u30ea\u30c7\u30fc\u30bf\u5b9f\u884c\u4f8b-hobby\u306e\u64cd\u4f5c)\u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002  \r\n`address`\u5c5e\u6027\u306e\u7279\u6b8a\u306a\u70b9\u306f`VList`\u306e`TEMPLATE`\u304c`list\u578b`\u3067\u3042\u308b\u70b9\u3067\u3059\u3002  \r\n\r\n`value[i]`\u304c`TEMPLATE[i]`\u3067\u305d\u308c\u305e\u308c\u691c\u8a3c\u3055\u308c\u307e\u3059\u3002\r\n\r\n```python\r\n\r\n# \u5931\u6557 (\u8981\u7d20\u6570\u304c\u8db3\u308a\u3066\u3044\u306a\u3044)\r\n>>> otsuhachi.address = []\r\nTraceback (most recent call last):\r\n...\r\nValueError: \u3042\u30683\u500b\u8a2d\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002([]: list)\r\n\r\n# \u5931\u6557 (\u8981\u7d20\u6570\u304c\u591a\u3044)\r\n>>> otsuhachi.address = ['', '', '', '']\r\nTraceback (most recent call last):\r\n...\r\nValueError: \u3042\u30681\u500b\u6e1b\u3089\u3059\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002(['', '', '', '']: list)\r\n\r\n# \u5931\u6557 (\u4e0d\u6b63\u306a\u5024)\r\n>>> otsuhachi.address = ['0000000000', 'Otsu Prefecture2', 'OtsuCity']\r\nTraceback (most recent call last):\r\n...\r\nValueError: \u6b63\u898f\u8868\u73fe'^\\\\d{3}-?\\\\d{4}$'\u306b\u5bfe\u5fdc\u3057\u3066\u3044\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002('0000000000': str)\r\n\r\nDuring handling of the above exception, another exception occurred:\r\n\r\nTraceback (most recent call last):\r\n...\r\nValueError: \u30a4\u30f3\u30c7\u30c3\u30af\u30b90\u306f\u4e0d\u6b63\u306a\u5024\u3067\u3059\u3002('0000000000': str)\r\n\r\n# \u5931\u6557 (\u4e0d\u6b63\u306a\u5024)\r\n>>> otsuhachi.address = ['282-2828', 'Otsu Prefecture2', 'OtsuCity']\r\nTraceback (most recent call last):\r\n...\r\nValueError: \u6b63\u898f\u8868\u73fe'(?!.*\\\\d.*)'\u306b\u5bfe\u5fdc\u3057\u3066\u3044\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002('Otsu Prefecture2': str)\r\n\r\nDuring handling of the above exception, another exception occurred:\r\n\r\nTraceback (most recent call last):\r\n...\r\nValueError: \u30a4\u30f3\u30c7\u30c3\u30af\u30b91\u306f\u4e0d\u6b63\u306a\u5024\u3067\u3059\u3002('Otsu Prefecture2': str)\r\n\r\n\r\n# \u6210\u529f\r\n>>> otsuhachi.address = ['282-2828', 'Otsu Prefecture', 'OtsuCity']\r\n>>> otsuhachi.address\r\n['282-2828', 'Otsu Prefecture', 'OtsuCity']\r\n```\r\n\r\n<!-- omit in toc -->\r\n#### \u30d0\u30ea\u30c7\u30fc\u30bf\u5b9f\u884c\u4f8b-\u6210\u529f\r\n\r\n[\u76ee\u6b21](#\u30d0\u30ea\u30c7\u30fc\u30bf\u306e\u5b9f\u884c\u4f8b\u76ee\u6b21)\u306b\u623b\u308b\r\n\r\n\u3059\u3079\u3066\u306e\u30d0\u30ea\u30c7\u30fc\u30bf\u3067\u306e\u691c\u8a3c\u304c\u7d42\u308f\u308c\u3070\u3001\u8a2d\u8a08\u901a\u308a\u306b\u30af\u30e9\u30b9\u304c\u52d5\u4f5c\u3057\u307e\u3059\u3002\r\n\r\n```python\r\n\r\n>>> otsuhachi.name = 'Otsuhachi'\r\n>>> otsuhachi.age = 28\r\n>>> otsuhachi.gender = 'male'\r\n>>> otsuhachi.grades = {'Japanese': 68, 'Social Studies': 28, 'Math': {'Math1': 66, 'Math2': 56}}\r\n>>> otsuhachi.hobby = ['PC', 'game']\r\n>>> otsuhachi.address = ['282-2828', 'Otsu Prefecture', 'OtsuCity']\r\n>>> otsuhachi.show_profile()\r\n\u540d\u524d: Otsuhachi\r\n\u5e74\u9f62: 28\r\n\u6027\u5225: male\r\n\u56fd\u8a9e: 68\r\n\u793e\u4f1a: 28\r\n\u6570\u5b66: {'Math1': 66, 'Math2': 56}\r\n\u8da3\u5473: ['PC', 'game']\r\n\u4f4f\u6240: ['282-2828', 'Otsu Prefecture', 'OtsuCity']\r\n```\r\n\r\n## \u30b3\u30f3\u30d0\u30fc\u30bf\u306e\u5909\u63db\r\n\r\n\u57fa\u672c\u7684\u306b\u30b3\u30f3\u30d0\u30fc\u30bf\u306f`C<\u5bfe\u8c61\u306e\u578b\u540d>`\u3067\u3001`<\u5bfe\u8c61\u306e\u578b>(value)`\u3067\u5909\u63db\u3067\u304d\u308b\u304b\u3069\u3046\u304b\u3092\u8a66\u3059\u306e\u304c\u57fa\u672c\u306b\u306a\u308a\u307e\u3059\u3002  \r\n\u305f\u3068\u3048\u3070`CString`\u306a\u3089\u3070`str(value)`\u3092\u8a66\u307f\u3066\u304b\u3089\u691c\u8a3c\u3092\u884c\u3044\u307e\u3059\u3002\r\n\u3057\u304b\u3057\u3001\u30b3\u30f3\u30d0\u30fc\u30bf\u306b\u3088\u3063\u3066\u306f\u305d\u306e\u57fa\u672c\u306b\u5f93\u308f\u306a\u3044\u3082\u306e\u304c\u3042\u308a\u307e\u3059\u3002  \r\n`CInt`\u306f\u3001`int(value)`\u3067\u304d\u306a\u304b\u3063\u305f\u5834\u5408\u306b`int(float(value))`\u3092\u8a66\u3057\u307e\u3059(`CFloat`\u306f\u305d\u306e\u9006\u306e\u52d5\u4f5c\u3067\u3059)\u3002  \r\n\u3053\u308c\u306f\u307e\u3060\u7406\u89e3\u3057\u3084\u3059\u3044\u5909\u63db\u3067\u3059\u304c\u3001\u4ee5\u4e0b\u306e2\u3064\u306e\u30b3\u30f3\u30d0\u30fc\u30bf\u306f\u82e5\u5e72\u7279\u6b8a\u306a\u6319\u52d5\u306e\u5909\u63db\u3092\u884c\u3044\u307e\u3059\u3002  \r\n\u3053\u308c\u306f`json`\u30d5\u30a1\u30a4\u30eb\u3084`\u6a19\u6e96\u5165\u529b`\u306a\u3069\u3067\u53d7\u3051\u53d6\u3063\u305f\u5834\u5408\u306e\u5909\u63db\u51e6\u7406\u3092\u5bb9\u6613\u306b\u884c\u3046\u305f\u3081\u3067\u3059\u3002\r\n\r\n<!-- omit in toc -->\r\n### CTimedelta\r\n\r\n\u3053\u306e\u30b3\u30f3\u30d0\u30fc\u30bf\u306f`str`, `dict`, `list`, `tuple`\u3044\u305a\u308c\u304b\u306e\u578b\u3067\u3042\u308b\u5834\u5408\u306b`Timedelta`\u578b\u306b\u5909\u63db\u3092\u8a66\u307f\u307e\u3059\u3002  \r\n\u5909\u63db\u306b\u5fc5\u8981\u306a\u5f62\u5f0f\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\u3002\r\n\r\n\u578b|\u5f62\u5f0f\r\n:--|:--\r\nstr|`(<\u65e5>( )day(s, ))<\u6642>:<\u5206>:<\u79d2>(.<\u30df\u30ea\u79d2>)`<br>`()`\u3067\u56f2\u307e\u308c\u305f\u90e8\u5206\u306e\u6709\u7121\u306f\u4efb\u610f<br>\u8981\u306f`str(<timedelta\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9>)`\u3067\u5909\u63db\u3055\u308c\u305f\u5f8c\u306e\u5f62\u5f0f(\u53b3\u5bc6\u306b\u306f\u65e5\u3068\u6642\u9593\u306e\u9593\u306e\u7a7a\u767d\u3092\u554f\u308f\u306a\u3044\u306a\u3069\u82e5\u5e72\u7570\u306a\u308b)\r\ndict|`timedelta(**value)`\u3067\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u751f\u6210\u3067\u304d\u308b\u5f62\u5f0f\r\nlist, tuple|`timedelta(*value)`\u3067\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u751f\u6210\u3067\u304d\u308b\u5f62\u5f0f\r\n\r\n<!-- omit in toc -->\r\n### CBool\r\n\r\n\u3053\u306e\u30b3\u30f3\u30d0\u30fc\u30bf\u306f\u4ee5\u4e0b\u306e\u6a19\u6e96\u5b9a\u7fa9\u306e\u9805\u76ee\u3092`bool`\u306b\u5909\u63db\u3057\u307e\u3059\u3002  \r\n\u307e\u305f\u3001\u81ea\u5206\u3067`True`\u306b\u306a\u308b\u5024\u3001`False`\u306b\u306a\u308b\u5024\u3092\u8a2d\u5b9a\u3059\u308b\u3053\u3068\u3082\u53ef\u80fd\u3067\u3059\u3002  \r\n\u3055\u3089\u306b\u3001`f(value)`\u304c\u771f\u507d\u5024\u3092\u8fd4\u3059\u95a2\u6570`f`\u306e\u30bf\u30d7\u30eb\u3092\u6e21\u3057\u3066\u5224\u5b9a\u3059\u308b\u3053\u3068\u3082\u53ef\u80fd\u3067\u3059\u3002\r\n\r\n\u4ee5\u4e0b\u304c\u6a19\u6e96\u5b9a\u7fa9\u306e\u771f\u507d\u5024\u5bfe\u5fdc\u8868\u3067\u3059\u3002\r\n`str`\u578b\u306f`value.lower()`\u3055\u308c\u305f\u3042\u3068\u3067\u5224\u5b9a\u3055\u308c\u308b\u306e\u3067\u3001\u5927\u6587\u5b57\u5c0f\u6587\u5b57\u3092\u554f\u3044\u307e\u305b\u3093\u3002\r\n\r\n\u578b|True|False\r\n:--:|:--:|:--:\r\nbool|True|False\r\nstr|'true', 'yes', 'y', '1'|'false', 'no', 'n', '0'\r\nint|1|0\r\nfloat|1.0|0.0\r\n\r\n### \u5b9f\u884c\u4f8b-\u30b3\u30f3\u30d0\u30fc\u30bf\r\n\r\n\r\n```python\r\n\r\nfrom datetime import timedelta\r\nfrom typing import cast\r\n\r\nfrom otsuvalidator import CBool, CTimedelta\r\n\r\n\r\nclass SampleClass:\r\n    bool_dflt: bool = cast(bool, CBool())\r\n    bool_user: bool = cast(bool, CBool(true_data=('\u306f\u3044', ), false_data=('\u3044\u3044\u3048', )))\r\n    td_timedelta: timedelta = cast(timedelta, CTimedelta())\r\n    td_str: timedelta = cast(timedelta, CTimedelta())\r\n    td_tuple: timedelta = cast(timedelta, CTimedelta())\r\n    td_dict: timedelta = cast(timedelta, CTimedelta())\r\n\r\n    def show(self):\r\n        keys = (\r\n            'bool_dflt',\r\n            'bool_user',\r\n            'td_timedelta',\r\n            'td_str',\r\n            'td_tuple',\r\n            'td_dict',\r\n        )\r\n        for k in keys:\r\n            v = getattr(self, k)\r\n            print(f'{k}: {v}({type(v).__name__})')\r\n\r\n\r\ns = SampleClass()\r\ntd = timedelta(days=1, seconds=2, microseconds=3, milliseconds=4, minutes=5, hours=6, weeks=7)\r\n# s.bool_dflt = '\u306f\u3044'  # Error\r\n\r\n# \u4e00\u822c\u306bYes/No\u3068\u3057\u3066\u89e3\u91c8\u3055\u308c\u308b\u3082\u306e\u306fbool\u306b\u5909\u63db\r\ns.bool_dflt = 'yes'\r\n\r\n# \u30e6\u30fc\u30b6\u5b9a\u7fa9\u306eTrue\u306a\u306e\u3067True\u306b\u306a\u308b\r\ns.bool_user = '\u306f\u3044'\r\n\r\n# \u7121\u5909\u63db\u3067timedelta\r\ns.td_timedelta = td\r\n\r\n# \u7279\u5b9a\u5f62\u5f0f\u306e\u6587\u5b57\u5217\u3092timedelta\u306b\u5909\u63db\r\ns.td_str = '50 days, 0:0:1'\r\n\r\n# \u7279\u5b9a\u5f62\u5f0f\u306e\u30bf\u30d7\u30eb\u3001\u30ea\u30b9\u30c8\u3092timedelta\u306b\u5909\u63db\r\ns.td_tuple = (1, 2, 3, 4, 5, 7)\r\n\r\n# \u7279\u5b9a\u5f62\u5f0f\u306e\u8f9e\u66f8\u3092timedelta\u306b\u5909\u63db\r\ns.td_dict = {'seconds': 2, 'microseconds': 3, 'milliseconds': 4, 'minutes': 5, 'hours': 6}\r\n\r\n# \u5c5e\u6027\u540d: str(\u5c5e\u6027)(\u5c5e\u6027\u306e\u578b)\u3092\u51fa\u529b\r\ns.show()\r\n```\r\n\r\n```console\r\n\r\nbool_dflt: True(bool)\r\nbool_user: True(bool)\r\ntd_timedelta: 50 days, 6:05:02.004003(timedelta)\r\ntd_str: 50 days, 0:00:01(timedelta)\r\ntd_tuple: 1 day, 7:05:02.004003(timedelta)\r\ntd_dict: 6:05:02.004003(timedelta)\r\n```\r\n\r\n",
    "bugtrack_url": null,
    "license": "MIT License  Copyright (c) 2021 Otsuhachi  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ",
    "summary": "\u5358\u4f53\u3067\u3082\u30c7\u30a3\u30b9\u30af\u30ea\u30d7\u30bf\u3068\u3057\u3066\u3082\u4f7f\u7528\u3067\u304d\u308b\u30d0\u30ea\u30c7\u30fc\u30bf\u30e9\u30a4\u30d6\u30e9\u30ea",
    "version": "2.0.1",
    "split_keywords": [
        "python",
        "validator",
        "descriptor",
        "converter"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e86af3580a0eca5c3472d4cc977ac25533137215b98f4777bc2b18a4196f12a0",
                "md5": "7599870dff7aa911530c4a047ecbde36",
                "sha256": "1be10270236e7637b5d98e0da33dd357e2db066509f821421a31ec0d026b1e48"
            },
            "downloads": -1,
            "filename": "otsuvalidator-2.0.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "7599870dff7aa911530c4a047ecbde36",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 19729,
            "upload_time": "2023-01-13T14:10:36",
            "upload_time_iso_8601": "2023-01-13T14:10:36.729511Z",
            "url": "https://files.pythonhosted.org/packages/e8/6a/f3580a0eca5c3472d4cc977ac25533137215b98f4777bc2b18a4196f12a0/otsuvalidator-2.0.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "80f9d9f6305829e0153afd4cba320fed242e003c6c422dfaf9b3287eff2b00bb",
                "md5": "4313d051b206ff1b494dbcff287cdb4b",
                "sha256": "dd68c43bd5e2f831b558de998bb68ae3df9534ce464f48def6c961f7846b2524"
            },
            "downloads": -1,
            "filename": "otsuvalidator-2.0.1.tar.gz",
            "has_sig": false,
            "md5_digest": "4313d051b206ff1b494dbcff287cdb4b",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 24780,
            "upload_time": "2023-01-13T14:10:38",
            "upload_time_iso_8601": "2023-01-13T14:10:38.758643Z",
            "url": "https://files.pythonhosted.org/packages/80/f9/d9f6305829e0153afd4cba320fed242e003c6c422dfaf9b3287eff2b00bb/otsuvalidator-2.0.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-01-13 14:10:38",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "Otsuhachi",
    "github_project": "OtsuValidator",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "otsuvalidator"
}
        
Elapsed time: 0.56823s