-
-
Notifications
You must be signed in to change notification settings - Fork 65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
2.2.0 broke support for nested BaseSettings with base type (e.g. using ABC) #241
Comments
Thanks @moonrail for reporting this and sorry for the problem.
agree
Yes, you are right. As this wasn't the plan I am going to introduce a config flag for this change and make this disable by default. So, You will have the old behavior after my fix.
We really try to not introduce breaking changes in minor releases but we are not aware of all the use-cases. |
@moonrail Could you please test it with Could you provide |
I think the validation error here is correct because you defined |
Hey @hramezani Tested code is: from abc import ABC, abstractmethod
from pydantic import SecretStr, HttpUrl
from pydantic_settings import BaseSettings
class BaseAuth(ABC, BaseSettings):
@property
@abstractmethod
def token(self) -> str:
"""returns authentication token for XYZ"""
pass
class CustomAuth(BaseAuth):
url: HttpUrl
username: str
password: SecretStr
_token: SecretStr = None
@property
def token(self):
... # (re)fetch token
return self._token.get_secret_value()
class Settings(BaseSettings):
auth: BaseAuth
s = Settings(
auth=CustomAuth(
url='https://127.0.0.1',
username='some-username',
password='some-password'
)
)
print(s.auth)
print(type(s.auth)) pydantic-settings 2.0.0 and 2.1.0 print:
While pydantic-settings 2.2.0 prints: Traceback (most recent call last):
File "/tmp/test_pydantic_settings_nesting.py", line 32, in <module>
s = Settings(
^^^^^^^^^
File "/tmp/venv/lib/python3.11/site-packages/pydantic_settings/main.py", line 85, in __init__
super().__init__(
File "/tmp/venv/lib/python3.11/site-packages/pydantic/main.py", line 171, in __init__
self.__pydantic_validator__.validate_python(data, self_instance=self)
TypeError: Can't instantiate abstract class BaseAuth with abstract method token |
pydantic-settings 2.2.1 just released. I reverted that change. |
Hello altogether,
change #204 is a breaking change. It introduces a dict-cast that leads to nested copy-by-value for BaseSettings instances. In 2.1.0 it was copy-by-reference.
See this line: https://github.com/pydantic/pydantic-settings/pull/204/files#diff-b4b68ace3cb0cf2820d1d882735748b675a379c39463ccc89700a9618a80a2a2R124
This breaks any use-case with a base class/type and/or abc classes, where the type is not explicitly known beforehand.
E.g. for pluggable authentication:
Upon execution you'll receive following ValidationException:
From this POV 2.2.0 should be 3.0.0, as this is a Breaking Change. Moving from copy-by-reference to copy-by-value with casting is a change that can have a lot of impact in an interfacing-focused library.
As a side note: The amount of breaking changes in Minor-Releases across the pydantic project increased in the last year. We have more and more debugging sessions regarding it and are scratching our heads, if and how we are possibly "holding it wrong" or its something out of our control and pydantic is not as stable as it should be...
The text was updated successfully, but these errors were encountered: