Last active
March 16, 2021 20:54
-
-
Save nymous/686d38ba1aa150fefe6da6d78b1cb441 to your computer and use it in GitHub Desktop.
Pydantic Literal enum bug in 1.8+
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
=== 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"]} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
=== 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"]} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
=== 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