pyiron_workflow.mixin.lexical module

Classes for “lexical” reasoning.

The motivation here is to be able to provide the object with a unique identifier in the context of other lexical objects. Each object may have at most one parent, while lexical parents may have an arbitrary number of children, and each child’s name must be unique in the scope of that parent. In this way, when lexical parents are also themselves lexical, we can build a path from the parent-most object to any child that is completely unique. The typical filesystem on a computer is an excellent example and fulfills our requirements, the only reason we depart from it is so that we are free to have objects stored in different locations (possibly even on totally different drives or machines) belong to the same lexical group.

exception pyiron_workflow.mixin.lexical.AlreadyHasParentError[source]

Bases: ValueError

To be raised when parenting an already-parented child.

exception pyiron_workflow.mixin.lexical.CyclicPathError[source]

Bases: ValueError

To be raised when adding a child would result in a cyclic lexical path.

class pyiron_workflow.mixin.lexical.Lexical(*args, label: str | None = None, parent: ParentType | None = None, **kwargs)[source]

Bases: UsesState, HasLabel, Generic[ParentType], ABC

An object with a unique lexical path.

The lexical parent object (if any), and the parent-most object are both easily accessible.

as_path(root: Path | str | None = None, mkdir: bool = False) Path[source]

The lexical path as a pathlib.Path, with a filesystem :param:`root` (default is the current working directory).

clean_path(root: Path | str | None = None, clean_parents: bool = True, remove_files: bool = False) None[source]

Recursively remove this object’s directory and optionally its ancestors. Unless :param:`remove_files` is True, this will only remove empty directories. If non-lexical directories are present, they will always block removal.

If this object is itself a lexical parent, it will run cleaning recursively on its children.

Parameters:
  • root – Base path from which to resolve the lexical path.

  • clean_parents – If True, also attempt to remove parent directories.

  • remove_files – If True, delete files within the directory before removal.

property detached_parent_path: str | None

The get/set state cycle of Lexical de-parents objects, but we may still be interested in the lexical path – e.g. if we pickle dump and load the object we will lose parent information, but this will still hold what the path _was_ before the orphaning process.

The detached path will get cleared if a new parent is set, but is otherwise used as the root for the purposes of finding the lexical path.

property full_label: str

A shortcut that combines the lexical path and label into a single string.

lexical_delimiter: ClassVar[str] = '/'
property lexical_path: str

The path of node labels from the graph root (parent-most node) down to this node.

property lexical_root: Lexical

The parent-most object in this lexical path; may be self.

property parent: ParentType | None
class pyiron_workflow.mixin.lexical.LexicalParent(*args, strict_naming: bool = True, **kwargs)[source]

Bases: HasLabel, Generic[ChildType], ABC

A labeled object with a collection of uniquely-named lexical children.

Children should be added or removed via the add_child() and remove_child() methods and _not_ by direct manipulation of the children container.

Children are dot-accessible and appear in __dir__() for tab-completion.

Iterating over the parent yields the children, and the length of the parent is the number of children.

When adding children or assigning parents, a check is performed on the lexical path to forbid cyclic paths.

add_child(child: ChildType, label: str | None = None, strict_naming: bool | None = None) ChildType[source]

Add a child, optionally assigning it a new label in the process.

Parameters:
  • child (ChildType) – The child to add.

  • label (str|None) – A (potentially) new label to assign the child. (Default is None, leave the child’s label alone.)

  • strict_naming (bool|None) – Whether to append a suffix to the label if another child is already held with the same label. (Default is None, use the class-level flag.)

Returns:

The child being added.

Return type:

(ChildType)

Raises:
  • TypeError – When the child is not of an allowed class.

  • ValueError – When the child has a different parent already.

  • AttributeError – When the label is already an attribute (but not a child).

  • AttributeError – When the label conflicts with another child and strict_naming is true.

property child_labels: tuple[str]
abstractmethod classmethod child_type() type[ChildType][source]
property children: bidict[str, ChildType]
remove_child(child: ChildType | str) ChildType[source]