nxt.stage module

class CompArc[source]

Bases: object

REFERENCE = 'reference'
PARENT = 'parent'
INSTANCE = 'instance'
ALL_ARCS = ('reference', 'parent', 'instance')
PRE_PROXY_ARCS = ['reference']
POST_PROXY_ARCS = ['parent', 'instance']
INHERITANCE_MAP = {'instance': ('_enabled', '_comment', '_code'), 'parent': (), 'reference': ('_start_point', '_enabled', '_execute_in', '_instance', '_comment', '_code')}
ATTR_NAMES = {'instance': '_instance', 'parent': '_parent_path'}
static get_arc(comp_node, node_to_check, comp_layer)[source]
Parameters
  • comp_node –

  • node_to_check –

  • comp_layer – CompLayer

Returns

CompArc or None

static get_bases_arc_dict(comp_node, comp_layer)[source]

Returns a dict mapping nodes from the bases tuple to their comp arc. If there is no node for an arc its corresponding key will not be present in the dict. {REFERENCE: [SpecNode, SpecNode], PARENT: CompNode, INSTANCE: CompNode} :param comp_node: CompNode :param comp_layer: CompLayer :return: dict

class Modes[source]

Bases: object

REPLACE = 'REPLACE'
ADD = 'ADD'
REMOVE = 'REMOVE'
class Stage(layer_data=<class 'dict'>, name='untitled')[source]

Bases: object

protected_attrs = ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_code', '_execute_in', '_comment', '_start_point', '_enabled', '_instance', '_child_order', '_name', '_source_layer', '_proxy', '_parent_path', '_node_path', '_cached_code']
meta_attrs = ('_comment__nxt', '_type__nxt', '_source__nxt')
property next_node
property prev_node
property filepath
property loaded_files
property reference_layers
property top_layer
get_layer(layer_alias)[source]
new_sublayer(layer_data=None, idx=0)[source]
remove_sublayer(layer)[source]
property total_nodes
property total_roots
static check_for_layer_ref_cycle(parent_layer, check_layer_path)[source]
classmethod load_from_filepath(filepath)[source]
load_from_file(layer_data, parent_layer=None)[source]

Loads from filepath into a layer. Calls itself for sub-layers it finds.

Parameters
  • layer_data – Clean dict of an nxt save file

  • parent_layer – Layer object that this layer will be sub-layered under. If you are creating a top layer it should be None

Returns

Layer object

reference_dependencies(layer)[source]

A layer and every layer it pulls in, as deep as they go.

Reloading one file is rarely the whole story: a layer is what its own file says plus what everything it references says, so this is the set of files that decide what that layer contributes.

A reference that did not resolve has no layer behind it and is left out: there is nothing loaded to reload.

Parameters

layer – layer to start from

Returns

the layer first, then its references depth first

Return type

list

reload_layers(layers, source=None)[source]

Re-read layers, replacing what is in memory with what is saved.

This throws away unsaved work on the layers it is given; that is what reloading is, and asking about it belongs to whoever offers it. Nothing is composited here, because which comp to build and when to build it is the caller’s business, and a reload of several layers wants one comp at the end rather than one each.

A layer that has never been written has nothing to be reloaded from and is skipped, with a complaint.

A file that has come to reference something else since it was opened brings that with it: the layers it now names are loaded, the ones it stopped naming are let go, and the stack is put in the order it gives. The layers it still names are left as they are, whatever state they are in, because nobody asked for those to be read again.

Parameters
  • layers (list) – layers to reload

  • source (dict | None) – real path -> layer data to use instead of reading the file, for putting back what a layer held before

Returns

real path -> the data each layer held before, in the form source takes, so that one reload can undo another. Layers a changed reference took out of the stage are in here too.

Return type

dict

settle_references(layer)[source]

Put the stack under a layer back in step with its references.

Only the difference is touched. A reference that was there before and is there still keeps the layer it had, whatever state that layer is in; a layer nothing references any more would otherwise go on compositing, and a reference nothing loaded would show as missing when the file it names is right there.

Parameters

layer – layer whose references have changed

Returns

({real path: save data} of the layers taken out, the layers brought in, the ones they reference included)

Return type

tuple

load_reference(layer, reference)[source]

