Source code for gtirb.node

import typing
from uuid import UUID, uuid4

import typing_extensions
from google.protobuf.message import Message

from .util import DeserializationError

if typing.TYPE_CHECKING:  # pragma: no cover
    # Ignore flake8 "imported but unused" errors.
    from .ir import IR  # noqa: F401


_T = typing.TypeVar("_T", bound="Node")


class _NodeMessage(typing_extensions.Protocol):
    uuid: bytes


[docs]class Node: """A Node is any GTIRB object which can be referenced by UUID. :ivar ~.uuid: The UUID of this Node. """
[docs] def __init__(self, uuid: typing.Optional[UUID] = None) -> None: """ :param uuid: The UUID of this ``Node``, or None if a new UUID needs generated via :func:`uuid.uuid4`. Defaults to None. """ if uuid is None: uuid = uuid4() self.uuid = uuid
@classmethod def _decode_protobuf( cls: typing.Type[_T], proto_object: _NodeMessage, uuid: UUID, ir: typing.Optional["IR"], ) -> _T: """Decode a Protobuf object to a Python GTIRB object. Must be overridden by subclasses. :param proto_object: The Protobuf object. :param uuid: The UUID of the object. """ raise NotImplementedError # pragma: no cover @classmethod def _from_protobuf( cls: typing.Type[_T], proto_object: _NodeMessage, ir: typing.Optional["IR"], ) -> _T: """Deserialize a Node from Protobuf. Performs a cache lookup for the object's UUID in the cache, calling the class' _decode_protobuf constructor if cannot find it. """ uuid = UUID(bytes=proto_object.uuid) node = None if ir is not None: cached_node = ir.get_by_uuid(uuid) if isinstance(cached_node, cls): node = cached_node elif cached_node is not None: raise DeserializationError( "got %s for UUID %s but expected %s" % (type(cached_node).__name__, uuid, cls.__name__) ) if node is None: node = cls._decode_protobuf(proto_object, uuid, ir) return node def _to_protobuf(self) -> Message: """Get a Protobuf representation of ``self``. Must be overridden by subclasses. """ raise NotImplementedError # pragma: no cover
[docs] def deep_eq(self, other: object) -> bool: """Check: is ``self`` structurally equal to ``other``? This method should be used only when deep structural equality checks are actually needed, and not for all equality checks. Typically the default implmentation of __eq__, which checks pointer equality, is sufficient; Nodes are cached such that references to two Nodes with the same UUID refer to the same exact object. Use this method when you have manually constructed Nodes that may share the same UUID despite being different objects, and you need to check for structural equality. """ raise NotImplementedError # pragma: no cover