Skip to content

Commit

Permalink
ORM: raise when trying to pickle instance of Entity (#5549)
Browse files Browse the repository at this point in the history
The ORM entities should not be pickled since it is not clear whether the
connection to the storage backend should be included as well and if it
were, implementing that in a consistent way across implementations is
not feasible.

Therefore, we now raise an explicit an `InvalidOperation` when an
instance of `Entity` is being pickled. This is achieved by overriding
the `__getstate__` dunder method which will be called by the `pickle`
module when dumping a class instance.
  • Loading branch information
sphuber authored Jun 1, 2022
1 parent 8fdc4e4 commit 1c509c5
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 0 deletions.
5 changes: 5 additions & 0 deletions aiida/orm/entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

from plumpy.base.utils import call_with_super_check, super_check

from aiida.common.exceptions import InvalidOperation
from aiida.common.lang import classproperty, type_check
from aiida.common.warnings import warn_deprecation
from aiida.manage import get_manager
Expand Down Expand Up @@ -217,6 +218,10 @@ def __init__(self, backend_entity: BackendEntityType) -> None:
self._backend_entity = backend_entity
call_with_super_check(self.initialize)

def __getstate__(self):
"""Prevent an ORM entity instance from being pickled."""
raise InvalidOperation('pickling of AiiDA ORM instances is not supported.')

@super_check
def initialize(self) -> None:
"""Initialize instance attributes.
Expand Down
8 changes: 8 additions & 0 deletions tests/orm/test_entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@
###########################################################################
# pylint: disable=no-self-use
"""Test for general backend entities"""
import pickle

import pytest

from aiida import orm
from aiida.common.exceptions import InvalidOperation


@pytest.mark.usefixtures('aiida_profile_clean')
Expand All @@ -37,3 +40,8 @@ def test_collections_count(self):
number_of_users, \
'{} User(s) was/were found using Collections\' count() method, ' \
'but {} User(s) was/were found using QueryBuilder directly'.format(user_collection_count, number_of_users)

def test_pickle(self):
"""Pickling is not supported and should raise."""
with pytest.raises(InvalidOperation):
pickle.dumps(orm.Entity({}))

0 comments on commit 1c509c5

Please sign in to comment.