Load one of a layer’s references, and what it references.

The work load_from_file does for each reference it finds in a file, for one that turned up after the file was opened. A reference this machine cannot find is left as written, because it is still what the graph asks for and may resolve elsewhere.

Parameters
  • layer – layer holding the reference

  • reference (str) – the reference as stored on that layer

Returns

the layers this brought into the stage

Return type

list

resort_layers()[source]

Stack the layers in the order the references describe.

Layers are stacked depth first from the top: a layer, then what it references, in the order it references them. That order is what decides whose opinion wins, so a file that has come to reference the same layers in a different order has to be able to move them, not only to add and to remove.

get_layer_save_data(layer_idx)[source]
static stash_node(node)[source]

Converts node into dict of {‘attr’: ‘value’}. Builtin object attrs are skipped. Dir is used to get the attr names so both NodeSpec and CompNode objects work. :param node: NodeSpec or CompNode :return: dict

get_stash_data(layer)[source]

Parses every descendant of a layer and gets the stash data for each node. It returns a dict of {‘node/path’: {‘attr’: ‘value’}}. :param layer: SpecLayer or CompLayer :return: dict

static legalize_name(name)[source]

Returns given name without leading numeral, and matching w regex: (a-z, A-Z, 0-9, _) Replaces illegal characters with underscore.

get_unique_node_name(name, layer, parent_path=None, layer_only=False)[source]

Get an unused node name. If given a name preference, the resulting name will increment an integer if needed to create a unique name. If layer only is False and the layer provided is not a comp layer a re-comp will be executed. Because its slow a full re-comp will only be kicked off if the layer arg is a spec layer and the layer only kwarg is false. Bear in mind that calling this function does not reserve that name for future use, so if the name is not used before this function is called again before a name is used, it may produce duplicate results. :param name: The name that is desired. :type name: str :param layer: Layer object used as context for a unique name :type layer: SpecLayer or CompLayer :param parent_path: the given name preference will be tested against this node’s children’s names :type parent_path: str :param layer_only: If false a new comp layer will be created (slow) :type layer_only: bool :return: an unused node name. :rtype: str

get_unique_attr_name(node_path, layer, attr_name=None)[source]

Returns a unique attr name after comparing preferred name to given node’s existing attr names. :param node_path: Node containing attrs to check :type node_path: str :param layer: Layer object :type layer: SpecLayer or CompLayer :param attr_name: Preferences for name of new attr :type attr_name: str | None :return: valid attribute name :rtype: str

add_node_hierarchy(node_hierarchy, parent=None, layer=None, comp_layer=None)[source]
static add_node_to_comp_layer(path, comp_node, comp_layer, ns=None, add_to_child_order=True)[source]

Simply deals with adding a comp node to the comp layer. This method does not deal with adjusting the node’s base classes tuple. Note: this method does not extend the dirty map. :param path: Node path of the node to add :param comp_node: CompNode object :param comp_layer: CompLayer :param ns: Optional namespace list (saves time if provided) :param add_to_child_order: If true the new node’s name will be added to its parent’s child order. :return: CompNode

add_node(name='node', data=None, parent=None, layer=None, fix_names=True, comp_layer=None)[source]

Add a new node to this graph. If nothing is specified, an empty node is created. If no layer index is given the stage top layer is used. The preferred name will be changed if it clashes with an existing used name. Unless fix names is False. :param name: Preferred name for the new node :type name: str :param data: Data for the new node :type data: dict :param parent: String of node path or Node object which will be cast to a node path. :type parent: NodeSpec or string :param layer: Layer object or layer index. :type layer: SpecLayer or int :param fix_names: If True the input name will be made unique :type fix_names: bool :param comp_layer: Layer to do a targeted re-comp on :type comp_layer: CompLayer :returns: NodeSpec

duplicate_node(node=None, layer=None, descendants=True)[source]

Duplicates a given node spec and returns a list of the nodes created. Multiple nodes can be created if the target and comp layer are not the same and descendants is set to True. :param node: NodeSpec object :param layer: Layer object on which the duplicated node should be created :param descendants: If true node descendants will be duplicated on the target layer :return: list of node specs created

delete_node(node, layer, comp_layer=None, remove_layer_data=True, delete_descendants=False, other_removed_nodes=None)[source]

