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
Pydantic 1.9.1 deepcopy breaks Redis caching, possibly other things #333
Comments
Ok, thanks for the analysis. Would you like to submit a PR? |
If you'd be OK with passing |
Absolutely |
Here's a repro for the pydantic side: import tempfile
from typing import Any
import pydantic
class Container(pydantic.BaseModel):
fh: Any
@pydantic.validate_arguments(config={"copy_on_model_validation": False})
def receives_container(container: Container) -> None:
...
with tempfile.TemporaryFile() as fh:
receives_container(Container(fh=fh)) Results in: Traceback (most recent call last):
File "/home/peter/PycharmProjects/copy-on-model-validation/main.py", line 17, in <module>
receives_container(Container(fh=fh))
File "pydantic/decorator.py", line 40, in pydantic.decorator.validate_arguments.validate.wrapper_function
File "pydantic/decorator.py", line 133, in pydantic.decorator.ValidatedFunction.call
File "pydantic/decorator.py", line 130, in pydantic.decorator.ValidatedFunction.init_model_instance
File "pydantic/main.py", line 341, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for ReceivesContainer
container
cannot pickle '_io.BufferedRandom' object (type=type_error) I created that as I found this issue: pydantic/pydantic#3284 and wanted a quick test.. and as that issue suggests Setting it on the |
Well, if passing it to |
So whats the solution? we strip validate arguments or we pin to 1.9? Or is there an alternative? |
As a user, I'm pinning to Pydantic 1.9.0 until they decide what they're going to do about it. I'm not sure, and I don't presume to tell you, what the best choice is for Starlite -- both pinning and remove |
We should probably set |
I just did a rebuild of my app using Pydantic 1.9.1 and Starlite 1.8.1, and does indeed seem to work. Thanks for the quick fix. |
I'm open to the possibility that this should be treated as an issue in Pydantic because it's a breaking change there, and pydantic/pydantic#4184 appears to be a variation of this.
I have a Starlite application which configures its caching as follows (excerpt from my actual
app.py
):config.settings
in this case is apydantic.BaseSettings
instance which reads the Redis URL from an environment variable, if set. The fallback logic is for local development where a Redis instance may not be running.I recently did an upgrade of my dependency tree which moved from Pydantic 1.9.0 to Pydantic 1.9.1, and my web worker processes now fail to boot. Reverting to Pydantic 1.9.0 resolves this.
The failure occurs at instantiating the
Starlite
application object:The root of the issue appears to be that in Pydantic 1.9.1, Pydantic defaults to performing a
copy.deepcopy()
of model members during validation, which in turn fails on encountering any non-pickle-able object (as in the above traceback where it attempts todeepcopy()
a Redis client instance). Pydantic 1.9.0 performed only a shallow copy.This behavior can be disabled by setting the
copy_on_model_validation
option to a false-y value in the config for a Pydantic model class, or by passing it in theconfig
dictionary of thevalidate_arguments
decorator, and that may be the simplest workaround to apply for now while Pydantic decides what to do about this. It may also be the correct long-term choice since it's likely that non-pickle-able objects, such as caching clients, will be passed in arguments to theStarlite
constructor from time to time.This issue appears to be present in any version of Starlite which decorates
Starlite.__init__()
withvalidate_arguments
, when using Pydantic 1.9.1 (I've tested Starlite 1.7.3 and 1.3.3), and disappears on reverting to Pydantic 1.9.0.The text was updated successfully, but these errors were encountered: