cillow.Switchable
Create a switch from callable that can be replaced with another callable temporarily. Supports module-level functions, classes, class methods and instance methods.
Features:
- Supports re-entrant context managers (nested switching)
- When exiting a context manager, the callable is restored to the previous state:
- For nested switches, this means restoring to the previous replacement
- Only when exiting the outermost context manager is the original callable restored
- Works with any callable that has a parent object (module, class, or instance)
Examples:
>>> # Example 1: Redirecting sys.stdout.write to a file
>>> import sys
>>> from pathlib import Path
>>>
>>> switchable = Switchable(sys.stdout.write)
>>> with switchable.switch_to(Path('test.txt').open('a').write):
... # Redirect print output to the file 'test.txt'
... print("This will go into the file!")
>>> print("This will print to the console.")
This will print to the console.
>>>
>>> # Example 2: Nested switching with re-entrant context managers
>>> import logging
>>>
>>> def custom_write_1(text):
... logging.error(f"[Logger 1] {text}")
>>>
>>> def custom_write_2(text):
... logging.error(f"[Logger 2] {text}")
>>>
>>> switchable = Switchable(print)
>>> with switchable.switch_to(custom_write_1):
... print("Message 1")
... with switchable.switch_to(custom_write_2):
... print("Message 2")
... print("Message 3")
>>> print("Message 4")
ERROR:root:[Logger 1] Message 1
ERROR:root:[Logger 2] Message 2
ERROR:root:[Logger 1] Message 3
Message 4
>>>
>>> # Example 3: Mocking a callable for testing
>>> import random
>>>
>>> def mock_random_choice(seq):
... return seq[0] # Always return the first element
>>>
>>> switchable = Switchable(random.choice)
>>> with switchable.switch_to(mock_random_choice):
... print(random.choice(list(range(10))))
>>> print(random.choice(list(range(10))))
0
5
Source code in cillow/switchable.py
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 |
|
original
property
¶
Access the original callable.
switch_to
¶
Switch to another target callable temporarily.
Inside the context, you can either use the switchable instance or the original callable to call the target callable.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
target
|
Callable[P_Spec, T_Retval]
|
The new target callable with same signature |
required |
Source code in cillow/switchable.py
switch
context manager¶
Switches from one callable to another temporarily and provides access to the underlying Switchable instance. This provides both a convenient one-off switch and the ability to perform additional switches within the same context if needed.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
__from
|
Callable[P_Spec, T_Retval]
|
The callable to switch from |
required |
__to
|
Callable[P_Spec, T_Retval]
|
The callable to switch to |
required |
Returns:
Type | Description |
---|---|
None
|
The Switchable instance being used for the switch |
Examples:
>>> import random
>>>
>>> # Simple usage
>>> with switch(random.random, lambda: 0.42):
... assert random.random() == 0.42
>>>
>>> # Advanced usage with nested switches
>>> with switch(random.random, lambda: 0.42) as switchable:
... assert random.random() == 0.42
... with switchable.switch_to(lambda: 0.99):
... assert random.random() == 0.99