-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Closed
Labels
bug V1Bug related to Pydantic V1.XBug related to Pydantic V1.X
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
In 1.9 Code changed in this merge #2650 The "models_as_dict" option for json has collision issues when the class names are the same but in multiple files. This is because of the change to name in custom_pydantic_encoder. In the following code this will result in an error as DBUser.User does not have the field Address. If we force the encoder to be defined after the class this issue does not happen. The other option would be modification of update_forward_refs but that seems a lot worse.
Output of python -c "import pydantic.utils; print(pydantic.utils.version_info())":
pydantic version: 1.9.0a2
pydantic compiled: True
install path: /PycharmProjects/pythonProject/venv/lib/python3.8/site-packages/pydantic
python version: 3.8.9 (default, Oct 26 2021, 07:25:53) [Clang 13.0.0 (clang-1300.0.29.30)]
Tried it in 3.10 as well.
##DBusers.py
from pydantic import BaseModel
from uuid import UUID
class User(BaseModel):
name: str
user_id: UUID
##this one throws Exception
from typing import List, Optional
from pydantic import BaseModel
from DBUser import User as DBUser
from uuid import uuid4
class Address(BaseModel):
city: str
country: str
class User(BaseModel):
name: str
address: Address
friends: Optional[List['User']] = None
connections: Optional[List[DBUser]]=None
class Config:
json_encoders = {
Address: lambda a: f'{a.city} ({a.country})',
"User": lambda u: f'{u.name} in {u.address.city} '
f'({u.address.country[:2].upper()})',
}
User.update_forward_refs()
wolfgang = User(
name='Wolfgang',
address=Address(city='Berlin', country='Deutschland'),
friends=[
User(name='Pierre', address=Address(city='Paris', country='France')),
User(name='John', address=Address(city='London', country='UK')),
],
connections=[
DBUser(name="joe",user_id=uuid4()),
DBUser(name="Jeff", user_id=uuid4()),
]
)
wolfgang.json(indent=2,models_as_dict=False) ##Raises AttributeError: 'User' object has no attribute 'address'
##this one does not throw Exception
from typing import List, Optional
from pydantic import BaseModel
from DBUser import User as DBUser
from uuid import uuid4
class Address(BaseModel):
city: str
country: str
class User(BaseModel):
name: str
address: Address
friends: Optional[List["User"]] = None
connections: Optional[List[DBUser]]=None
class Config:
json_encoders = {
Address: lambda a: f'{a.city} ({a.country})',
}
User.update_forward_refs()
User.Config.json_encoders[User] =lambda u: f'{u.name} in {u.address.city} ' f'({u.address.country[:2].upper()})'
wolfgang = User(
name='Wolfgang',
address=Address(city='Berlin', country='Deutschland'),
friends=[
User(name='Pierre', address=Address(city='Paris', country='France')),
User(name='John', address=Address(city='London', country='UK')),
],
connections=[
DBUser(name="joe",user_id=uuid4()),
DBUser(name="Jeff", user_id=uuid4()),
]
)
print(wolfgang.json(indent=2,models_as_dict=False)) ##Does not explode
Metadata
Metadata
Assignees
Labels
bug V1Bug related to Pydantic V1.XBug related to Pydantic V1.X