Deletes the given spec node. Returns a bool of success and a list of dirty node paths. If a comp layer is provided deleted nodes are removed from the dirty map. :param node: SpecNode :param layer: SpecLayer :param comp_layer: CompLayer :param remove_layer_data: If true, start, position, and collapse data is removed from the layer(s) :param delete_descendants: If true all descendants are deleted as well :param other_removed_nodes: A list of other node paths that are going to be deleted in the same event loop as the given node. Has no effect if comp_layer is None. :type other_removed_nodes: list (must be list not tuple) :return: (bool, list)

static remove_node_from_comp_layer(path, comp_node, comp_layer, ns=None, rm_from_child_order=True, rm_layer_data=True)[source]
ripple_delete(path, comp_node, target_layer, comp_layer, dirties=(), rm_from_child_order=True)[source]
parent_nodes(nodes, parent_path, layer, check_names=True)[source]

Make the given parent path the parent of all the given nodes. :param nodes: Nodes that will become children of the parent. :type nodes: list | [tree.CompTreeNode] :param parent_path: Node that will be the parent. :type parent_path: comptree.CompTreeNode :param layer: Layer object :type layer: SpecLayer :return: Dictionary of the changed children paths in the format {<old path> : <new path>} :rtype: dict

add_node_attr(node, attr, attr_data, layer, tracked=True)[source]
delete_node_attr(node, attr_name)[source]
rename_node_attr(node, attr_name, new_attr_name, layer)[source]
can_rename_targeted(old_path, new_path, layer, comp_layer)[source]

Whether a rename can be composited in place, without a rebuild.

A rename is a path change, and a path change only alters what the stage composites when another layer is involved, or when something else derives its own path from this one. When none of that is true the comp layer can be updated by removing one node and adding one back, which is what a new node already costs.

Parameters
  • old_path (str) – path the node is moving from

  • new_path (str) – path the node is moving to

  • layer (SpecLayer) – SpecLayer the node is authored on

  • comp_layer (CompLayer) – CompLayer that would be updated

Returns

(can_target, reason), reason explains a False

Return type

tuple

set_node_name(node, name, layer, force=False, comp_layer=None)[source]

Set’s the name of a node. This by definition changes the path to the node. Default behavior is to prevent clashing node names when stage is built to given layer. If force is true, will accept clashing names. TODO is it worthwhile to reverse this api? Where “forcing” is default and one would have to opt-into fixes via fix=True?

Parameters
  • node (NodeSpec) – Node to change name of.

  • name (str) – Name to change to.

  • layer (Layer, optional) – Context to prevent clashing node name, defaults to None.

  • force (bool, optional) – If True, allows clashing node names, defaults to False.

  • comp_layer (CompLayer) – The current CompLayer if you have one

transfer_node_data(target_node, target_layer, source_node, source_layer, include_inherit=False)[source]

Transfers data from one node to another. If the source arg is a node object a source layer must also be provided. :param target_node: NodeSpec :param source_node: CompNode, NodeSpec or node data dict :param source_layer: Layer object :param target_layer: SpecLayer object :param include_inherit: Bool passed to get_node_data :return: None

set_node_data(node, node_data, layer)[source]
node_setattr_data(node, attr, layer, create, comp_layer=None, **values)[source]
set_node_instance_path(node, instance_path, target_layer, comp_layer=None)[source]

Sets the node’s instance path to the given path and sets the source meta attr. :param node: Node object :type node: SpecNode :param instance_path: Node path of instance source :type instance_path: str :param target_layer: Target spec layer :type target_layer: SpecLayer :param comp_layer: Comp layer to do targeted change to :type comp_layer: CompLayer :return: None

static remove_node_instance(node)[source]

Removes the instance path and meta attr from the node. :param node: Node object :type node: SpecNode :return: None

safe_get_node_instance(comp_node, comp_layer, expanded=True)[source]

Safely gets the instance from a node :param comp_node: CompNode object :param comp_layer: CompLayer object :param expanded: If True relative paths will be expanded :return: (CompNode, NodePath)

node_setattr_comment(node, attr_name, layer, comment=None, create=False)[source]
lookup_layer(layer_path)[source]

