From 4c9ee486d8d06aa366ae3bdef610b29c6c3ba449 Mon Sep 17 00:00:00 2001 From: dmontagu <35119617+dmontagu@users.noreply.github.com> Date: Tue, 23 Jul 2019 08:40:28 -0700 Subject: [PATCH] Add literal docs (#651) * Add literal docs * Update history * Incorporate feedback * fix history --- HISTORY.rst | 1 + docs/examples/literal1.py | 18 ++++++++++++++++++ docs/examples/literal2.py | 32 ++++++++++++++++++++++++++++++++ docs/examples/literal3.py | 30 ++++++++++++++++++++++++++++++ docs/index.rst | 23 +++++++++++++++++++++++ 5 files changed, 104 insertions(+) create mode 100644 docs/examples/literal1.py create mode 100644 docs/examples/literal2.py create mode 100644 docs/examples/literal3.py diff --git a/HISTORY.rst b/HISTORY.rst index c8cab05..8510aa0 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -6,6 +6,7 @@ History v0.31 (unreleased) .................. * fix schema generation for ``NewType`` and ``Literal``, #649 by @dmontagu +* add documentation for Literal type, #651 by @dmontagu v0.30.1 (2019-07-15) .................... diff --git a/docs/examples/literal1.py b/docs/examples/literal1.py new file mode 100644 index 0000000..7e94b69 --- /dev/null +++ b/docs/examples/literal1.py @@ -0,0 +1,18 @@ +from typing_extensions import Literal + +from pydantic import BaseModel, ValidationError + +class Pie(BaseModel): + flavor: Literal['apple', 'pumpkin'] + +Pie(flavor='apple') +Pie(flavor='pumpkin') +try: + Pie(flavor='cherry') +except ValidationError as e: + print(str(e)) +""" +1 validation error +flavor + unexpected value; permitted: 'apple', 'pumpkin' (type=value_error.const; given=cherry; permitted=('apple', 'pumpkin')) +""" diff --git a/docs/examples/literal2.py b/docs/examples/literal2.py new file mode 100644 index 0000000..c2715e1 --- /dev/null +++ b/docs/examples/literal2.py @@ -0,0 +1,32 @@ +from typing import ClassVar, List, Union + +from typing_extensions import Literal + +from pydantic import BaseModel, ValidationError + +class Cake(BaseModel): + kind: Literal['cake'] + required_utensils: ClassVar[List[str]] = ['fork', 'knife'] + +class IceCream(BaseModel): + kind: Literal['icecream'] + required_utensils: ClassVar[List[str]] = ['spoon'] + +class Meal(BaseModel): + dessert: Union[Cake, IceCream] + +print(type(Meal(dessert={'kind': 'cake'}).dessert).__name__) +# Cake +print(type(Meal(dessert={'kind': 'icecream'}).dessert).__name__) +# IceCream +try: + Meal(dessert={'kind': 'pie'}) +except ValidationError as e: + print(str(e)) +""" +2 validation errors +dessert -> kind + unexpected value; permitted: 'cake' (type=value_error.const; given=pie; permitted=('cake',)) +dessert -> kind + unexpected value; permitted: 'icecream' (type=value_error.const; given=pie; permitted=('icecream',)) +""" diff --git a/docs/examples/literal3.py b/docs/examples/literal3.py new file mode 100644 index 0000000..6366500 --- /dev/null +++ b/docs/examples/literal3.py @@ -0,0 +1,30 @@ +from typing import Optional, Union + +from typing_extensions import Literal + +from pydantic import BaseModel + +class Dessert(BaseModel): + kind: str + +class Pie(Dessert): + kind: Literal['pie'] + flavor: Optional[str] + +class ApplePie(Pie): + flavor: Literal['apple'] + +class PumpkinPie(Pie): + flavor: Literal['pumpkin'] + +class Meal(BaseModel): + dessert: Union[ApplePie, PumpkinPie, Pie, Dessert] + +print(type(Meal(dessert={'kind': 'pie', 'flavor': 'apple'}).dessert).__name__) +# ApplePie +print(type(Meal(dessert={'kind': 'pie', 'flavor': 'pumpkin'}).dessert).__name__) +# PumpkinPie +print(type(Meal(dessert={'kind': 'pie'}).dessert).__name__) +# Pie +print(type(Meal(dessert={'kind': 'cake'}).dessert).__name__) +# Dessert diff --git a/docs/index.rst b/docs/index.rst index 00d6438..a48fc6d 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -654,6 +654,29 @@ against defined Json structure if it's provided. (This script is complete, it should run "as is") +Literal Type +............ + +Pydantic supports the use of ``typing_extensions.Literal`` as a lightweight way to specify that a field +may accept only specific literal values: + +.. literalinclude:: examples/literal1.py + +(This script is complete, it should run "as is") + +One benefit of this field type is that it can be used to check for equality with one or more specific values +without needing to declare custom validators: + +.. literalinclude:: examples/literal2.py + +(This script is complete, it should run "as is") + +With proper ordering in an annotated ``Union``, you can use this to parse types of decreasing specificity: + +.. literalinclude:: examples/literal3.py + +(This script is complete, it should run "as is") + Custom Data Types .................