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
cached_property issues #1241
Comments
You might be able to use I want to make some improvements to the interface for skipping types, replacing I'd be happy to accept a PR to correctly skip python 3.8's
|
Yep, just to be clear, it would look like this: class A(BaseModel):
class Config:
arbitrary_types_allowed = True
keep_untouched = (cached_property,)
@cached_property
def test(self):
return 10 I use this with some of my own models without a problem. |
Hi, thank you very much, it works fine. The issue now is that you cannot set the property. e.g. class A(BaseModel):
class Config:
arbitrary_types_allowed = True
keep_untouched = (cached_property,)
@cached_property
def test(self):
return 10
a = A()
a.test = 15
# Traceback (most recent call last):
# File "<input>", line 1, in <module>
# File "pydantic/main.py", line 290, in pydantic.main.BaseModel.__setattr__
# ValueError: "A" object has no field "test" While with vanilla python classes, the class A:
@cached_property
def test(self):
return 10
a = A()
print(a.test)
# 10
a.test = 15
print(a.test)
# 15 |
that's a separate issue and related to #655. |
Note that, as discussed in #655, you can work around this via from functools import cached_property
from pydantic import BaseModel
class A(BaseModel):
class Config:
arbitrary_types_allowed = True
keep_untouched = (cached_property,)
@cached_property
def test(self):
return 10
a = A()
print(repr(a))
# A()
print(a.dict())
# {}
print(a.test) # causes cached property to be computed and stored on instance
# 10
print(repr(a))
# A(test=10)
# note that the cached property is now part of the unstructuring/serialization,
# even though it wasn't before:
print(a.dict())
# {'test': 10}
object.__setattr__(a, "test", 15)
print(repr(a))
# A(test=15) |
Note that through a custom rework of the Basically, you'd want to keep the cached value living in a property of the And note that to prevent memory leaks you'd probably want the cache to be a Given the complexity here, I'd probably just recommend using a different approach than |
I think the solution is to wait for #935 and either document that |
I tested today and #1241 (comment) works fine even without >>> from functools import *; import pydantic
>>> class Test():
... class Config:
... keep_untouched=(cached_property,)
... @cached_property
... def hola(self)->str:
... print('done')
... return "yo"
>>> t=Test()
>>> t.hola
done
'yo'
>>> t.hola
'yo' |
from functools import cached_property
from pydantic import BaseModel
class Bar(BaseModel):
spam: int
eggs: int
@cached_property
def spameggs(self) -> int:
return self.spam + self.eggs
class Config:
keep_untouched = (cached_property,) # https://github.com/samuelcolvin/pydantic/issues/1241
bar = Bar(spam=10, eggs=20)
print(bar.spameggs)
print(bar) Run result:
Is it related or I need to create a separate issue? |
Hi @AlekseiMarinichenko |
Update: |
Unable to use cached_property
Hi,
I am using pydantic for almost any project right now and I find it awesome.
I recently found an handy package, funcy, and I am trying to work with
cached_property
decorator.What I am doing is something like this:
The
arbitrary_types_allowed = True
is needed because if not present, aValidationError
is raised:When i do:
Same happens with python3.8
cached_property
.If doing the same with a vanilla python class, the behaviour is the expected one (the property outputs 10).
Is there anything I am missing?
Could anyone help me?
Thank you very much, pydantic is really great and you are doing a terrific job.
The text was updated successfully, but these errors were encountered: