Skip to content
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

Instances of LiquidMetalInterface class not pickable #208

Closed
lelaus opened this issue Nov 14, 2024 · 2 comments
Closed

Instances of LiquidMetalInterface class not pickable #208

lelaus opened this issue Nov 14, 2024 · 2 comments
Assignees
Labels
enhancement New feature or request

Comments

@lelaus
Copy link
Collaborator

lelaus commented Nov 14, 2024

The objects created as instantiations of the class LiquidMetalInterface are not pickable. To reproduce this limitation, try this code:

import pickle
from lbh15 import Lead
ll=Lead(T=1000)
with open('test.dat', 'wb') as file:
    pickle.dump(ll, file, protocol=pickle.DEFAULT_PROTOCOL)

The following error is returned:
AttributeError: Can't pickle local object 'LiquidMetalInterface.__add_property.<locals>.<lambda>'

An extension should be implemented to make such objects pickable, allowing them to be serialized and saved into a file.

The reason why a LiquidMetalInterface object is not pickable is because a lambda function is used within the __add_property() method of _lbh15.py module. Lambda functions create anonymous function objects, while pickle records references to functions as module-level names, and not the functions themselves. So, an alternative solution should be sought.

In issue #63 , the Lambda function was introduced to simplify the implementation by avoiding the definition of the inner function new_property_info(). However, the previous solution also doesn't make an instance of the LiquidMetalInterface class pickable. The reason for this is that the inner functions do not make their names available at the module-level either.

So, among the others, two options could be suggested:

  1. to define an external module-level function, that should be passed as argument to the function setattr() in the method __add_property();
  2. to use functools.partial according to what stated, for instance, in https://docs.python.org/3/library/functools.html#partial-objects and https://stackoverflow.com/questions/58361373/are-partial-functions-officially-picklable.
@lelaus lelaus added the enhancement New feature or request label Nov 14, 2024
@lelaus lelaus added this to the Release of v3.0.0 milestone Nov 14, 2024
@lelaus lelaus self-assigned this Nov 14, 2024
lelaus added a commit that referenced this issue Nov 14, 2024
…ner function in LiquidMetalInterface class
@lelaus
Copy link
Collaborator Author

lelaus commented Nov 14, 2024

The solution implemented in commit 5703f93 is to replace the lambda function passed to setattr() in the __add_property() method with the private __property_info() method of the LiquidMetalInterface class. This way pickle can reference the name of this private method. This also implies the need to use functools.partial to define the method to add to the LiquidMetalInterface instance in __add_property(), so that you can only define the method to call and not call it.

@panDanieleN
Copy link
Collaborator

Merged into master.

No need to update tests and doc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants