Resolvables#
SolConf Modules#
Solconf modules are regular python modules augmented with extra functionality and stored in solconf package directory hierarchies containing files having '.solconf' extensions. To load a solconf package, use soleil.load_solconf() to load any of the modules in the package root:
module = load_solconf('/path/to/package/root/module.solconf')
Note
You can also create a package without explicitly loading a module by passing the package root only: load_solconf('/path/to/package/root')
By default, calling load_solconf() will first create a package with default name solconf and then create a module within that package using the file’s stem name:
assert module.__name__ == 'solconf.module'
This new module is registered in python’s sys registry and can be subsequently loaded from any other python package using import solconf.module.
Solconf sub-modules
Any sub-directory within the package root can be loaded from within a solconf module using the load() directive:
# /path/to/package/root/module.solconf
submodule = load('.module.submodule')
Todo
Make load_solconf and load the same function, deducing whether a module name or filename is passed in based on the string format. Make it possible to call load from
regular python modules.
Module subscripting
Solconf modules that have a promoted member that supports subscripting (e.g., a dictionary or a list) can be accessed directly with a subscript even if the member has not been resolved.
Resolving SolConf Modules#
Solconf modules can be resolved by specifying a member with an explicit as_type() annotation:
type:as_type = 'numpy.array'
object=[0,1,2,3]
dtype='f'
If no as_type()-annotated member is provided, the module will instead resolve to a dictionary containing all members:
alpha = 1
beta = 2
gamma = 3
If no as_type() member is provided and further a single member is annotated with promoted(), then the module
will resolve to that member :
# package/config.solconf
alpha = 1
beta:promoted = 2
gamma = 3
# main.py
assert load_solconf('package/config.solconf') == 2
Loading a module containing a promoted member will return that member by default:
# package/config.solconf
class Trunk:
...
class NonLinearity:
...
@promoted
class Model:
trunk = Trunk
...
# main.py
assert load(main.solconf) is Model
Classes#
Missing
Python Containers#
Dictionaries, lists, tuples, sets
Warning
Currently, container resolution does not preserve resolved instance uniqueness. The non-container members of resolved containers, however, will preserve uniqueness.
Todo
Builtins (dict, set, tuple, list) do not resolve to unique instances because they do not support adding an extra attribute (i.e., __soleil_resolved__). Fix this by having the pre-processor output a soleil-specific shim that derives from the container and supports adding extra attributes. The resolver for these shims should output the parent container.
Uniqueness of Resolution#
A resolvable object will only resolve once, meaning that all other references to that resolvable object will point to the same resolved object.
For the case of resolvable classes, this can be overriden by deriving from a given resolvable class:
from soleil import resolve
class RslvblA:
type:as_type = lambda **x: x
a = 1
b = 2
assert resolve(RslvblA) is resolve(RslvblA)
class RslvblB(RslvblA): pass
assert resolve(RslvblB) is not resolve(RslvblA)