Finds and returns a layer object from the sub layers list who’s real path matches the layer path arg. :param layer_path: String of real file path to layer’s save file :return: Layer Object

get_node_source_layer(node)[source]

Gets the source layer object for a given node. :param node: NodeSpec or CompNode :return: Layer object or None

static get_uncomped_opinion(node, attr)[source]
static get_node_attr_comment(node_object, attr)[source]
get_node_attr_names(node)[source]
get_node_instanced_attr_names(node, comp_layer)[source]
get_node_attr_value(node, attr_name, layer, resolved=True)[source]

Get the value of the specified attr from the specified node, optionally resolved. :param node: node that contains attr. :type node: nxt_node.Node :param attr_name: name of the attr you would like the value from. :type attr_name: str :param resolved: whether to resolve the value of the attr and return it :type resolved: bool :param layer: Layer object :type layer: Layer or CompLayer :return: value of the requested attribute, if found, else None

static get_node_attr_source(node, attr_name)[source]

Tries to find the node who truly holds the local attribute via recursively looking for the _source__nxt meta attribute. :param node: Node who has access to the attr_name :param attr_name: Name of attribute you want to find the source node for nodes (stored in the ._inherit attr). Usually this is True except in some edgecases like finding the source of _compute. :return: Node object or None if no source found (None is not expected)

get_node_attr_data(node, attr_name, layer, quiet=False)[source]
get_node_data(node, layer, include_inherit=False)[source]
static get_tokens_from(string, token_type=(Token(prefix='file::', detect=None, resolve=None), Token(prefix='path::', detect=None, resolve=None), Token(prefix='_nxtpath', detect=None, resolve=None), Token(prefix='contents::', detect=None, resolve=None), Token(prefix='_nxtcolor', detect=None, resolve=None), Token(prefix='', detect=None, resolve=None)))[source]

Returns a list of token strings the given string contains. TODO Token syntax should be changed to make each token type explicit rather than assuming attr refs for random strings. Tokens can be attribute references that look like ${<NodeName>.<ChildNodeName>.<AttributeName>} at the most verbose, ${<AttributeName>} at a minimum. or tokens can be file tokens that look like ${file::<filepath, relative or absolute>} i.e. ${file::../otherfile.txt} :return: List of tokens as found. :rtype: list

static next_token_partition(text)[source]

partition given text on a token that appears resolvable(contains no sub tokens). Returns in a tuple: (before_token, token_content, after_token), losing the token prefix and suffix in the partition.

Parameters

text (str) – text to find a token from, and partition

Returns

before_token, token_content, after_token

Return type

tuple(str, str, str)

static determine_token_type(token_str)[source]
resolve(node, text, layer, **kwargs)[source]
resolve_attr_ref_token(node, text, layer)[source]

Resolve an attribute ref string into the value contained at that attribute. Attr refs look like: ${/<NodeName>/<ChildNodeName>.<AttributeName>} at the most verbose, ${<AttributeName>} at a minimum.

Parameters
  • node (Node) – node resolve is started from

  • text (str) – text to resolve

  • layer (Layer) – Layer object for context of this resolve

Returns

attribute value given text refers to

Return type

str

resolve_file_path_token(node, text, start_layer)[source]

Uses pathing module to attempt to expand given token_str into a file path. Path is treated as a relative path to start layer’s real file path. :param node: node resolve is started from :type node: Node :param text: text to resolve :type text: str :param start_layer: Layer object who’s file path is used to resolve the given token :type start_layer: Layer :return: file path :rtype: str

resolve_file_token(node, text, start_layer)[source]

Generates a file path using resolution of path token logic, but only returns a path if the file exists.

Parameters
  • node (Node) – node resolve is started from

  • text (str) – text to resolve

  • start_layer – Layer object who’s file path is used to resolve

the given token :type start_layer: Layer :return: file path or empty string :rtype: str

resolve_contents_token(node, text, layer)[source]

Resolves to the text file contents of file path as a string.

Parameters
  • node (Node) – node resolve is started from

  • text (str) – text to resolve

  • layer (Layer) – Layer object for context of this resolve

Returns

string contents of file, if found, otherwise empty string

Return type

str

infer_lower_comp(comp_node, comp_layer, active_layers=None, depth=1, inferred_comp_layer=None)[source]

