API Reference
Runtime support library for pyrig.
Contains code that a project needs at runtime, such as CLI invocation.
core
Infrastructure for cross-package dependency and subclass discovery.
constants
Constants used throughout the project.
dependencies
Cross-package subclass discovery driven by the installed package dependency graph.
Supports plugin hierarchies in dependent projects by automatically locating all subclass implementations defined across the installed dependency graph, without requiring explicit registration.
discovery
Subclass and module discovery scoped across installed package dependents.
deps_depending_on_dep(dependency)
cached
Return every installed package that depends on dependency.
The result is cached per unique dependency argument.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dependency
|
ModuleType
|
Package whose dependents should be discovered. |
required |
Returns:
| Type | Description |
|---|---|
ModuleType
|
Tuple of imported module objects for every package that depends on |
...
|
|
tuple[ModuleType, ...]
|
Does not include |
Source code in src/pyrig_runtime/core/dependencies/discovery.py
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | |
discover_equivalent_modules_across_dependents(module)
Yield the equivalent module from every dependent of module's root package.
For each installed package that depends on the root of module, locates
the module at the same sub-path within that dependent and yields it if
it can be imported. The root package itself is excluded from results.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
module
|
ModuleType
|
Module whose root determines which dependents to search and whose sub-path within that root is used to locate the corresponding module in each dependent. |
required |
Yields:
| Type | Description |
|---|---|
ModuleType
|
Successfully imported module objects in dependency order. Dependents |
ModuleType
|
that have no module at the equivalent sub-path are silently skipped. |
Source code in src/pyrig_runtime/core/dependencies/discovery.py
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | |
discover_subclasses_across_dependencies(cls, module)
Yield subclasses of cls found in module and in dependent packages.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cls
|
type[T]
|
Base class whose subclasses should be discovered. |
required |
module
|
ModuleType
|
Module to search first, also used to determine which root package to scan for dependents. |
required |
Yields:
| Type | Description |
|---|---|
type[T]
|
Subclass types of |
type[T]
|
dependent packages in dependency order. |
Source code in src/pyrig_runtime/core/dependencies/discovery.py
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | |
graph
Directed graph of installed Python package dependency relationships.
DependencyGraph
Bases: DiGraph
Directed graph of installed Python package dependencies.
Nodes are package names; an edge A → B means "A depends on B". The graph is built at instantiation by scanning all installed distributions.
When a root package is given, the graph is pruned to retain only
that package and every package that depends on it directly or
transitively.
Source code in src/pyrig_runtime/core/dependencies/graph.py
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | |
__init__(root=None)
Initialize the dependency graph rooted at the given package.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
root
|
str | None
|
Name of the root package. Accepts either the installed name
( |
None
|
Source code in src/pyrig_runtime/core/dependencies/graph.py
24 25 26 27 28 29 30 31 32 33 | |
add_edge(source, target)
Add a directed edge from source to target.
Creates both nodes if they do not already exist.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str
|
Edge origin node. |
required |
target
|
str
|
Edge destination node. |
required |
Source code in src/pyrig_runtime/core/graph.py
74 75 76 77 78 79 80 81 82 83 84 85 86 | |
add_node(node)
Add a node to the graph. No-op if the node already exists.
Source code in src/pyrig_runtime/core/graph.py
88 89 90 91 92 93 94 | |
ancestors(target)
Find all nodes that have a directed path to the target node.
The target itself is excluded from the result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
str
|
Node to find ancestors for. |
required |
Returns:
| Type | Description |
|---|---|
set[str]
|
Set of all nodes with a directed path to the target, excluding the |
set[str]
|
target itself. |
Raises:
| Type | Description |
|---|---|
KeyError
|
If the target node is not in the graph. |
Source code in src/pyrig_runtime/core/graph.py
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | |
build()
Build the graph from installed Python distributions.
Source code in src/pyrig_runtime/core/dependencies/graph.py
35 36 37 38 39 40 41 | |
cached(*args, **kwargs)
cached
classmethod
Return a cached instance, constructing it only on the first call.
Repeated calls with identical arguments return the same instance without rebuilding the graph.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*args
|
Any
|
Positional arguments forwarded to the constructor. |
()
|
**kwargs
|
Any
|
Keyword arguments forwarded to the constructor. |
{}
|
Returns:
| Type | Description |
|---|---|
Self
|
The cached graph instance for the given arguments. |
Source code in src/pyrig_runtime/core/graph.py
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | |
parse_name_and_deps(dist)
Extract the package name and dependencies from a distribution.
Both the package name and every dependency name are normalized to an
importable module name; version specifiers and extras in requirement
strings are stripped. Dots are preserved for namespace packages
(e.g. zope.interface remains zope.interface). The dependency
iterator is exhausted once consumed; it yields nothing when the
distribution declares no dependencies.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dist
|
Distribution
|
Distribution to extract metadata from. |
required |
Returns:
| Type | Description |
|---|---|
str
|
A two-tuple |
Iterator[str]
|
name and |
tuple[str, Iterator[str]]
|
declared dependency. |
Source code in src/pyrig_runtime/core/dependencies/graph.py
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | |
prune(root)
Retain only the given root and its ancestors, removing all other nodes.
Keeps root and all its ancestors (nodes with a directed path to
root). All other nodes and their associated edges are removed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
root
|
str
|
The node to keep, along with all nodes that have a directed path to it. |
required |
Source code in src/pyrig_runtime/core/graph.py
59 60 61 62 63 64 65 66 67 68 69 70 71 72 | |
sorted_ancestors(target)
Return all ancestors of the target node in topological order.
Ancestors are nodes that have a directed path to the target. The result is ordered so that each ancestor appears after all ancestors it has outgoing edges to.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
str
|
Node to find ancestors of. |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
List of ancestor node identifiers in topological order. |
list[str]
|
Returns an empty list if the target has no ancestors. |
Raises:
| Type | Description |
|---|---|
KeyError
|
If the target node is not in the graph. |
RuntimeError
|
If the ancestor subgraph contains a cycle, making topological sorting impossible. |
Source code in src/pyrig_runtime/core/graph.py
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | |
topological_sort_subgraph(nodes)
Sort a subset of nodes in topological order.
If there is an edge from A to B, B appears before A in the result. The ordering is deterministic: when multiple nodes are eligible to be emitted at the same step, they are emitted in ascending lexicographic order.
Only edges whose both endpoints are in nodes are considered; edges
to or from nodes outside the subset are ignored.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nodes
|
set[str]
|
The subset of nodes to sort. |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
List of nodes in topological order, with each node appearing |
list[str]
|
after all nodes it has outgoing edges to. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If the subgraph contains a cycle, making topological sorting impossible. |
Source code in src/pyrig_runtime/core/graph.py
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | |
subclass
Abstract base for cross-package subclass discovery without explicit registration.
DependencySubclass
Abstract base enabling plugin-style subclass discovery across installed packages.
Subclasses declare a discovery scope by overriding the discovery hook, and the base class automatically finds all subclass implementations defined in that scope across every installed package that depends on the root package. The scope may be a single module, to keep discovery narrow, or a whole sub-package, to widen it to a full hierarchy. No explicit registration is required.
Source code in src/pyrig_runtime/core/dependencies/subclass.py
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | |
__str__()
Return the fully qualified class name of this instance.
Source code in src/pyrig_runtime/core/dependencies/subclass.py
74 75 76 | |
concrete_subclasses()
classmethod
Yield all concrete leaf subclasses discovered across dependent packages.
Yields:
| Type | Description |
|---|---|
type[Self]
|
Non-abstract leaf subclass types. |
Source code in src/pyrig_runtime/core/dependencies/subclass.py
142 143 144 145 146 147 148 149 | |
discovery_module()
abstractmethod
classmethod
Return the module or package that scopes discovery of this class.
Every concrete subclass must override this to declare where its implementation classes live. Returning a package widens discovery to that package's whole module hierarchy; returning a plain module keeps discovery narrow to that single module.
The base implementation returns pyrig_runtime.rig.
Returns:
| Type | Description |
|---|---|
ModuleType
|
The module or package that scopes the search for concrete |
ModuleType
|
implementations of this class. |
Source code in src/pyrig_runtime/core/dependencies/subclass.py
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | |
leaf()
classmethod
Return the single leaf subclass found across dependent packages.
If no subclasses are found, the class itself is returned.
Returns:
| Type | Description |
|---|---|
type[Self]
|
The single leaf subclass type, or the class itself if no |
type[Self]
|
subclasses are found. May be abstract. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If more than one leaf subclass is discovered across the dependent packages. |
Source code in src/pyrig_runtime/core/dependencies/subclass.py
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | |
sort_key()
classmethod
Return the sort key used to order this class relative to peer subclasses.
Override to sort by priority, numeric position, or any other criterion. The default returns the class name, giving alphabetical ordering.
Returns:
| Type | Description |
|---|---|
Any
|
A value comparable with |
Any
|
subclasses. |
Source code in src/pyrig_runtime/core/dependencies/subclass.py
96 97 98 99 100 101 102 103 104 105 106 107 | |
subclasses()
classmethod
Yield all subclasses discovered across installed dependent packages.
Only leaf-level subclasses are yielded; any intermediate parent classes that also appear in the result set are omitted.
Yields:
| Type | Description |
|---|---|
type[Self]
|
Leaf subclass types. |
Source code in src/pyrig_runtime/core/dependencies/subclass.py
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | |
subclasses_sorted(subclasses)
classmethod
Sort the given subclasses using each subclass's sort_key().
Does not perform any discovery.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
subclasses
|
Iterable[type[Self]]
|
Subclass types to sort. |
required |
Returns:
| Type | Description |
|---|---|
list[type[Self]]
|
The same subclass types sorted by their |
Source code in src/pyrig_runtime/core/dependencies/subclass.py
168 169 170 171 172 173 174 175 176 177 178 179 180 | |
DependencySubclassMeta
Bases: ABCMeta
Metaclass backing DependencySubclass with the cached I/L properties.
Source code in src/pyrig_runtime/core/dependencies/subclass.py
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | |
I
property
Return a cached instance of the leaf subclass.
The instance is created once per class and reused on every subsequent access.
Returns:
| Type | Description |
|---|---|
C
|
An instance of the leaf subclass, or of the class itself if no |
C
|
subclasses exist. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If more than one leaf subclass is found. |
L
property
Return the cached leaf subclass type.
The result is cached per class and reused on every subsequent access.
Returns:
| Type | Description |
|---|---|
type[C]
|
The single leaf subclass type, or the class itself if no |
type[C]
|
subclasses exist. May be abstract. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If more than one leaf subclass is found. |
__str__()
Return the fully qualified name of this class.
Source code in src/pyrig_runtime/core/dependencies/subclass.py
23 24 25 | |
graph
Abstract directed graph foundation with forward and reverse edge traversal.
DiGraph
Bases: ABC
Abstract directed graph with forward and reverse adjacency tracking.
Subclasses implement build to populate nodes and edges. When a root
node is given, the graph is pruned to contain only that node and every node
that transitively points to it.
Attributes:
| Name | Type | Description |
|---|---|---|
root |
The root node passed at construction, or |
|
nodes |
set[str]
|
Set of all node identifiers currently in the graph. |
edges |
dict[str, set[str]]
|
Forward adjacency map from each node to its outgoing neighbors. |
reverse_edges |
dict[str, set[str]]
|
Reverse adjacency map from each node to its incoming neighbors. |
Source code in src/pyrig_runtime/core/graph.py
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | |
__init__(root=None)
Initialize the directed graph, optionally pruned to the given root.
Source code in src/pyrig_runtime/core/graph.py
41 42 43 44 45 46 47 48 49 | |
add_edge(source, target)
Add a directed edge from source to target.
Creates both nodes if they do not already exist.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str
|
Edge origin node. |
required |
target
|
str
|
Edge destination node. |
required |
Source code in src/pyrig_runtime/core/graph.py
74 75 76 77 78 79 80 81 82 83 84 85 86 | |
add_node(node)
Add a node to the graph. No-op if the node already exists.
Source code in src/pyrig_runtime/core/graph.py
88 89 90 91 92 93 94 | |
ancestors(target)
Find all nodes that have a directed path to the target node.
The target itself is excluded from the result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
str
|
Node to find ancestors for. |
required |
Returns:
| Type | Description |
|---|---|
set[str]
|
Set of all nodes with a directed path to the target, excluding the |
set[str]
|
target itself. |
Raises:
| Type | Description |
|---|---|
KeyError
|
If the target node is not in the graph. |
Source code in src/pyrig_runtime/core/graph.py
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | |
build()
abstractmethod
Populate the graph with nodes and edges.
Called during construction before any pruning occurs. Subclasses must add all nodes and edges that belong to the graph.
Source code in src/pyrig_runtime/core/graph.py
51 52 53 54 55 56 57 | |
cached(*args, **kwargs)
cached
classmethod
Return a cached instance, constructing it only on the first call.
Repeated calls with identical arguments return the same instance without rebuilding the graph.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*args
|
Any
|
Positional arguments forwarded to the constructor. |
()
|
**kwargs
|
Any
|
Keyword arguments forwarded to the constructor. |
{}
|
Returns:
| Type | Description |
|---|---|
Self
|
The cached graph instance for the given arguments. |
Source code in src/pyrig_runtime/core/graph.py
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | |
prune(root)
Retain only the given root and its ancestors, removing all other nodes.
Keeps root and all its ancestors (nodes with a directed path to
root). All other nodes and their associated edges are removed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
root
|
str
|
The node to keep, along with all nodes that have a directed path to it. |
required |
Source code in src/pyrig_runtime/core/graph.py
59 60 61 62 63 64 65 66 67 68 69 70 71 72 | |
sorted_ancestors(target)
Return all ancestors of the target node in topological order.
Ancestors are nodes that have a directed path to the target. The result is ordered so that each ancestor appears after all ancestors it has outgoing edges to.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
str
|
Node to find ancestors of. |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
List of ancestor node identifiers in topological order. |
list[str]
|
Returns an empty list if the target has no ancestors. |
Raises:
| Type | Description |
|---|---|
KeyError
|
If the target node is not in the graph. |
RuntimeError
|
If the ancestor subgraph contains a cycle, making topological sorting impossible. |
Source code in src/pyrig_runtime/core/graph.py
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | |
topological_sort_subgraph(nodes)
Sort a subset of nodes in topological order.
If there is an edge from A to B, B appears before A in the result. The ordering is deterministic: when multiple nodes are eligible to be emitted at the same step, they are emitted in ascending lexicographic order.
Only edges whose both endpoints are in nodes are considered; edges
to or from nodes outside the subset are ignored.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nodes
|
set[str]
|
The subset of nodes to sort. |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
List of nodes in topological order, with each node appearing |
list[str]
|
after all nodes it has outgoing edges to. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If the subgraph contains a cycle, making topological sorting impossible. |
Source code in src/pyrig_runtime/core/graph.py
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | |
introspection
Runtime introspection primitives for classes, callables, modules, and packages.
classes
Utilities for introspecting and filtering Python classes.
discard_abstract_classes(classes)
Filter out abstract classes from a collection.
A class is considered abstract when it has one or more unimplemented abstract methods and therefore cannot be instantiated directly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
classes
|
Iterable[type[T]]
|
Iterable of class types to filter. |
required |
Yields:
| Type | Description |
|---|---|
type[T]
|
Concrete (non-abstract) classes from the input. |
Source code in src/pyrig_runtime/core/introspection/classes.py
50 51 52 53 54 55 56 57 58 59 60 61 62 | |
discard_parent_classes(classes)
Yield only leaf classes, removing any ancestors present in the collection.
A class is kept only when no other class in the collection is a strict subclass of it. The original iterable is not modified.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
classes
|
Iterable[type[T]]
|
Iterable of class types to filter. |
required |
Yields:
| Type | Description |
|---|---|
type[T]
|
Classes that have no subclasses present in the same collection. |
Source code in src/pyrig_runtime/core/introspection/classes.py
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | |
discover_subclasses(cls)
Discover all transitive subclasses of cls currently loaded in memory.
Does not trigger any imports, so only subclasses from already-imported modules are included in the result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cls
|
type[T]
|
Base class to find subclasses of. |
required |
Returns:
| Type | Description |
|---|---|
set[type[T]]
|
Set of all transitive subclass types, excluding |
Source code in src/pyrig_runtime/core/introspection/classes.py
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |
functions
Utilities for Python functions.
module_functions(module)
Yield all functions defined directly in a module.
Excludes objects imported from other modules.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
module
|
ModuleType
|
Module to inspect. |
required |
Yields:
| Type | Description |
|---|---|
Callable[..., Any]
|
Each function defined in |
Source code in src/pyrig_runtime/core/introspection/functions.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | |
inspection
Utilities for inspecting Python objects.
obj_members(obj, predicate=None)
Yield the members of an object as name-value pairs without invoking descriptors.
Members are read statically, so properties with side effects are not
triggered. __annotate__ and __annotate_func__ are always excluded
from the result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
Any
|
Object to inspect (class, module, or any Python object). |
required |
predicate
|
Callable[[Any], bool] | None
|
Optional filter. When given, only members for which it
returns |
None
|
Returns:
| Type | Description |
|---|---|
Iterator[tuple[str, Any]]
|
|
Source code in src/pyrig_runtime/core/introspection/inspection.py
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
unwrap_obj(obj)
Unwrap a Python object to its innermost underlying object.
Recognizes properties, bound methods, classmethods, staticmethods, and
functools.wraps-style decorator chains. All layers are removed, not just
the outermost one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
Any
|
Python object to unwrap. |
required |
Returns:
| Type | Description |
|---|---|
Any
|
The innermost Python object after all wrapping layers have been removed. |
Source code in src/pyrig_runtime/core/introspection/inspection.py
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | |
modules
Utilities for Python modules.
import_modules(module_names)
Import multiple modules by name, lazily.
Modules are imported on demand as the result is iterated, not eagerly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
module_names
|
Iterable[str]
|
Dotted module names to import. |
required |
Yields:
| Type | Description |
|---|---|
ModuleType
|
Each imported module, in the order the names are iterated. |
Source code in src/pyrig_runtime/core/introspection/modules.py
161 162 163 164 165 166 167 168 169 170 171 172 | |
iter_modules(package)
Import and yield each direct child of a package, in discovery order.
Only the immediate children are visited; nested sub-packages are not recursed into.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
package
|
ModuleType
|
Package to iterate. Must have a |
required |
Yields:
| Type | Description |
|---|---|
ModuleType
|
|
bool
|
|
Note
Importing each child is a deliberate side effect — any module-level code in those children executes on demand as the iterator is consumed.
Source code in src/pyrig_runtime/core/introspection/modules.py
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | |
replace_root_module(module, root, default=MISSING)
replace_root_module(
module: ModuleType, root: str
) -> ModuleType
replace_root_module(
module: ModuleType, root: str, default: T
) -> ModuleType | T
Import the equivalent module under a different root package.
Replaces the first dotted segment of module's name with root and
attempts to import the resulting module name. Later segments are left
untouched even if they happen to share the old root's name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
module
|
ModuleType
|
Module whose root segment should be swapped. |
required |
root
|
str
|
Root package name to substitute in. |
required |
default
|
Any
|
Value to return if the import fails. If not provided, the exception propagates unchanged. |
MISSING
|
Returns:
| Type | Description |
|---|---|
ModuleType | Any
|
The imported module at the equivalent sub-path under |
ModuleType | Any
|
|
Example
from some_package.subpackage import module replace_root_module(module, "other_package")
Source code in src/pyrig_runtime/core/introspection/modules.py
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | |
replace_root_module_name(module, root)
Return the equivalent module name under a different root package.
Replaces the first dotted segment of module.__name__ with root. Later
segments are left untouched even if they happen to share the old root's
name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
module
|
ModuleType
|
Module whose root segment should be swapped. |
required |
root
|
str
|
Root package name to substitute in. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The equivalent dotted module name under |
Example
replace_root_module_name(module, "other_package") 'other_package.subpackage.module'
Source code in src/pyrig_runtime/core/introspection/modules.py
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | |
root_module(module)
Import and return the top-level package of the given module.
For a module named "package.subpackage.module", the module corresponding
to "package" is returned. For a top-level module with no dots in its name,
the module for that same name is returned.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
module
|
ModuleType
|
Module to resolve the root package for. |
required |
Returns:
| Type | Description |
|---|---|
ModuleType
|
The module corresponding to the first segment of the dotted name. |
Example
from some_package.subpackage import module root_module(module)
Source code in src/pyrig_runtime/core/introspection/modules.py
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | |
root_module_name(module)
Return the name of the top-level package of the given module.
For a module named "package.subpackage.module", the string "package"
is returned. For a top-level module with no dots in its name, that same
name is returned.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
module
|
ModuleType
|
Module to resolve the root package name for. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The first segment of the dotted module name. |
Example
from some_package.subpackage import module root_module_name(module) 'some_package'
Source code in src/pyrig_runtime/core/introspection/modules.py
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | |
safe_import_module(module_name, package=None, *, default=MISSING, exceptions=(Exception,))
safe_import_module(
module_name: str,
package: str | None = ...,
*,
exceptions: tuple[type[BaseException], ...] = ...,
) -> ModuleType
safe_import_module(
module_name: str,
package: str | None = ...,
*,
default: T,
exceptions: tuple[type[BaseException], ...] = ...,
) -> ModuleType | T
Import a module by name, with an optional fallback on failure.
Any Exception raised during import — not just ImportError — is
handled, so errors at module level (e.g., ValueError raised on
import) are also covered.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
module_name
|
str
|
Dotted module name (e.g., |
required |
package
|
str | None
|
Anchor package for relative imports, forwarded to |
None
|
default
|
Any
|
Value to return if the import raises. If not provided, the exception propagates unchanged. |
MISSING
|
exceptions
|
tuple[type[BaseException], ...]
|
Tuple of exception types to catch. Defaults to |
(Exception,)
|
Returns:
| Type | Description |
|---|---|
ModuleType | Any
|
The imported module, or |
ModuleType | Any
|
|
Source code in src/pyrig_runtime/core/introspection/modules.py
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | |
packages
Subclass discovery scoped by a module name prefix.
discover_subclasses_across_module(cls, module)
Discover all subclasses of cls whose module name starts with module.
When module is a package, its full module hierarchy is imported first, so
subclasses are found in its sub-modules at any nesting depth, including ones
not yet imported when this is called. When module is a plain module, no
import walking happens and only subclasses already defined are considered.
A subclass matches when the dotted name of its defining module starts with
module.__name__. This includes module itself, every sub-module of it,
and any sibling module whose name shares that prefix (for example, scope
pkg.foo also matches pkg.foobar). Choosing a plain module as the scope
therefore narrows discovery to that one file, while choosing a package
widens it to the whole hierarchy.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cls
|
type[T]
|
Base class whose subclasses should be discovered. |
required |
module
|
ModuleType
|
Module or package whose dotted name prefixes the discovery scope. |
required |
Returns:
| Type | Description |
|---|---|
set[type[T]]
|
Set of all subclass types of |
set[type[T]]
|
with |
Source code in src/pyrig_runtime/core/introspection/packages.py
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | |
is_package(module)
Return True if module is a package rather than a plain module.
Source code in src/pyrig_runtime/core/introspection/packages.py
83 84 85 | |
register_package_modules(package)
cached
Ensure all modules in a package hierarchy are imported.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
package
|
ModuleType
|
Root package whose entire module hierarchy will be imported. |
required |
Note
Cached per package — subsequent calls with the same package do nothing.
Source code in src/pyrig_runtime/core/introspection/packages.py
48 49 50 51 52 53 54 55 56 57 58 59 | |
walk_package(package)
Walk all modules in a package hierarchy, recursing into sub-packages.
Importing each visited module is a side effect of iteration. The root
package itself is not yielded.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
package
|
ModuleType
|
Root package to start traversal from. |
required |
Yields:
| Type | Description |
|---|---|
ModuleType
|
|
bool
|
|
Source code in src/pyrig_runtime/core/introspection/packages.py
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | |
strings
String conversion utilities for Python package naming conventions.
dependency_requirement_as_module_name(dep_req)
Extract the importable module name from a dependency requirement string.
Version specifiers, extras notation, and any other non-name characters are stripped. Hyphens in the package name are normalized to underscores.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dep_req
|
str
|
A dependency requirement string (
e.g., |
required |
Returns:
| Type | Description |
|---|---|
str
|
The package name in snake_case (
e.g., |
str
|
). |
Source code in src/pyrig_runtime/core/strings.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | |
dependency_requirement_split_pattern()
Return a compiled regex pattern matching characters outside a package name.
Returns:
| Type | Description |
|---|---|
Pattern[str]
|
A pattern matching any character that is not alphanumeric, an |
Pattern[str]
|
underscore, a hyphen, or a period. |
Source code in src/pyrig_runtime/core/strings.py
41 42 43 44 45 46 47 48 | |
distribution_summary(name)
Return the summary recorded in an installed distribution's metadata.
This function assumes that the package is installed and its metadata has a "Summary" field.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Name of an installed distribution (e.g. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The distribution's summary description. |
Source code in src/pyrig_runtime/core/strings.py
68 69 70 71 72 73 74 75 76 77 78 79 80 | |
fully_qualified_name(obj)
Return the fully qualified name of a callable.
The returned name consists of the callable's module and qualified name,
preserving any enclosing classes or functions.
E.g., for a method foo in class Bar in module baz, the fully qualified
name is "baz.Bar.foo".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
MethodType | FunctionType | type
|
The callable (function, method, or class). |
required |
Returns:
| Type | Description |
|---|---|
str
|
The callable's fully qualified name. |
Source code in src/pyrig_runtime/core/strings.py
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | |
kebab_to_snake_case(value)
Convert a kebab-case string to snake_case, replacing hyphens with underscores.
Source code in src/pyrig_runtime/core/strings.py
8 9 10 | |
snake_to_kebab_case(value)
Convert a snake_case string to kebab-case, replacing underscores with hyphens.
Source code in src/pyrig_runtime/core/strings.py
13 14 15 | |
wrappers
Wrapper utilities.
safe_call(func, *args, default=MISSING, exceptions=(Exception,), **kwargs)
safe_call(
func: Callable[..., T],
*args: Any,
default: D,
exceptions: tuple[type[BaseException], ...] = ...,
**kwargs: Any,
) -> T | D
safe_call(
func: Callable[..., T],
*args: Any,
exceptions: tuple[type[BaseException], ...] = ...,
**kwargs: Any,
) -> T
Call func, returning default on failure or re-raising if none is given.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Callable[..., Any]
|
Callable to invoke. |
required |
*args
|
Any
|
Positional arguments forwarded to |
()
|
default
|
Any
|
Value to return when a caught exception is raised. If not provided, any caught exception propagates unchanged. |
MISSING
|
exceptions
|
tuple[type[BaseException], ...]
|
Exception types to catch. Defaults to |
(Exception,)
|
**kwargs
|
Any
|
Keyword arguments forwarded to |
{}
|
Returns:
| Type | Description |
|---|---|
Any
|
The return value of |
Any
|
exception is caught and |
Source code in src/pyrig_runtime/core/wrappers.py
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | |
rig
Convention-based namespace that dependent projects mirror to extend behavior.
cli
CLI subsystem for pyrig-runtime-based projects.
Dependent projects inherit a runnable CLI entry point and can extend it with project-specific commands alongside shared built-in commands.
cli
Typer CLI application builder with cross-package command discovery.
CLI
Bases: DependencySubclass
Typer application builder for pyrig-runtime-based projects.
Builds and runs the command-line application for any project that depends on
pyrig-runtime. A dependent project may subclass CLI to override any step of
the build to fit its needs.
Source code in src/pyrig_runtime/rig/cli/cli.py
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 | |
__str__()
Return the fully qualified class name of this instance.
Source code in src/pyrig_runtime/core/dependencies/subclass.py
74 75 76 | |
app()
Build a fully configured Typer application.
Source code in src/pyrig_runtime/rig/cli/cli.py
45 46 47 48 | |
base_app()
Create an empty base Typer application.
Returns:
| Type | Description |
|---|---|
Typer
|
A new Typer app configured to show help when invoked without |
Typer
|
arguments. |
Source code in src/pyrig_runtime/rig/cli/cli.py
50 51 52 53 54 55 56 57 | |
base_app_kwargs()
Return keyword arguments for creating the base Typer application.
This base configuration makes sure that calling the CLI without any arguments will display the help message, and that the help text is the same as the description of the invoking project.
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
A dictionary of keyword arguments to pass to |
Source code in src/pyrig_runtime/rig/cli/cli.py
59 60 61 62 63 64 65 66 67 68 69 70 71 72 | |
build_app(app)
Register the callback and all commands onto the given app.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app
|
Typer
|
The Typer app to populate. |
required |
Returns:
| Type | Description |
|---|---|
Typer
|
The same app instance, now fully configured. |
Source code in src/pyrig_runtime/rig/cli/cli.py
74 75 76 77 78 79 80 81 82 83 84 85 86 | |
callback(verbose=typer.Option(0, '--verbose', '-v', count=True, help='Increase verbosity: -v (DEBUG), -vv (modules), -vvv (timestamps)'), quiet=typer.Option(0, '--quiet', '-q', count=True, help='Decrease verbosity: -q (WARNING), -qq (ERROR), -qqq (CRITICAL)'))
Apply the verbosity options for the current invocation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
verbose
|
int
|
Number of times verbosity was increased (e.g. via |
Option(0, '--verbose', '-v', count=True, help='Increase verbosity: -v (DEBUG), -vv (modules), -vvv (timestamps)')
|
quiet
|
int
|
Number of times verbosity was decreased (e.g. via |
Option(0, '--quiet', '-q', count=True, help='Decrease verbosity: -q (WARNING), -qq (ERROR), -qqq (CRITICAL)')
|
Source code in src/pyrig_runtime/rig/cli/cli.py
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | |
concrete_subclasses()
classmethod
Yield all concrete leaf subclasses discovered across dependent packages.
Yields:
| Type | Description |
|---|---|
type[Self]
|
Non-abstract leaf subclass types. |
Source code in src/pyrig_runtime/core/dependencies/subclass.py
142 143 144 145 146 147 148 149 | |
configure_logging(verbose, quiet)
Configure the logging level and format for the current invocation.
Each increment of verbose lowers the log level by one step (toward
DEBUG); each increment of quiet raises it by one step (toward
CRITICAL). The format also expands at higher verbosity, adding module
names at two increments and timestamps at three.
The log level is intentionally unclamped to potentially support custom log levels.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
verbose
|
int
|
Number of times verbosity was increased (e.g. via |
required |
quiet
|
int
|
Number of times verbosity was decreased (e.g. via |
required |
Note
Uses logging.basicConfig with force=True to ensure that the
configuration is applied even if logging has already been configured
by the calling project or other dependencies.
Source code in src/pyrig_runtime/rig/cli/cli.py
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | |
discovery_module()
classmethod
Return the pyrig_runtime.rig.cli.cli module.
Source code in src/pyrig_runtime/rig/cli/cli.py
36 37 38 39 | |
leaf()
classmethod
Return the single leaf subclass found across dependent packages.
If no subclasses are found, the class itself is returned.
Returns:
| Type | Description |
|---|---|
type[Self]
|
The single leaf subclass type, or the class itself if no |
type[Self]
|
subclasses are found. May be abstract. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If more than one leaf subclass is discovered across the dependent packages. |
Source code in src/pyrig_runtime/core/dependencies/subclass.py
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | |
module_subcommand_groups(module)
Return the Typer command groups found in a subcommands module.
Scans the module's namespace for typer.Typer instances. Both natively
defined and imported instances are included. The key for each entry is
the kebab-case form of the attribute name it is bound to.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
module
|
ModuleType
|
The subcommands module to scan. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Typer]
|
Mapping of kebab-case attribute name to the |
dict[str, Typer]
|
bound to it. |
Source code in src/pyrig_runtime/rig/cli/cli.py
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | |
package_name()
Return the snake_case package name of the invoking project.
For example, if the project is invoked as uv run my-project, the
package name is my_project.
Source code in src/pyrig_runtime/rig/cli/cli.py
251 252 253 254 255 256 257 | |
project_name()
Return the stem of sys.argv[0] as the invoking project name.
When a project is invoked through a registered console-script entry point
(e.g. uv run my-project), sys.argv[0] is the path to that script, so
its stem is the project name as it was registered.
Source code in src/pyrig_runtime/rig/cli/cli.py
259 260 261 262 263 264 265 266 | |
register_callback(app)
Attach the verbosity callback to the given app.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app
|
Typer
|
The Typer app to attach the callback to. |
required |
Source code in src/pyrig_runtime/rig/cli/cli.py
88 89 90 91 92 93 94 | |
register_direct_subcommands(app, module)
Register every function defined in a module as a top-level command.
Adds each function found directly in module to app as a flat Typer
command. Imported functions are excluded.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app
|
Typer
|
The Typer app to register the commands onto. |
required |
module
|
ModuleType
|
The subcommands module to scan for command functions. |
required |
Source code in src/pyrig_runtime/rig/cli/cli.py
205 206 207 208 209 210 211 212 213 214 215 216 | |
register_shared_subcommands(app)
Discover and register shared commands from pyrig-runtime and its dependents.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app
|
Typer
|
The Typer app to register the commands onto. |
required |
Note
Commands are registered in dependency order (pyrig-runtime first, then dependent packages in topological order). When two packages define a command with the same name, the last registration takes precedence.
Source code in src/pyrig_runtime/rig/cli/cli.py
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | |
register_subcommand_groups(app, module)
Register every typer.Typer instance in a module as a named command group.
Attaches each typer.Typer found in the module's namespace to app,
using the kebab-case form of the attribute name as the group name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app
|
Typer
|
The Typer app to register the command groups onto. |
required |
module
|
ModuleType
|
The subcommands module to scan for group instances. |
required |
Source code in src/pyrig_runtime/rig/cli/cli.py
218 219 220 221 222 223 224 225 226 227 228 229 | |
register_subcommands(app)
Discover and register project-specific commands for the invoking project.
Any dependent project can define its own CLI commands by adding
functions or typer.Typer groups to <package>.rig.cli.subcommands.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app
|
Typer
|
The Typer app to register the commands onto. |
required |
Note
If the invoking project's subcommands module cannot be imported, registration is silently skipped.
Source code in src/pyrig_runtime/rig/cli/cli.py
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | |
run()
Build and invoke the Typer application.
Source code in src/pyrig_runtime/rig/cli/cli.py
41 42 43 | |
sort_key()
classmethod
Return the sort key used to order this class relative to peer subclasses.
Override to sort by priority, numeric position, or any other criterion. The default returns the class name, giving alphabetical ordering.
Returns:
| Type | Description |
|---|---|
Any
|
A value comparable with |
Any
|
subclasses. |
Source code in src/pyrig_runtime/core/dependencies/subclass.py
96 97 98 99 100 101 102 103 104 105 106 107 | |
subclasses()
classmethod
Yield all subclasses discovered across installed dependent packages.
Only leaf-level subclasses are yielded; any intermediate parent classes that also appear in the result set are omitted.
Yields:
| Type | Description |
|---|---|
type[Self]
|
Leaf subclass types. |
Source code in src/pyrig_runtime/core/dependencies/subclass.py
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | |
subclasses_sorted(subclasses)
classmethod
Sort the given subclasses using each subclass's sort_key().
Does not perform any discovery.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
subclasses
|
Iterable[type[Self]]
|
Subclass types to sort. |
required |
Returns:
| Type | Description |
|---|---|
list[type[Self]]
|
The same subclass types sorted by their |
Source code in src/pyrig_runtime/core/dependencies/subclass.py
168 169 170 171 172 173 174 175 176 177 178 179 180 | |
commands
Implementations of CLI command actions for pyrig-runtime-based projects.
version
Version display command for pyrig-runtime-based project CLIs.
project_version()
Print the name and installed version of the project using this runtime.
The version belongs to the dependent project, not to pyrig-runtime itself. The project must be installed for its version to be available.
Source code in src/pyrig_runtime/rig/cli/commands/version.py
10 11 12 13 14 15 16 17 | |
main
Console-script entry point for pyrig-runtime-based projects.
main()
Run the CLI application.
Source code in src/pyrig_runtime/rig/cli/main.py
6 7 8 | |
shared_subcommands
Shared CLI commands for all dependent packages.
In every installed pyrig-runtime based package functions defined directly in this
module are registered as top-level CLI commands and module-level typer.Typer instances
are registered as command groups, with each group's name derived from the kebab-case
form of the variable name.
version()
Print the name and installed version.
Reports the version of whichever project's CLI entry point was used to invoke this command, not pyrig-runtime's own version. The project must be installed; an editable install is sufficient.
Example
$ uv run myproject version
myproject 0.4.1
Source code in src/pyrig_runtime/rig/cli/shared_subcommands.py
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
subcommands
Project-specific CLI commands.
Functions defined directly in this module are registered as top-level CLI
commands. Module-level typer.Typer instances are registered as command
groups, with each group's name derived from the kebab-case form of the
variable name.