Skip to content

Commit

Permalink
Lazily define _plugin_type_string and _query_type_string of Node`
Browse files Browse the repository at this point in the history
These class attributes require a look up whether the `Node` class has a
registered entry point which can have a non-negligible cost. These
attributes were defined in the `AbstractNodeMeta` class, which is the
metaclass of the `Node` class, which would cause this code to be
executed as soon as the class was imported.

Here, the `AbstractNodeMeta` metaclass is removed. The
`_plugin_type_string` and `_query_type_string` class attributes are
changed to class properties. The actual value is stored in the private
attribute analog which is defined lazily the first time the property is
accessed.
  • Loading branch information
sphuber committed Aug 31, 2023
1 parent 517ffcb commit 3a61a70
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 9 deletions.
25 changes: 21 additions & 4 deletions aiida/orm/nodes/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@
from aiida.common.links import LinkType
from aiida.common.warnings import warn_deprecation
from aiida.manage import get_manager
from aiida.orm.utils.node import AbstractNodeMeta
from aiida.orm.utils.node import ( # pylint: disable=unused-import
AbstractNodeMeta,
get_query_type_from_type_string,
get_type_string_from_class,
)

from ..computers import Computer
from ..entities import Collection as EntityCollection
Expand Down Expand Up @@ -149,9 +153,22 @@ class Node(Entity['BackendNode', NodeCollection], metaclass=AbstractNodeMeta):
_CLS_NODE_LINKS = NodeLinks
_CLS_NODE_CACHING = NodeCaching

# added by metaclass
_plugin_type_string: ClassVar[str]
_query_type_string: ClassVar[str]
__plugin_type_string: ClassVar[str]
__query_type_string: ClassVar[str]

@classproperty
def _plugin_type_string(cls) -> str:
"""Return the plugin type string of this node class."""
if not hasattr(cls, '__plugin_type_string'):
cls.__plugin_type_string = get_type_string_from_class(cls.__module__, cls.__name__) # type: ignore[misc]
return cls.__plugin_type_string

@classproperty
def _query_type_string(cls) -> str:
"""Return the query type string of this node class."""
if not hasattr(cls, '__query_type_string'):
cls.__query_type_string = get_query_type_from_type_string(cls._plugin_type_string) # type: ignore[misc]
return cls.__query_type_string

# This will be set by the metaclass call
_logger: Optional[Logger] = None
Expand Down
5 changes: 0 additions & 5 deletions aiida/orm/utils/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,4 @@ class AbstractNodeMeta(ABCMeta):
def __new__(mcs, name, bases, namespace, **kwargs):
newcls = ABCMeta.__new__(mcs, name, bases, namespace, **kwargs) # pylint: disable=too-many-function-args
newcls._logger = logging.getLogger(f"{namespace['__module__']}.{name}")

# Set the plugin type string and query type string based on the plugin type string
newcls._plugin_type_string = get_type_string_from_class(namespace['__module__'], name) # pylint: disable=protected-access
newcls._query_type_string = get_query_type_from_type_string(newcls._plugin_type_string) # pylint: disable=protected-access

return newcls

0 comments on commit 3a61a70

Please sign in to comment.