Infer a new comp node based on the provided args. This method attempts to shift the composition for a node to a different comp depth. The default depth is 1 which means it will infer a new comp node as though the comp’s display layer was 1 layer below the provided comp_layer’s display layer. None is returned if it is not possible to infer a new comp node based on the args provided. If the depth is 0 the comp node is returned unchanged. If the depth is < 0 None is returned as this method infers lower comps (high numbers are lower layers). If no inferred_comp_layer is provided one is created. Its only use is to hold pointers to inferred nodes as they are created, within this method it is treated like a real comp layer, however it is not returned or intended to be returned. :param comp_node: Comp node to be used as the source for the inference. :type comp_node: CompNode :param comp_layer: Comp layer used to inform us what spec layers to consider. :type comp_layer: CompLayer :param active_layers: If no active layers are provided they will be calculated from the comp layer’s range using the depth arg. If the caller of this method already knows the active layers it should pass them here to improve the speed of the inferred comp. :type active_layers: list or None :param depth: number of layers to rollback the comp :type depth: int :param inferred_comp_layer: Temporary comp layer used to hold inferred nodes, if not is provided one will be created and passed to further recursions of this method. :type inferred_comp_layer: CompLayer :return: CompNode or None

static get_specs_at_path(node_path, layers)[source]

Give a node path and a list of layers this method will look up the node path on each layer and return a list of SpecNode objects at that path. If no node is found at the given path for any layer nothing will be added to the list, this may result in the return list length being shorter than the input layer list. :param node_path: string of node path :param layers: list of SpecLayer objects :return: list of SpecNode objects

get_attr_as_real_data_type(node, attr, layer, _globals=None)[source]

Resolves the attribute value specified and evaluates it to the python type it’s syntax indicates, if possible. If node.attr is 5

[${/node.attr}, 123] converts to [5, 123]

Parameters
  • node – Node object

  • attr – String of name of node attr

  • layer – Layer object used to resolve tokens in

get_node_attr_external_sources(node, attr_name, layer)[source]

Get a list of paths to attributes that the given attribute includes in it’s value. This is similar to get_attr_refs, but excludes local attribute paths like ${self.attr_name} and ${attr_name} :param node: Node that contains attr. :type node: comptree.CompTreeNode :param attr_name: Name of attr :type attr_name: str :param layer: root node to find node under :type layer: comptree.CompTreeNode :return: List of paths to attributes that the given attribute includes in it’s value :rtype: list

get_node_code_external_sources(node, layer)[source]
get_node_code_string(node, layer, data_state='raw')[source]

Returns the compute code as a string where each line is on a new line.

Parameters
  • node (comptree.CompTreeNode) – Node to retrieve compute string from.

  • data_state (bool) – Whether to return the code with attr_refs resolved or not.

  • layer (comptree.CompTreeNode) – node to consider root

Returns

The compute string of the given node.

Return type

str

get_node_code(node, layer, custom_code=None)[source]

Converts node’s compute lines into a code object. If an exception is raised while we try to compile the compute code we log it and raise a GraphError. :param node: CompNode :param layer: CompLayer :param custom_code: String of code to used instead of the node’s actual compute. :return: code

get_node_code_lines(node, layer, data_state='raw')[source]

Returns a copy of the list of code lines on the given node. :param node: Node to retrieve compute string from. :type node: Node object :param layer: Layer object :type layer: SpecLayer or CompLayer :param data_state: if DATA_STATE.RESOLVED is received the compute lines will be resolved otherwise we return the raw value. :type data_state: str :return: The compute string of the given node. :rtype: str

set_node_code_lines(node, code_lines, comp_layer)[source]
static clear_code_lines(node)[source]
get_node_local_attrs_data(node)[source]
create_instance_node(source_path, tgt_path, comp_layer, new_tgt_ns=None)[source]

Creates an instance node and adds it to the comp layer. Returns the new instance node if it isn’t an implied node, otherwise returns False. :param source_path: String of path instancing from :param tgt_path: String of path instancing to (could be new node path) :param comp_layer: NxtCompLayer :param new_tgt_ns: Namespace list of tgt_path :return: NxtCompNode or False

static namespace_merger(source_ns, target_ns)[source]

