Skip to content

Commit 6924eab

Browse files
committed
Add None module
1 parent 63f5e70 commit 6924eab

File tree

8 files changed

+169
-2
lines changed

8 files changed

+169
-2
lines changed

coverage-badge.svg

Lines changed: 1 addition & 1 deletion
Loading
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
::: synalinks.src.modules.core.none

docs/Synalinks API/Modules API/Core Modules/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
- [Input module](Input module.md)
44
- [Identity module](Identity module.md)
5+
- [None module](None module.md)
56
- [Generator module](Generator module.md)
67
- [Decision module](Decision module.md)
78
- [Action module](Action module.md)

docs/Synalinks API/Modules API/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ if __name__ == "__main__":
4747

4848
- [Input module](Core Modules/Input module.md)
4949
- [Identity module](Core Modules/Identity module.md)
50+
- [None module](Core Modules/None module.md)
5051
- [Generator module](Core Modules/Generator module.md)
5152
- [Decision module](Core Modules/Decision module.md)
5253
- [Action module](Core Modules/Action module.md)

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ nav:
5858
- Synalinks API/Modules API/Core Modules/index.md
5959
- Synalinks API/Modules API/Core Modules/Input module.md
6060
- Synalinks API/Modules API/Core Modules/Identity module.md
61+
- Synalinks API/Modules API/Core Modules/None module.md
6162
- Synalinks API/Modules API/Core Modules/Generator module.md
6263
- Synalinks API/Modules API/Core Modules/Decision module.md
6364
- Synalinks API/Modules API/Core Modules/Action module.md

synalinks/src/modules/core/none.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# License Apache 2.0: (c) 2025 Yoan Sallami (Synalinks Team)
2+
3+
from synalinks.src import tree
4+
from synalinks.src.api_export import synalinks_export
5+
from synalinks.src.backend import JsonDataModel
6+
from synalinks.src.backend import SymbolicDataModel
7+
from synalinks.src.modules.module import Module
8+
9+
10+
@synalinks_export(["synalinks.modules.NoneModule", "synalinks.NoneModule"])
11+
class NoneModule(Module):
12+
"""None module.
13+
14+
This module should be used as a placeholder when no operation is to be
15+
performed and the output should be None.
16+
17+
This module is useful to implement stop conditions when combined with a conditional
18+
branch or as placeholder (like the Identity) before implementing guards that leverage
19+
the xor operation.
20+
21+
Args:
22+
**kwargs (keyword arguments): The default module's arguments
23+
"""
24+
25+
def __init__(self, **kwargs):
26+
super().__init__(**kwargs)
27+
self.built = True
28+
29+
async def call(self, inputs):
30+
if isinstance(inputs, (JsonDataModel, SymbolicDataModel)):
31+
return None
32+
return tree.map_structure(
33+
lambda x: None,
34+
inputs,
35+
)
36+
37+
async def compute_output_spec(self, inputs):
38+
if isinstance(inputs, (JsonDataModel, SymbolicDataModel)):
39+
return inputs.clone()
40+
return tree.map_structure(
41+
lambda x: x.clone(),
42+
inputs,
43+
)
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# License Apache 2.0: (c) 2025 Yoan Sallami (Synalinks Team)
2+
3+
from synalinks.src import testing
4+
from synalinks.src.backend import DataModel
5+
from synalinks.src.modules.core.none import NoneModule
6+
from synalinks.src.modules.core.input_module import Input
7+
from synalinks.src.programs.program import Program
8+
9+
10+
class NoneModuleTest(testing.TestCase):
11+
async def test_single_inputs(self):
12+
class Query(DataModel):
13+
query: str
14+
15+
inputs = Input(data_model=Query)
16+
outputs = await NoneModule()(inputs)
17+
18+
program = Program(
19+
inputs=inputs,
20+
outputs=outputs,
21+
)
22+
23+
result = await program(Query(query="a"))
24+
25+
self.assertEqual(result, None)
26+
27+
async def test_tuple_inputs(self):
28+
class Query(DataModel):
29+
query: str
30+
31+
inputs = (
32+
Input(data_model=Query),
33+
Input(data_model=Query),
34+
Input(data_model=Query),
35+
)
36+
outputs = await NoneModule()(inputs)
37+
38+
program = Program(
39+
inputs=inputs,
40+
outputs=outputs,
41+
)
42+
43+
result = await program(
44+
(
45+
Query(query="a"),
46+
Query(query="b"),
47+
Query(query="c"),
48+
)
49+
)
50+
51+
self.assertEqual(result[0], None)
52+
self.assertEqual(result[1], None)
53+
self.assertEqual(result[2], None)
54+
55+
async def test_list_inputs(self):
56+
class Query(DataModel):
57+
query: str
58+
59+
inputs = [
60+
Input(data_model=Query),
61+
Input(data_model=Query),
62+
Input(data_model=Query),
63+
]
64+
outputs = await NoneModule()(inputs)
65+
66+
program = Program(
67+
inputs=inputs,
68+
outputs=outputs,
69+
)
70+
71+
result = await program(
72+
[
73+
Query(query="a"),
74+
Query(query="b"),
75+
Query(query="c"),
76+
]
77+
)
78+
79+
self.assertEqual(result[0], None)
80+
self.assertEqual(result[1], None)
81+
self.assertEqual(result[2], None)
82+
83+
async def test_dict_inputs(self):
84+
class Query(DataModel):
85+
query: str
86+
87+
inputs = {
88+
"a": Input(data_model=Query),
89+
"b": Input(data_model=Query),
90+
"c": Input(data_model=Query),
91+
}
92+
outputs = await NoneModule()(inputs)
93+
94+
program = Program(
95+
inputs=inputs,
96+
outputs=outputs,
97+
)
98+
99+
result = await program(
100+
{
101+
"a": Query(query="a"),
102+
"b": Query(query="b"),
103+
"c": Query(query="c"),
104+
}
105+
)
106+
107+
expected_json_a = {
108+
"query": "a",
109+
}
110+
expected_json_b = {
111+
"query": "b",
112+
}
113+
expected_json_c = {
114+
"query": "c",
115+
}
116+
117+
self.assertEqual(result["a"], None)
118+
self.assertEqual(result["b"], None)
119+
self.assertEqual(result["c"], None)

synalinks/src/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from synalinks.src.api_export import synalinks_export
44

55
# Unique source of truth for the version number.
6-
__version__ = "0.2.021"
6+
__version__ = "0.2.022"
77

88

99
@synalinks_export("synalinks.version")

0 commit comments

Comments
 (0)