Kv Compiler Source Code Generation

Generates the compiled kv source code.

class kivy.lang.compiler.src_gen.KvCompiler(**kwargs)[source]

Bases: builtins.object

The compiler that generates all the source code.

This class is not part of the public API.

gen_base_rebind_node_local_variable(src_code, subgraph, node, temp_pool, nodes_use_count, nodes_original_ref, nodes_temp_var_name, bind_store_name)[source]

generates the source for getting the value from the bind store on which the rebind function was bound, and saves it as a local variable to be used by children nodes later in the rebind function.

Should only be called on the nodes of a subgraph and not its terminal nodes. Also, should only be called on a node of the subgraph, if this this is at the root of the rebind function. That means we need to lookup the node’s root value from the bind store.

gen_non_bind_node_local_variable(src_code, node, temp_pool, nodes_use_count, nodes_original_ref, nodes_temp_var_name, indent)[source]

Create the local temp variable when rebinding from a node, provided the node is neither a leaf nor a rebindable attribute. E.g. a simple addition operation, or even a attribute, but rebind is False for that attribute.

gen_subgraph_and_children_rebind_callback(src_code, subgraph, bind_store_name)[source]

The subgraph is composed of root nodes and leaf nodes and is of course a directed graph because the containing graph is directed.

All the leaf nodes (called terminal nodes here) are attribute nodes. They are either rebind nodes (to which we bind a rebind function, e.g. for self.widget.x, it is the self node with property widget), or are leaf nodes (to which we bind a rule, e.g. self.widget with x property in the example above).

All the root nodes, called simply nodes, are either attribute nodes that are rebind, or are literals or captured global/local/nonlocal variables. This means, that we can compute the value of any of the terminal nodes using just the nodes of the subgraph. We don’t need anything else!

Task: Given a subgraph, find all the nodes in the larger graph that depend (are children) of the terminal nodes in the subgraph. We then bind a single rebind function, that updates all the nodes in the dependency graph of the subgraph, whenever any of the root nodes of the subgraph is changed.

This means we unbind, and then rebind to any new values discovered.

At the end of the rebind callback, we also executed all (once) the rules that contain any of the nodes encountered along the way. This ensures the rule(s) are properly executed when any of the rebind node change.

Algorithm: The overall algorithm is pretty simple, we start with the subgraph added to a queue. Then we (1) remove the first subgraph from the queue (2) add all the subgraphs that depend on (are children of) this subgraph to the queue, (3) use the subgraph if it has not already been used in a previous iteration of the loop.

The exact details of how each subgraph is “used”, is defined in the function.

gen_subgraph_bindings(src_code, subgraph, temp_pool, nodes_use_count, nodes_original_ref, nodes_temp_var_name, init_bindings, bind_store_name, parent_nodes_of_leaves=None, store_indices_count=None)[source]

Generates the code that binds all the callbacks associated with this subgraph.