Smartly merges instance namespaces source_ns into target_ns. Example 1:

source = [‘Character’, ‘build’, ‘legs’, ‘left’] target = [‘dummy’, ‘build’, ‘legs’] return == [‘dummy’, ‘build’, ‘legs’, ‘left’]

Example 2:

source = [‘control’, ‘create’] target = [‘leg’, ‘create’, ‘fk’, ‘controls’, ‘upper’] return = [‘leg’, ‘create’, ‘fk’, ‘controls’, ‘upper’, ‘create’]

Parameters

source_ns – List of strings representing an instance source

namespace :param target_ns: List of strings representing an instance target namespace :return: Merged list of string representing an instance child namespace

new_layer(logical_index=<class 'int'>, layer_data=<class 'dict'>)[source]
register_layer(layer, logical_index=None)[source]
build_stage(from_idx=0, node_paths=())[source]
comp_pre_proxies(comp_layer)[source]

Loops the pre comp arcs as defined by CompModes. This method expects that the following comp layer attributes are empty dicts or lists respectively.

‘_nodes_path_as_key’ ‘_nodes_node_as_key’ ‘_node_table’

Parameters

comp_layer – CompLayer

Returns

Int of node count

targeted_comp_pre_proxies(spec_node, new_node_path, comp_layer, target_layer)[source]

Adds a single node to a comp layer, loops the same arcs as pre_proxy_comp, the logic is slightly different as we are doing targeted work on the comp layer. :param spec_node: SpecNode :param new_node_path: String of node path :param comp_layer: CompLayer :param target_layer: SpecLayer :return: CompNode

targeted_comp_proxies(comp_node, node_path, comp_layer)[source]

Given a comp node and a comp layer this function will discover, generate, and add to the comp layer proxy nodes needed by the comp node. The newly generated nodes are not fully composited, this function simply creates the mapping for compping the new nodes. In the end it produces a proxy map used by the post_proxy_comp function. This process is iterative, not recursive. :param comp_node: NxtCompNode :param node_path: String of node path :param comp_layer: CompLayer :return: proxy_map dict

discover_proxies(node_path, comp_node, comp_layer, namespace=None)[source]

Given a node and the current comp layer this function will return a multi list of proxy nodes that need to be created. Its called discover because it must be called many times as we discover nodes that need to be created we don’t yet know if those discoveries themselves need to generate proxies. The return is sorted by namespace depth, shallow to deep. :param node_path: String of node path :param comp_node: NxtCompNode :param comp_layer: CompLayer :return: sorted list of tuples [(target_ns, src_path, tgt_path)]

comp_proxies(comp_layer, node_count)[source]
post_proxy_comp(comp_layer)[source]
targeted_comp_post_proxies(proxy_map, comp_layer=None)[source]

Given a proxy map, this function finishes the compositing of nodes by mutating the base class tuple of each node in the proxy_map. The map is structured like this:

High level terms:

{dirty_node: arc_dict}

Actual data:
{NxtCompNode: {CompArc.PARENT: NxtCompNode or None,

CompArc.INSTANCE: NxtCompNode or None}}

If any given arc key is None or missing in the arc dict no change is made in that loop. :param proxy_map: dict :param comp_layer: CompLayer :return: list of dirty node paths

targeted_uncomp(comp_node, comp_layer, target_layer, arcs=('reference', 'parent', 'instance'))[source]

For each arc in the arcs list remove the base class of the given node that corresponds to the arc name. Each arc name in the arcs list must map to an internal attr name in order to determine which base class to remove. See: CompArc.ATTR_NAMES Resulting in the comp node no longer inheriting from some or any arc(s). :param comp_node: NxtCompNode :param comp_layer: CompLayer :param target_layer: SpectLayer :param arcs: list of CompArc arcs :return: list of dirty node paths

static instance_is_possible(node_path, comp_node, comp_layer, namespace=None)[source]

Simply checks that the given node has a valid shot at having proxies (instances) connected to it.

Returns

Expanded instance path instance is possible, else None

static update_inherited_attrs(comp_node, comp_layer, arcs=('reference', 'parent', 'instance'))[source]
sort_instances(comp_layer, deep_sort=False)[source]

