-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
Checks
- I added a descriptive title to this issue
- I have searched (google, github) for similar issues and couldn't find anything
- I have read and followed the docs and still think this is a bug
Bug
Output of python -c "import pydantic.utils; print(pydantic.utils.version_info())":
pydantic version: 1.8.2
pydantic compiled: True
install path: C:\Users\jmartins\.virtualenvs\pydantic_bug_report-NJE4-7fw\Lib\site-packages\pydantic
python version: 3.9.6 (tags/v3.9.6:db3ff76, Jun 28 2021, 15:26:21) [MSC v.1929 64 bit (AMD64)]
platform: Windows-10-10.0.19042-SP0
optional deps. installed: ['typing-extensions']
Generating a schema with the .schema() method works as expected when resolving default values of Enum type, while it does not resolve default values of IntEnum type the same way. A minimum example follows:
# std lib imports
from enum import Enum, IntEnum
# external imports
from pydantic import BaseModel
class ExampleEnum(Enum):
A = "a"
class ExampleIntEnum(IntEnum):
A = 1
class ExampleModel(BaseModel):
example_enum: ExampleEnum = ExampleEnum.A
example_int_enum: ExampleIntEnum = ExampleIntEnum.A
generated_schema_properties = ExampleModel.schema().get("properties", {})
example_enum_generated_default = generated_schema_properties.get("example_enum", {}).get("default", None)
example_int_enum_generated_default = generated_schema_properties.get("example_int_enum", {}).get("default", None)
print(example_enum_generated_default is ExampleEnum.A.value)
# -> True
print(example_int_enum_generated_default is ExampleIntEnum.A.value)
# -> FalseI've tracked the issue down to the encode_default function in schema.py:
def encode_default(dft: Any) -> Any:
if isinstance(dft, (int, float, str)):
return dft
elif sequence_like(dft):
t = dft.__class__
return t(encode_default(v) for v in dft)
elif isinstance(dft, dict):
return {encode_default(k): encode_default(v) for k, v in dft.items()}
elif dft is None:
return None
else:
return pydantic_encoder(dft)When resolving defaults for Enum the else clause is correctly used, but since isinstance(ExampleIntEnum.A, int) is truthy it returns ExampleIntEnum.A when using an IntEnum. I would suggest changing the first if to a stricter direct 'primitive' type check like if type(dft) in (int, float, str):.
I can do this myself and open a PR if there is interest and no opposition to a stricter type check.