settingsd 0.8.13 applied the Unix conf.d idea to a Python settings module. Instead of keeping development, staging, and production branches in one file, put the pieces in numbered files and assemble them in a defined order.
The README showed a small installation call in an application’s package:
import settingsd
settings = settingsd.install(__name__)That call discovered fragments, executed them into a shared namespace, and installed the result as the application’s settings object. Existing imports could continue to ask the application for its settings.
Order and provenance
Fragment names supplied a numeric index and a name, as in 01-apple.py. The finder selected matching files; the loader decided what their contents meant. Python fragments executed in the shared namespace, while JSON could contribute values without executing Python statements.
The namespace was an OrderedDict subclass with an intercepted assignment path. When an uppercase setting received a different object, it recorded which fragment and directory made that assignment. The show, source, and trace tools could then explain the assembled settings.
The provenance addresses the configuration problem in Deleting Duplicate Schemas. If two fragments set the same key, the earlier assignment remained in the provenance ledger even though the later value won.
The trace recorded assignments, excluding assignments of the identical object. In-place mutations, such as appending to a list, were not tracked.
A path could change during assembly
Fragments could edit __path__, making additional directories available to the finder. The generator checked the path after each fragment ran and rescanned when it changed. Already executed fragment keys were tracked so a rescan would not execute them again.
The README went further: it showed an early production fragment prepending a directory so a later production file would replace the ordinary file of the same name. The final source does not fully support that promise. It keeps the pending cache and adds a discovered key only when the key is absent. A fragment already queued from the original directory therefore keeps its place even after a higher-priority directory appears.
The rescan added new keys but retained existing pending entries, so the README’s override example did not work as written.
The result behaved like a class body
After loading the parts, settingsd converted the namespace into a new type and instantiated it. This allowed descriptors and special methods to take effect. A fragment could define:
def echo(settings, *args, **kwds):
print((settings, args, kwds))The assembled object could expose that as settings.echo(...), with the settings instance bound as the first argument. The implementation installed a descriptor that looked up the original function in the assembly namespace and bound it to the instance on access.
The Django extras used this construction for lazy setup and fallback to default settings. These were executable configuration files, with the powers and ordering dependencies that implies. settingsd did not sandbox fragments.
Finders and loaders were replaceable through dotted module:attribute references. Directory and ZIP discovery could share the assembly loop; adding a loader did not require replacing the rules for ordering or tracing settings.
The defaults needed somewhere to live
One fix is worth its own short note. Reading an absent mutable default made a copy, but initially did not store it. A fragment could modify the copy and lose the change on its next lookup. The correction materialized SETTINGSD_ defaults in the namespace before returning them.