Sorts instances based on the length of their trace list. An instance trace list is every node that is directly or indirectly instanced by the node in question.

Parameters
  • comp_layer – CompLayer

  • deep_sort – If True nodes are double sorted such that it is

guaranteed that the inst target is after its inst source. This is of course slower and not always needed. :return: Sorted list of instance target nodes

static get_instance_sources(node, trace_list, comp_layer)[source]

Fill a list (trace_list) with all of the nodes in the instance source trace of the node on the comp_layer. This function is recursive, the trace_list is passed forward during recursion. :param node: NxtCompNode :param trace_list: list object to be filled :param comp_layer: CompLayer :return: trace_list (same object you provided when calling)

get_instance_targets(inst_source_path, target_list, comp_layer)[source]
static extend_dirty_map(node_path, concern, dirty_map)[source]

Adds node path to concerns map if it is not in the dict and adds the concern to its concern list. :param node_path: String of node path :param concern: Node path of node that node_path should be concerned with :param dirty_map: Dict of concerns {node/path: [other/node/path]} :return: Dict

static remove_from_dirty_map(node_path, dirty_map)[source]
get_layers_with_opinion(node_path, layer_list=None, attr_name=None)[source]

Returns all layers in given layer list(or current stage) that contain the given node_path. Ordered with the top layer at 0.

Parameters
  • node_path (str) – path to find layers for.

  • layer_list – list of layers to check, defaults to None. If not

given, all layers in stage will be checked. :type layer_list: list, optional :param attr_name: Optional: name of specific attr that must have an opinion at the given node path. :type attr_name: str :return: list of layers :rtype: list

static assign_layer_parents(layer_list)[source]

Loops the layers in the given layer list and sets their parent_layer attribute. Then the file path and layer keys are set in the parent layer’s sub_layers dict. :return: None

set_node_child_order(node, child_order, target_layer, comp_layer=None)[source]
propagate_child_order(source_node_path, old_child_order, new_child_order, comp_layer)[source]
static get_node_spec(node_object)[source]
static retarget_spec_node(node, old_path, new_path, layer)[source]

Update one spec node’s bookkeeping after its path changed.

The layer wide refresh() does this for every node it holds, which is wasted work when a single node was renamed.

Parameters
  • node – the spec node that moved

  • old_path (str) – path it was at

  • new_path (str) – path it is at now

  • layer (SpecLayer) – SpecLayer holding it

rekey_comp_node(old_path, new_path, new_name, old_name, comp_layer)[source]

Move one node in the comp layer from one path to another.

A rename is not a delete and a create. The composited node at the old path may be several opinions merged together, an authored node and a proxy among them, and rebuilding it from one spec node would throw the rest away. Nothing about what is merged changes when a node is renamed, only where it is filed, so the node object is kept and re-filed under the new path.

Callers must have established with can_rename_targeted that no other layer and nothing derived is involved.

Parameters
  • old_path (str) – path being vacated

  • new_path (str) – path being moved to

  • new_name (str) – the node’s new name

  • old_name (str) – the name it had, for the parent’s child order

  • comp_layer (CompLayer) – CompLayer to update

static get_node_child_order(node)[source]

Returns a copy of the node’s child order list, thus mutation of the return value will not effect the node object. :param node: Node object :return: Copy of the child order list

get_reverted_child_order(node_path, target_layer, comp_layer)[source]

Merges child order lists from lowest to highest layer, effectively removing any local edits to the child order of the node. :param node: Node object :return: Non-repeating list of strings representing node names.

static get_top_node(node, layer)[source]
get_node_inherited_attr_names(node, comp_layer)[source]
static get_node_comment(node)[source]

Returns the comment of the specified node.

Parameters

node (comptree.CompTreeNode) – Node to get comment from.

Returns

Comment of node.

Return type

str

static set_node_comment(node, comment, layer)[source]

Sets the node comment :param node: SpecNode :param comment: String of node comment. NoneType is allowed :param layer: SpecLayer :return: None

static node_attr_exists(node, attr_name)[source]

Check if node as the given attr. :param node: NxtNode :param attr_name: string of attr name :raises: AttributeError :return: bool

execute(start=None, layer=None, parameters=None)[source]

