Output of python -c "import pydantic.utils; print(pydantic.utils.version_info())":
pydantic version: 1.5.1
pydantic compiled: False
install path: /home/johnc/.virtualenvs/myproject/lib/python3.7/site-packages/pydantic
python version: 3.7.5 (default, Apr 19 2020, 20:18:17) [GCC 9.2.1 20191008]
platform: Linux-5.3.0-51-generic-x86_64-with-Ubuntu-19.10-eoan
optional deps. installed: []
Currently the result of default_factory isn't deepcopy'd, is this a bug or a feature?
In my use case it's actually useful, since my factory is intentionally returning a singleton, but I'm wondering if it's safe to rely on this?
If it's intended to stay this way I can add a unit test to avoid regression?
Or is this something you'd rather not lock down?
The relevant lines:https://github.com/samuelcolvin/pydantic/blob/5067508eca6222b9315b1e38a30ddc975dee05e7/pydantic/fields.py#L274-L282
Example code:
from typing import Union
import pydantic
class Sentinel:
pass
MY_SENTINEL = Sentinel()
class Foo(pydantic.BaseModel):
myfield: Union[str, Sentinel] = pydantic.Field(default_factory=lambda : MY_SENTINEL)
class Config:
arbitrary_types_allowed = True
assert Foo().myfield is Foo().myfield
this is almost certainly intentional; having a customizable default_factory allows the user to provide unique copies if needed anyway
Hi @therefromhere!
It is indeed intentional ! This is the exact same behaviour as dataclasses from the standard library:
from dataclasses import dataclass, field
from typing import Union
class Sentinel:
pass
MY_SENTINEL = Sentinel()
@dataclass
class Bar:
myfield: Union[str, Sentinel] = field(default_factory=lambda: MY_SENTINEL)
assert Bar().myfield is Bar().myfield
Most helpful comment
Hi @therefromhere!
It is indeed intentional ! This is the exact same behaviour as
dataclassesfrom the standard library: