pyiv.override
Config overlay for replacing production bindings in tests.
What Problem Does This Solve?
Test suites need the real module graph with a few bindings swapped for doubles.
Rebuilding the whole Config is brittle. override(base).with_(test)
keeps the base registrations and replaces only keys present in the override.
Real-World Use Cases:
Swap
Clock/Filesystemfor synthetic doubles in integration testsReplace a remote client with an in-memory stub while keeping the rest of the graph
Usage Examples:
>>> from pyiv import Config, get_injector
>>> from pyiv.override import override
>>> class Database:
... def name(self) -> str:
... return "prod"
>>> class ProdDatabase(Database):
... def name(self) -> str:
... return "prod"
>>> class FakeDatabase(Database):
... def name(self) -> str:
... return "fake"
>>> class ProdConfig(Config):
... def configure(self):
... self.register(Database, ProdDatabase)
>>> class TestConfig(Config):
... def configure(self):
... self.register(Database, FakeDatabase)
>>> inj = get_injector(override(ProdConfig).with_(TestConfig))
>>> inj.inject(Database).name()
'fake'
- class pyiv.override.OverriddenConfig(bases: Tuple[Type[Config] | Config, ...], overrides: Tuple[Type[Config] | Config, ...])[source]
Bases:
ConfigMerged config: base bindings with override bindings on top.
Why this exists: Tests need the production graph with a few keys swapped. Prefer
override()rather than constructing this directly.See the
OverrideBuilderexample for usage viaoverride(...).with_(...).
- class pyiv.override.OverrideBuilder(bases: Tuple[Type[Config] | Config, ...])[source]
Bases:
objectFluent step after
override()— callwith_()to finish.Why this exists: Splitting
override(base)from.with_(test)keeps the API readable when overlaying several override modules.Example
>>> from pyiv import Config, get_injector >>> class Database: ... def name(self) -> str: ... return "prod" >>> class Fake(Database): ... def name(self) -> str: ... return "fake" >>> class Prod(Config): ... def configure(self): ... self.register(Database, Database) >>> class Test(Config): ... def configure(self): ... self.register(Database, Fake) >>> get_injector(override(Prod).with_(Test)).inject(Database).name() 'fake'