-
Notifications
You must be signed in to change notification settings - Fork 175
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
Classes with cached_property
can't be cloudpickled
#438
Comments
Hii @durumu, pickling cached objects such as function/methods/properties is not yet supported by cloudpickle (see #178). A possible minimal fix (that would not attempt at pickling the cache contents when pickling the cached object, see #178 (comment)) should be relatively simple to implement, PR welcome. |
This seemingly also does not work for the class definition itself: from functools import cached_property
import cloudpickle
class MyExample:
def __init__(self, foo):
self.foo = foo
@cached_property
def bar(self) -> int:
return self.foo * 3
cloudpickle.dumps(MyExample) # fails |
Ran into a similar issue, inspired from this wrote similar functionality that uses from functools import cached_property
# This function is used to extract the necessary information to pickle a cached_property object.
def pickle_cached_property(obj: cached_property): # noqa: ANN202
# The `func` attribute of a cached_property object is the original method
# that was decorated with @cached_property.
# The `__globals__` attribute of that function contains a reference to the
# global namespace where the function was defined, which may include the owner class.
for cls in obj.func.__globals__.values():
# Check if the value is a class (owner of the cached_property).
if isinstance(cls, type):
for name, prop in cls.__dict__.items():
# Check if the property matches the cached_property we're trying to pickle.
if prop is obj:
return (unpickle_cached_property, (obj.func, cls, name))
# If the loop completes without returning, it means the owner class wasn't found.
err = f"Could not find the owner class for cached_property {obj}"
raise TypeError(err)
# Define a function to reconstruct the cached_property object during unpickling
def unpickle_cached_property(func, owner, name): # noqa: ANN202;
# Create a new cached_property object with the original function
prop = cached_property(func)
# The `__set_name__` method of a cached_property is normally called automatically
# when the property is assigned to a class attribute. However, since we are
# reconstructing the object during unpickling, we need to call it manually.
# This method sets up the internal state of the cached_property object
# so that it can function correctly when accessed as a class attribute.
prop.__set_name__(owner, name)
return prop
# Register the pickling and unpickling functions for the cached_property class
copyreg.pickle(cached_property, pickle_cached_property, unpickle_cached_property) |
I believe this is a bug.
Here is an example:
This fails with
TypeError: cannot pickle '_thread.RLock' object
.The text was updated successfully, but these errors were encountered: