order.unique#

Classes that define unique objects and the index to store them.

Class UniqueObject#

class UniqueObject(name, id)[source]#

Bases: object

An unique object defined by a name and an id. The purpose of this class is to provide a simple interface for objects that

  1. are used programatically and should therefore have a unique, human-readable name, and

  2. have a unique identifier that can be saved to files, such as (e.g.) ROOT trees.

Both, name and id should have unique values within a certain UniqueObjectIndex.

Arguments

name and id initialize the same-named attributes.

Example

import order as od

foo = od.UniqueObject("foo", 1)

foo.name, foo.id
# -> "foo", 1

# name and id must be strictly string and integer types, respectively
od.UniqueObject(123, 1)
# -> TypeError: invalid name: 123
UniqueObject("foo", "mystring")
# -> TypeError: invalid id: mystring

# unique objects can als be compared by name and id
foo == 1
# -> True

bar == "bar"
# -> True

foo == bar
# -> False

# automatically use the next highest possible id
obj = UniqueObject("baz", id=UniqueObject.AUTO_ID)  # same as "+"

obj.id
# -> 2  # 1 is the previous maximum id

Members

classattribute cls_name_singular#

type: str

The name of the unique object class in singular form, e.g. for producing automatic messages.

classattribute cls_name_plural#

type: str

The name of the unique object class in plural form, e.g. for producing automatic messages.

name#

type: str (read-only)

The unique name.

id#

type: int (read-only)

The unique id.

Class UniqueObjectIndex#

class UniqueObjectIndex(cls, objects=None)[source]#

Bases: order.mixins.CopyMixin

Index of UniqueObject instances which are - as the name suggests - unique within this index, enabling fast lookups by either name or id.

Arguments

cls must be a subclass of UniqueObject, which is used for type validation when a new object is added to the index.

Copy behavior

All attributes are copied, except for

  • the index of objects itself.

Example

import order as od

idx = od.UniqueObjectIndex()
foo = idx.add("foo", 1)
bar = idx.add("bar", 2)

len(idx)
# -> 2

idx.get(1) == foo
# -> True

idx.add("foo", 3)
# -> DuplicateNameException

idx.add("test", 1)
# -> DuplicateIdException

idx.names()
# -> ["foo", "bar"]

idx.ids()
# -> [1, 2]

Members

cls#

type: UniqueObjectMeta (read-only)

Class of objects hold by this index.

n#

type: DotAccessProxy (read-only)

An object that provides simple attribute access to contained objects via name.

Methods:

names()

Returns the names of the contained objects in the index.

ids()

Returns the ids of the contained objects in the index.

keys()

Returns the (name, id) pairs of all objects contained in the index.

values()

Returns all objects contained in the index.

items()

Returns (name, id, object) 3-tuples of all objects contained in the index

add(*args[, overwrite])

Adds a new object to the index.

extend(objs[, overwrite])

Adds multiple new objects to the index.

get(obj[, default])

Returns an object that is stored in the index.

get_first([default])

Returns the first object that is stored in the index.

get_last([default])

Returns the last object that is stored in the index.

has(obj)

Checks if an object is contained in the index.

index(obj)

Returns the position of an object in the index.

remove(obj[, silent])

Removes an object from the index.

clear()

Removes all objects from the index.

names()[source]#

Returns the names of the contained objects in the index.

ids()[source]#

Returns the ids of the contained objects in the index.

keys()[source]#

Returns the (name, id) pairs of all objects contained in the index.

values()[source]#

Returns all objects contained in the index.

items()[source]#

Returns (name, id, object) 3-tuples of all objects contained in the index

add(*args, overwrite=True, **kwargs)[source]#

Adds a new object to the index. When the first arg is not an instance of cls, all args and kwargs are passed to the cls constructor to create a new object. The added object is returned.

By default, in case an object with the same name or id was already registered before, it is overwritten by the new object. When overwrite is False, an exception is raised instead.

extend(objs, overwrite=False)[source]#

Adds multiple new objects to the index. All elements of the sequence objs, as well as overwrite, are forwarded to add() and the added objects are returned in a list. When an object is a dictionary or a tuple, it is expanded for the invocation of add().

get(obj, default=no_default)[source]#

Returns an object that is stored in the index. obj might be a name, id, or an instance of cls. If default is given, it is used as the default return value if no such object could be found. Otherwise, an error is raised.

get_first(default=no_default)[source]#

Returns the first object that is stored in the index. If default is given, it is used as the default return value if no object could be found. Otherwise, an exception is raised.

get_last(default=no_default)[source]#

Returns the last object that is stored in the index. If default is given, it is used as the default return value if no object could be found. Otherwise, an exception is raised.

has(obj)[source]#

Checks if an object is contained in the index. obj might be a name, id, or an instance of the wrapped cls.

index(obj)[source]#

Returns the position of an object in the index. obj might be a name, id, or an instance of cls. When the object is not found in the index, an exception is raised.

remove(obj, silent=False)[source]#

Removes an object from the index. obj might be a name, id, or an instance of cls. Returns the removed object. Unless silent is True, an exception is raised if the object could not be found.

clear()[source]#

Removes all objects from the index.

Class UniqueObjectMeta#

class UniqueObjectMeta(class_name, bases, class_dict)[source]#

Bases: type

Meta class definition for UniqueObject that ammends the class dict for newly created classes.

Decorator unique_tree#

unique_tree(cls=None, parents=1, deep_children=False, deep_parents=False, skip=None)[source]#

Decorator that adds attributes and methods to the decorated class to provide tree features, i.e., parent-child relations. Example:

@unique_tree()
class MyNode(UniqueObject):
    cls_name_singular = "node"
    cls_name_plural = "nodes"

# now, MyNode has the following attributes and methods:
# nodes,          parent_nodes,
# has_node(),     has_parent_node(),
# add_node(),     add_parent_node(),
# remove_node(),  remove_parent_node(),
# walk_nodes(),   walk_parent_nodes(),
# get_node(),     get_parent_node(),
# has_nodes,      has_parent_nodes,
# is_leaf_node,   is_root_node

c1 = MyNode("nodeA", 1)
c2 = c1.add_node("nodeB", 2)

c1.has_node(2)
# -> True

c2.has_parent_node("nodeA")
# -> True

c2.remove_parent_node(c1)
c2.has_parent_node("nodeA")
# -> False

cls denotes the type of instances the tree should hold and defaults to the decorated class itself. When parents is False, the additional features are reduced to provide only child relations. When parents is an integer, it is interpreted as the maximim number of parents a child can have. Negative numbers mean that an unlimited amount of parents is allowed. Additional convenience methods are added when parents is True or exactly 1. When deep_children (deep_parents) is True, get_* and has_* child (parent) methods will have recursive features. When skip is a sequence, it can contain names of attributes to skip that would normally be created.

A class can be decorated multiple times. Internally, the objects are stored in a separated UniqueObjectIndex instance per added tree functionality.

Doc strings are automatically created.