Skip to content

Instantly share code, notes, and snippets.

@nymous
Last active March 16, 2021 20:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nymous/686d38ba1aa150fefe6da6d78b1cb441 to your computer and use it in GitHub Desktop.
Save nymous/686d38ba1aa150fefe6da6d78b1cb441 to your computer and use it in GitHub Desktop.
Pydantic Literal enum bug in 1.8+
from typing import Literal
from enum import Enum
import logging
from pydantic import BaseModel, ValidationError
from pydantic.utils import version_info
print("=== PYDANTIC INFO ===")
print(version_info())
class MyEnum(str, Enum):
FOO = "foo"
BAR = "bar"
print("\n\n=== ModelWithLiteralEnumMember ===")
class ModelWithLiteralEnumMember(BaseModel):
kind: Literal[MyEnum.FOO]
print("\n---- Parse model ----")
print(ModelWithLiteralEnumMember(kind="foo"))
try:
print(ModelWithLiteralEnumMember(kind="bar"))
except ValidationError:
print("OK - Can validate the enum")
print("\n---- Get JSON schema ----")
try:
print(ModelWithLiteralEnumMember.schema_json()) # This works until 1.7.3 but crashes on 1.8+
except KeyError:
logging.exception("Cannot get JSON schema for ModelWithLiteralEnumMember")
print("\n\n=== ModelWithLiteralEnumMemberAndForwardRef ===")
class ModelWithLiteralEnumMemberAndForwardRef(BaseModel):
kind: Literal[MyEnum.FOO]
ModelWithLiteralEnumMemberAndForwardRef.update_forward_refs()
print("\n---- Parse model ----")
print(ModelWithLiteralEnumMemberAndForwardRef(kind="foo"))
try:
print(ModelWithLiteralEnumMemberAndForwardRef(kind="bar"))
except ValidationError:
print("OK - Can validate the enum")
print("\n---- Get JSON schema ----")
try:
print(ModelWithLiteralEnumMemberAndForwardRef.schema_json()) # Still doesn't work...
except KeyError:
logging.exception("Cannot get JSON schema for ModelWithLiteralEnumMemberAndForwardRef")
print("\n\n=== ModelWithLiteralEnumMemberAndFullEnum ===")
class ModelWithLiteralEnumMemberAndFullEnum(BaseModel):
kind: Literal[MyEnum.FOO]
possible_kinds: MyEnum
print("\n---- Get JSON schema ----")
print(ModelWithLiteralEnumMemberAndFullEnum.schema_json()) # ... but now with the new property it does work
print("\n\n=== ModelWithLiteralEnumValue ===")
class ModelWithLiteralEnumValue(BaseModel):
kind: Literal[MyEnum.FOO.value]
print("\n---- Parse model ----")
print(ModelWithLiteralEnumValue(kind="foo"))
try:
print(ModelWithLiteralEnumValue(kind="bar"))
except ValidationError:
print("OK - Can validate the enum")
print("\n---- Get JSON schema ----")
print(ModelWithLiteralEnumValue.schema_json())
print("\n\n=== ModelWithLiteralEnumValue ===")
class ModelWithLiteralStr(BaseModel):
kind: Literal["foo"]
print("\n---- Parse model ----")
print(ModelWithLiteralStr(kind="foo"))
try:
print(ModelWithLiteralStr(kind="bar"))
except ValidationError:
print("OK - Can validate the enum")
print("\n---- Get JSON schema ----")
print(ModelWithLiteralStr.schema_json())
=== PYDANTIC INFO ===
pydantic version: 1.7.3
pydantic compiled: True
install path: /tmp/tmp.iid8D0iv22/.venv/lib/python3.9/site-packages/pydantic
python version: 3.9.2 (default, Feb 20 2021, 18:40:11) [GCC 10.2.0]
platform: Linux-5.11.6-arch1-1-x86_64-with-glibc2.33
optional deps. installed: []
=== ModelWithLiteralEnumMember ===
---- Parse model ----
kind='foo'
OK - Can validate the enum
---- Get JSON schema ----
{"title": "ModelWithLiteralEnumMember", "type": "object", "properties": {"kind": {"title": "Kind", "$ref": "#/definitions/MyEnum"}}, "required": ["kind"], "definitions": {"MyEnum": {"title": "MyEnum", "description": "An enumeration.", "enum": ["foo", "bar"], "type": "string"}}}
=== ModelWithLiteralEnumMemberAndForwardRef ===
---- Parse model ----
kind='foo'
OK - Can validate the enum
---- Get JSON schema ----
{"title": "ModelWithLiteralEnumMemberAndForwardRef", "type": "object", "properties": {"kind": {"title": "Kind", "$ref": "#/definitions/MyEnum"}}, "required": ["kind"], "definitions": {"MyEnum": {"title": "MyEnum", "description": "An enumeration.", "enum": ["foo", "bar"], "type": "string"}}}
=== ModelWithLiteralEnumMemberAndFullEnum ===
---- Get JSON schema ----
{"title": "ModelWithLiteralEnumMemberAndFullEnum", "type": "object", "properties": {"kind": {"title": "Kind", "$ref": "#/definitions/MyEnum"}, "possible_kinds": {"$ref": "#/definitions/MyEnum"}}, "required": ["kind", "possible_kinds"], "definitions": {"MyEnum": {"title": "MyEnum", "description": "An enumeration.", "enum": ["foo", "bar"], "type": "string"}}}
=== ModelWithLiteralEnumValue ===
---- Parse model ----
kind='foo'
OK - Can validate the enum
---- Get JSON schema ----
{"title": "ModelWithLiteralEnumValue", "type": "object", "properties": {"kind": {"title": "Kind", "const": "foo", "type": "string"}}, "required": ["kind"]}
=== ModelWithLiteralEnumValue ===
---- Parse model ----
kind='foo'
OK - Can validate the enum
---- Get JSON schema ----
{"title": "ModelWithLiteralStr", "type": "object", "properties": {"kind": {"title": "Kind", "const": "foo", "type": "string"}}, "required": ["kind"]}
=== PYDANTIC INFO ===
pydantic version: 1.8
pydantic compiled: True
install path: /tmp/tmp.iid8D0iv22/.venv/lib/python3.9/site-packages/pydantic
python version: 3.9.2 (default, Feb 20 2021, 18:40:11) [GCC 10.2.0]
platform: Linux-5.11.6-arch1-1-x86_64-with-glibc2.33
optional deps. installed: ['typing-extensions']
=== ModelWithLiteralEnumMember ===
---- Parse model ----
kind=<MyEnum.FOO: 'foo'>
OK - Can validate the enum
---- Get JSON schema ----
ERROR:root:Cannot get JSON schema for ModelWithLiteralEnumMember
Traceback (most recent call last):
File "/tmp/tmp.iid8D0iv22/main.py", line 33, in <module>
print(ModelWithLiteralEnumMember.schema_json()) # This works until 1.7.3 but crashes on 1.8+
File "pydantic/main.py", line 706, in pydantic.main.BaseModel.schema_json
File "pydantic/main.py", line 695, in pydantic.main.BaseModel.schema
File "pydantic/schema.py", line 167, in pydantic.schema.model_schema
File "pydantic/schema.py", line 548, in pydantic.schema.model_process_schema
File "pydantic/schema.py", line 589, in pydantic.schema.model_type_schema
File "pydantic/schema.py", line 241, in pydantic.schema.field_schema
File "pydantic/schema.py", line 495, in pydantic.schema.field_type_schema
File "pydantic/schema.py", line 810, in pydantic.schema.field_singleton_schema
KeyError: <enum 'MyEnum'>
=== ModelWithLiteralEnumMemberAndForwardRef ===
---- Parse model ----
kind=<MyEnum.FOO: 'foo'>
OK - Can validate the enum
---- Get JSON schema ----
ERROR:root:Cannot get JSON schema for ModelWithLiteralEnumMemberAndForwardRef
Traceback (most recent call last):
File "/tmp/tmp.iid8D0iv22/main.py", line 55, in <module>
print(ModelWithLiteralEnumMemberAndForwardRef.schema_json()) # Still doesn't work...
File "pydantic/main.py", line 706, in pydantic.main.BaseModel.schema_json
File "pydantic/main.py", line 695, in pydantic.main.BaseModel.schema
File "pydantic/schema.py", line 167, in pydantic.schema.model_schema
File "pydantic/schema.py", line 548, in pydantic.schema.model_process_schema
File "pydantic/schema.py", line 589, in pydantic.schema.model_type_schema
File "pydantic/schema.py", line 241, in pydantic.schema.field_schema
File "pydantic/schema.py", line 495, in pydantic.schema.field_type_schema
File "pydantic/schema.py", line 810, in pydantic.schema.field_singleton_schema
KeyError: <enum 'MyEnum'>
=== ModelWithLiteralEnumMemberAndFullEnum ===
---- Get JSON schema ----
{"title": "ModelWithLiteralEnumMemberAndFullEnum", "type": "object", "properties": {"kind": {"title": "Kind", "$ref": "#/definitions/MyEnum"}, "possible_kinds": {"$ref": "#/definitions/MyEnum"}}, "required": ["kind", "possible_kinds"], "definitions": {"MyEnum": {"title": "MyEnum", "description": "An enumeration.", "enum": ["foo", "bar"], "type": "string"}}}
=== ModelWithLiteralEnumValue ===
---- Parse model ----
kind='foo'
OK - Can validate the enum
---- Get JSON schema ----
{"title": "ModelWithLiteralEnumValue", "type": "object", "properties": {"kind": {"title": "Kind", "enum": ["foo"], "type": "string"}}, "required": ["kind"]}
=== ModelWithLiteralEnumValue ===
---- Parse model ----
kind='foo'
OK - Can validate the enum
---- Get JSON schema ----
{"title": "ModelWithLiteralStr", "type": "object", "properties": {"kind": {"title": "Kind", "enum": ["foo"], "type": "string"}}, "required": ["kind"]}
=== PYDANTIC INFO ===
pydantic version: 1.8.1
pydantic compiled: True
install path: /tmp/tmp.iid8D0iv22/.venv/lib/python3.9/site-packages/pydantic
python version: 3.9.2 (default, Feb 20 2021, 18:40:11) [GCC 10.2.0]
platform: Linux-5.11.6-arch1-1-x86_64-with-glibc2.33
optional deps. installed: ['typing-extensions']
=== ModelWithLiteralEnumMember ===
---- Parse model ----
kind=<MyEnum.FOO: 'foo'>
OK - Can validate the enum
---- Get JSON schema ----
ERROR:root:Cannot get JSON schema for ModelWithLiteralEnumMember
Traceback (most recent call last):
File "/tmp/tmp.iid8D0iv22/main.py", line 33, in <module>
print(ModelWithLiteralEnumMember.schema_json()) # This works until 1.7.3 but crashes on 1.8+
File "pydantic/main.py", line 715, in pydantic.main.BaseModel.schema_json
File "pydantic/main.py", line 704, in pydantic.main.BaseModel.schema
File "pydantic/schema.py", line 167, in pydantic.schema.model_schema
File "pydantic/schema.py", line 548, in pydantic.schema.model_process_schema
File "pydantic/schema.py", line 589, in pydantic.schema.model_type_schema
File "pydantic/schema.py", line 241, in pydantic.schema.field_schema
File "pydantic/schema.py", line 495, in pydantic.schema.field_type_schema
File "pydantic/schema.py", line 810, in pydantic.schema.field_singleton_schema
KeyError: <enum 'MyEnum'>
=== ModelWithLiteralEnumMemberAndForwardRef ===
---- Parse model ----
kind=<MyEnum.FOO: 'foo'>
OK - Can validate the enum
---- Get JSON schema ----
ERROR:root:Cannot get JSON schema for ModelWithLiteralEnumMemberAndForwardRef
Traceback (most recent call last):
File "/tmp/tmp.iid8D0iv22/main.py", line 55, in <module>
print(ModelWithLiteralEnumMemberAndForwardRef.schema_json()) # Still doesn't work...
File "pydantic/main.py", line 715, in pydantic.main.BaseModel.schema_json
File "pydantic/main.py", line 704, in pydantic.main.BaseModel.schema
File "pydantic/schema.py", line 167, in pydantic.schema.model_schema
File "pydantic/schema.py", line 548, in pydantic.schema.model_process_schema
File "pydantic/schema.py", line 589, in pydantic.schema.model_type_schema
File "pydantic/schema.py", line 241, in pydantic.schema.field_schema
File "pydantic/schema.py", line 495, in pydantic.schema.field_type_schema
File "pydantic/schema.py", line 810, in pydantic.schema.field_singleton_schema
KeyError: <enum 'MyEnum'>
=== ModelWithLiteralEnumMemberAndFullEnum ===
---- Get JSON schema ----
{"title": "ModelWithLiteralEnumMemberAndFullEnum", "type": "object", "properties": {"kind": {"title": "Kind", "$ref": "#/definitions/MyEnum"}, "possible_kinds": {"$ref": "#/definitions/MyEnum"}}, "required": ["kind", "possible_kinds"], "definitions": {"MyEnum": {"title": "MyEnum", "description": "An enumeration.", "enum": ["foo", "bar"], "type": "string"}}}
=== ModelWithLiteralEnumValue ===
---- Parse model ----
kind='foo'
OK - Can validate the enum
---- Get JSON schema ----
{"title": "ModelWithLiteralEnumValue", "type": "object", "properties": {"kind": {"title": "Kind", "enum": ["foo"], "type": "string"}}, "required": ["kind"]}
=== ModelWithLiteralEnumValue ===
---- Parse model ----
kind='foo'
OK - Can validate the enum
---- Get JSON schema ----
{"title": "ModelWithLiteralStr", "type": "object", "properties": {"kind": {"title": "Kind", "enum": ["foo"], "type": "string"}}, "required": ["kind"]}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment