Source code for zoti_graph.core

from enum import Flag
from pathlib import PurePosixPath
from typing import Dict
from copy import deepcopy

from zoti_graph.util import SearchableEnum, default_init, default_repr


# meta attributes (added by the loader)
META_UID = "__uid__"

# keywords (read from the user input)
KEY_NODE = "nodes"
KEY_PORT = "ports"
KEY_EDGE = "edges"
KEY_PRIM = "primitives"

# attributes (read from user input)
ATTR_NAME = "name"
ATTR_KIND = "kind"
ATTR_ENT = "entry"
ATTR_REL = "relation"


[docs]class Uid: """Class denoting unique identifiers for hierarchically organized entities. Internally is based on ``PurePosixPath`` from `pathlib <https://docs.python.org/3/library/pathlib.html>`_. :param uid: if ``None`` then the root path ``/`` is assumed """ _uid: PurePosixPath def __init__(self, uid=None): if isinstance(uid, PurePosixPath): self._uid = uid elif uid: self._uid = PurePosixPath(uid) else: self._uid = PurePosixPath("/") def __repr__(self): return self._uid.as_posix() def __eq__(self, other): if other: return self._uid == other._uid else: return False def __lt__(self, other): return len(self._uid.parts) < len(other._uid.parts) def __gt__(self, other): return len(self._uid.parts) > len(other._uid.parts) def __hash__(self): return hash(self._uid)
[docs] def name(self): """ Returns the (base)name from a path. """ basename = self._uid.name return basename[1:] if basename.startswith("^") else basename
[docs] def parent(self): """ Returns the ID of the parent of this entity. """ return Uid(self._uid.parent)
[docs] def withNode(self, name: str): """ Builds a child node ID by appending its name to this path. """ return Uid(self._uid.joinpath(name))
[docs] def withPort(self, name: str): """ Builds a port ID by appending its name to this path. """ return Uid(self._uid.joinpath("^" + name))
[docs] def withPath(self, path, port=None): """Builds an ID by appending a given path to this one. if the ``port`` argument is also provided, it creates a port ID. """ if port is not None: newpath = self._uid.joinpath(path._uid).joinpath("^" + port) else: newpath = self._uid.joinpath(path._uid) return Uid(newpath)
[docs] def withSuffix(self, suffix): """ adds only a suffix string to the current id. """ return Uid(self._uid.with_name(f"{self._uid.name}_{suffix}"))
[docs] def replaceRoot(self, old_root, new_root): while not self._uid.is_relative_to(old_root._uid) and old_root: old_root = old_root.parent() path = self._uid.relative_to(old_root._uid) return Uid(new_root._uid.joinpath(path))
########## ## EDGE ## ##########
[docs]class Rel(Flag, metaclass=SearchableEnum): """ Bitwise flags denoting kinds of edges. """ TREE = 3 # : 011 CHILD = 1 # : 001 belongs to tree PORT = 2 # : 010 belongs to tree GRAPH = 4 # : 100 NONE = 0 # : 000
[docs]class Edge: """Container for edge entry.""" mark: Dict _info: Dict
########## ## PORT ## ##########
[docs]class Port: """Container for port entry.""" name: str mark: Dict _info: Dict
[docs] def duplicate(self, **kwargs): ret = deepcopy(self) for k, v in kwargs.items(): setattr(ret, k, v) return ret
########### ## NODES ## ###########
[docs]class Node: """Base class for a leaf node""" name: str parameters: Dict mark: Dict _info: Dict
[docs] def duplicate(self, **kwargs): ret = deepcopy(self) for k, v in kwargs.items(): setattr(ret, k, v) return ret