> [!META]- Inline Metadata [status:: boat] [tags:: #state/boat #note/evergreen #concepts/python ] [up:: [[Python MOC]]] When you have a class that is used to hold data and is regularly pickled and later retrieved and unpickled, updates to the class in the environment that unpickle the object can cause issues (such as different attributes). For this reason, it is helpful to store the instance's version and make automated changes to make old pickled instances compatible with the latest version of the object. # Storing the Object Version Python's `importlib.metadata` module allows you to get the **distribution version** of a package, so this is useful when you are using a packaging system (such as setuptools or poetry) and your class is part of that package. What you will do is upon instantiation, set a version attribute to the version of the package using importlib like so: ```python class Test: def __init__(self): self.version = importlib.metadata.version("package_name") ``` # Using `__setstate__` to Update an Object Upon Unpickling A really powerful tool for this use case is `__setstate__()` which allows you to update an object's state when unpickling it. Used in conjunction with versioning, you could use it to check an object's version and make it compatible based on that. Here is a simpler example showing across-the-board updates based on missing attributes: ```python def __setstate__(self, state): """ Magic method for unpickling that allows us to unpickle old instances In future cases, when potentially breaking version changes are made, do version check to make required updates. """ if "attribute_name" in state: self.new_attribute_name = [state["attribute_name"]] del state["attribute_name"] if "other_attribute" not in state: self.other_attribute = False self.__dict__.update(state) ``` # Sources - [importlib.metadata.version documentation](https://docs.python.org/3/library/importlib.metadata.html)