Executes stage. Optionally at given start. Start can be a start point index, or a node path to start from. If no start is given will attempt to start at first start point. If more than one start node is present a random one will be chosen.

Parameters
  • start (str, optional) – Node path to start from, defaults to None

  • layer (CompLayer) – Layer to execute

  • parameters – Optional dict of {‘/node.attr’: value} to be

applied before execution begins. :type parameters: dict :raises IndexError: If start point index is not found. :raises ValueError: If given start node path cannot be found or if no start is specified and no start nodes can be found. :return: a runtime CompLayer object :rtype: CompLayer

execute_nodes(node_paths, layer, parameters=None)[source]

Execute nodes at given node_paths using given layer. Returns runtime layer object that if passed as layer argument to successive calls will “continue” execution with the same cached values. If parameters are provided they will be applied before the layer node runs, unless the layer provided (in the layer arg) is a runtime layer, in which case they will be applied before the first node is run. :param node_paths: node paths to execute :type node_paths: list :param layer: CompLayer to execute :type layer: CompLayer :param parameters: Optional dict of {‘/node.attr’: value} to be applied before execution begins. :type parameters: dict :raises ValueError: When layer argument has invalid value; GraphError: For any exception raised by a node’s compute. :return: Runtime CompLayer that can be used for continued execution. :rtype: CompLayer

execute_custom_code(code_string, node_path, layer)[source]
static get_node_exec_in(node)[source]
static set_node_exec_in(node, exec_in_path, layer)[source]
static set_node_enabled(spec_node, state, comp_layer)[source]

Sets the enabled state of the given node. And updates the comp to accurately reflect the change without building a new comp layer. :param spec_node: Spec Node object :type spec_node: SpecNode :param state: Enabled state :type state: bool :param comp_layer: Current comp layer, should contain the spec node :type comp_layer: CompLayer :return: List of dirty nodes, aka nodes that were updated.

static get_layer_start_nodes(layer)[source]
set_runtime_parameters(parameters, runtime_layer)[source]
setup_runtime_layer(comp_layer=None, parameters=None)[source]

Modifies given CompLayer for runtime use. If no comp layer is given the runtime layer is generated using all of the stage’s sub_layers. :param comp_layer: CompLayer :param parameters: Optional dict of {‘/node.attr’: value} to be applied before layer node is executed. :return: A runtime CompLayer :rtype: CompLayer

save_to_temp(comp_layer, output_dir=None)[source]

Saves the spec layers, that make up a comp layer, to an output dir. If no output_dir is provided one will be generated using tempfile.mkdtemp. The reference list of the sub-layers are converted to relative paths so they work with all the layers in the same folder. The cwd of each layer is set to the original location of the source layer. :param comp_layer: CompLayer :param output_dir: Path to output directory (defaults to a generated temp dir) :return: Path to temp top layer file

run(runtime_layer, stage=None, rt_node=None, custom_code=None)[source]
clean_globals(code_lines, good_keys, global_dict)[source]

Super hack that tries to remove non global keyword var from the globals :param code_lines: list of strings :param good_keys: list of expected global keys :param global_dict: global dict to clean :return: None

determine_nxt_type(value)[source]
w(string, quote_type=0)[source]

Wraps your string in quotes.

Parameters
  • string (str) – Input string to be wrapped

  • quote_type (int or str) – Int 1: ‘, 2: “, 3: ‘’’, 4: “””

Default is 1, any string can also be provided and we will wrap the string arg in that string ie w(‘Hello World’, ‘$’) returns ‘$Hello World$’ :return: String wrapped in quote marks or custom string

get_historical_opinions(comp_node, attr, comp_layer, include_local=False)[source]

Gets all the historical values for the given node and attr. The local opinion is not included in the return. The MRO is looped so all depths of parents and instances are considered. :param comp_node: NxtCompNode :param attr: String of attr name :param comp_layer: CompLayer :param include_local: if True the local opinion will not be stripped from the start of the return list. :return: [{META_ATTRS.SOURCE: source, META_ATTRS.VALUE: val}]

composite_lists(list_1, list_2)[source]
nxt_uuid(extra=0, f=False)[source]

Creates an ALMOST guaranteed unique id int. :param f: If True the float value will be returned else int will :param extra: An extra int that helps with the uniqueness problem. :return: int