bigraph-schema 0.0.45__tar.gz → 0.0.46__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of bigraph-schema might be problematic. Click here for more details.
- {bigraph-schema-0.0.45/bigraph_schema.egg-info → bigraph-schema-0.0.46}/PKG-INFO +5 -1
- {bigraph-schema-0.0.45 → bigraph-schema-0.0.46}/bigraph_schema/registry.py +6 -2
- {bigraph-schema-0.0.45 → bigraph-schema-0.0.46}/bigraph_schema/type_system.py +225 -111
- {bigraph-schema-0.0.45 → bigraph-schema-0.0.46/bigraph_schema.egg-info}/PKG-INFO +5 -1
- {bigraph-schema-0.0.45 → bigraph-schema-0.0.46}/bigraph_schema.egg-info/SOURCES.txt +1 -15
- {bigraph-schema-0.0.45 → bigraph-schema-0.0.46}/setup.py +1 -1
- bigraph-schema-0.0.45/.github/workflows/notebook_to_html.yml +0 -48
- bigraph-schema-0.0.45/.github/workflows/pytest.yml +0 -29
- bigraph-schema-0.0.45/.gitignore +0 -14
- bigraph-schema-0.0.45/CLA.md +0 -113
- bigraph-schema-0.0.45/CODE_OF_CONDUCT.md +0 -137
- bigraph-schema-0.0.45/CONTRIBUTING.md +0 -44
- bigraph-schema-0.0.45/notebooks/core.ipynb +0 -1683
- bigraph-schema-0.0.45/notebooks/demo.ipynb +0 -1487
- bigraph-schema-0.0.45/notebooks/images/place-link.png +0 -0
- bigraph-schema-0.0.45/notebooks/images/reaction-after.png +0 -0
- bigraph-schema-0.0.45/notebooks/images/reaction-before.png +0 -0
- bigraph-schema-0.0.45/notebooks/images/redex-reactum.png +0 -0
- bigraph-schema-0.0.45/pytest.ini +0 -4
- bigraph-schema-0.0.45/release.sh +0 -43
- {bigraph-schema-0.0.45 → bigraph-schema-0.0.46}/AUTHORS.md +0 -0
- {bigraph-schema-0.0.45 → bigraph-schema-0.0.46}/LICENSE +0 -0
- {bigraph-schema-0.0.45 → bigraph-schema-0.0.46}/README.md +0 -0
- {bigraph-schema-0.0.45 → bigraph-schema-0.0.46}/bigraph_schema/__init__.py +0 -0
- {bigraph-schema-0.0.45 → bigraph-schema-0.0.46}/bigraph_schema/data.py +0 -0
- {bigraph-schema-0.0.45 → bigraph-schema-0.0.46}/bigraph_schema/parse.py +0 -0
- {bigraph-schema-0.0.45 → bigraph-schema-0.0.46}/bigraph_schema/protocols.py +0 -0
- {bigraph-schema-0.0.45 → bigraph-schema-0.0.46}/bigraph_schema/react.py +0 -0
- {bigraph-schema-0.0.45 → bigraph-schema-0.0.46}/bigraph_schema/units.py +0 -0
- {bigraph-schema-0.0.45 → bigraph-schema-0.0.46}/bigraph_schema.egg-info/dependency_links.txt +0 -0
- {bigraph-schema-0.0.45 → bigraph-schema-0.0.46}/bigraph_schema.egg-info/requires.txt +0 -0
- {bigraph-schema-0.0.45 → bigraph-schema-0.0.46}/bigraph_schema.egg-info/top_level.txt +0 -0
- {bigraph-schema-0.0.45 → bigraph-schema-0.0.46}/setup.cfg +0 -0
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: bigraph-schema
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.46
|
|
4
4
|
Summary: A serializable type schema for compositional systems biology
|
|
5
5
|
Home-page: https://github.com/vivarium-collective/bigraph-schema
|
|
6
6
|
Author: Eran Agmon, Ryan Spangler
|
|
7
7
|
Author-email: agmon.eran@gmail.com, ryan.spangler@gmail.com
|
|
8
|
+
License: UNKNOWN
|
|
9
|
+
Platform: UNKNOWN
|
|
8
10
|
Classifier: Development Status :: 3 - Alpha
|
|
9
11
|
Classifier: Intended Audience :: Developers
|
|
10
12
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -52,3 +54,5 @@ This resource will guide you through the core concepts and methods, helping you
|
|
|
52
54
|
## License
|
|
53
55
|
|
|
54
56
|
Bigraph-schema is open-source software released under the [Apache 2 License](https://github.com/vivarium-collective/bigraph-schema/blob/main/LICENSE).
|
|
57
|
+
|
|
58
|
+
|
|
@@ -43,6 +43,10 @@ optional_schema_keys = set([
|
|
|
43
43
|
type_schema_keys = required_schema_keys | optional_schema_keys
|
|
44
44
|
|
|
45
45
|
|
|
46
|
+
def deep_merge_copy(dct, merge_dct):
|
|
47
|
+
return deep_merge(copy.deepcopy(dct), merge_dct)
|
|
48
|
+
|
|
49
|
+
|
|
46
50
|
def deep_merge(dct, merge_dct):
|
|
47
51
|
"""Recursive dict merge
|
|
48
52
|
|
|
@@ -347,9 +351,9 @@ class Registry(object):
|
|
|
347
351
|
return function_name, module_key
|
|
348
352
|
|
|
349
353
|
|
|
350
|
-
def register_multiple(self, schemas,
|
|
354
|
+
def register_multiple(self, schemas, strict=False):
|
|
351
355
|
for key, schema in schemas.items():
|
|
352
|
-
self.register(key, schema,
|
|
356
|
+
self.register(key, schema, strict=strict)
|
|
353
357
|
|
|
354
358
|
def find(self, key):
|
|
355
359
|
return self.registry.get(key)
|
|
@@ -220,6 +220,41 @@ def visit_method(schema, state, method, values, core):
|
|
|
220
220
|
return result
|
|
221
221
|
|
|
222
222
|
|
|
223
|
+
def generate_quote(core, schema, state, top_schema=None, top_state=None, path=None):
|
|
224
|
+
return schema, state, top_schema, top_state
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def sort_quote(core, schema, state):
|
|
228
|
+
return schema, state
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def sort_any(core, schema, state):
|
|
232
|
+
if not isinstance(schema, dict):
|
|
233
|
+
schema = core.find(schema)
|
|
234
|
+
if not isinstance(state, dict):
|
|
235
|
+
return schema, state
|
|
236
|
+
|
|
237
|
+
merged_schema = {}
|
|
238
|
+
merged_state = {}
|
|
239
|
+
|
|
240
|
+
for key in union_keys(schema, state):
|
|
241
|
+
if is_schema_key(key):
|
|
242
|
+
if key in state:
|
|
243
|
+
merged_schema[key] = core.merge_schemas(
|
|
244
|
+
schema.get(key, {}),
|
|
245
|
+
state[key])
|
|
246
|
+
else:
|
|
247
|
+
merged_schema[key] = schema[key]
|
|
248
|
+
else:
|
|
249
|
+
subschema, merged_state[key] = core.sort(
|
|
250
|
+
schema.get(key, {}),
|
|
251
|
+
state.get(key, None))
|
|
252
|
+
if subschema:
|
|
253
|
+
merged_schema[key] = subschema
|
|
254
|
+
|
|
255
|
+
return merged_schema, merged_state
|
|
256
|
+
|
|
257
|
+
|
|
223
258
|
def fold_any(schema, state, method, values, core):
|
|
224
259
|
if isinstance(state, dict):
|
|
225
260
|
result = {}
|
|
@@ -613,46 +648,14 @@ def is_empty(value):
|
|
|
613
648
|
return False
|
|
614
649
|
|
|
615
650
|
|
|
616
|
-
def merge_any(schema, current_state, new_state, core):
|
|
617
|
-
# overwrites in place!
|
|
618
|
-
# TODO: this operation could update the schema (by merging a key not
|
|
619
|
-
# already in the schema) but that is not represented currently....
|
|
620
|
-
merge_state = None
|
|
621
|
-
|
|
622
|
-
if is_empty(current_state):
|
|
623
|
-
merge_state = new_state
|
|
624
|
-
|
|
625
|
-
elif is_empty(new_state):
|
|
626
|
-
merge_state = current_state
|
|
627
|
-
|
|
628
|
-
elif isinstance(new_state, dict):
|
|
629
|
-
if isinstance(current_state, dict):
|
|
630
|
-
for key, value in new_state.items():
|
|
631
|
-
if is_schema_key(key):
|
|
632
|
-
current_state[key] = value
|
|
633
|
-
else:
|
|
634
|
-
current_state[key] = core.merge(
|
|
635
|
-
schema.get(key),
|
|
636
|
-
current_state.get(key),
|
|
637
|
-
value)
|
|
638
|
-
merge_state = current_state
|
|
639
|
-
else:
|
|
640
|
-
merge_state = new_state
|
|
641
|
-
else:
|
|
642
|
-
merge_state = new_state
|
|
643
|
-
|
|
644
|
-
return merge_state
|
|
645
|
-
|
|
646
|
-
# return core.deserialize(
|
|
647
|
-
# schema,
|
|
648
|
-
# merge_state)
|
|
649
|
-
|
|
650
|
-
|
|
651
651
|
def bind_any(schema, state, key, subschema, substate, core):
|
|
652
652
|
result_schema = core.resolve_schemas(
|
|
653
653
|
schema,
|
|
654
654
|
{key: subschema})
|
|
655
655
|
|
|
656
|
+
if state is None:
|
|
657
|
+
state = {}
|
|
658
|
+
|
|
656
659
|
state[key] = substate
|
|
657
660
|
|
|
658
661
|
return result_schema, state
|
|
@@ -877,7 +880,8 @@ def union_keys(schema, state):
|
|
|
877
880
|
|
|
878
881
|
def generate_any(core, schema, state, top_schema=None, top_state=None, path=None):
|
|
879
882
|
schema = schema or {}
|
|
880
|
-
|
|
883
|
+
if is_empty(state):
|
|
884
|
+
state = core.default(schema)
|
|
881
885
|
top_schema = top_schema or schema
|
|
882
886
|
top_state = top_state or state
|
|
883
887
|
path = path or []
|
|
@@ -925,7 +929,10 @@ def generate_any(core, schema, state, top_schema=None, top_state=None, path=None
|
|
|
925
929
|
generated_schema,
|
|
926
930
|
generated_state)
|
|
927
931
|
else:
|
|
928
|
-
|
|
932
|
+
top_state = core.merge_recur(
|
|
933
|
+
top_schema,
|
|
934
|
+
top_state,
|
|
935
|
+
generated_state)
|
|
929
936
|
|
|
930
937
|
else:
|
|
931
938
|
generated_schema, generated_state = schema, state
|
|
@@ -945,16 +952,21 @@ registry_types = {
|
|
|
945
952
|
'_slice': slice_any,
|
|
946
953
|
'_apply': apply_any,
|
|
947
954
|
'_check': check_any,
|
|
955
|
+
'_sort': sort_any,
|
|
948
956
|
'_generate': generate_any,
|
|
949
957
|
'_serialize': serialize_any,
|
|
950
958
|
'_deserialize': deserialize_any,
|
|
951
959
|
'_dataclass': dataclass_any,
|
|
952
960
|
'_resolve': resolve_any,
|
|
953
961
|
'_fold': fold_any,
|
|
954
|
-
'_merge': merge_any,
|
|
955
962
|
'_bind': bind_any,
|
|
956
963
|
'_divide': divide_any},
|
|
957
964
|
|
|
965
|
+
'quote': {
|
|
966
|
+
'_type': 'quote',
|
|
967
|
+
'_generate': generate_quote,
|
|
968
|
+
'_sort': sort_quote},
|
|
969
|
+
|
|
958
970
|
'tuple': {
|
|
959
971
|
'_type': 'tuple',
|
|
960
972
|
'_default': default_tuple,
|
|
@@ -1198,32 +1210,18 @@ class TypeSystem(Registry):
|
|
|
1198
1210
|
return merged
|
|
1199
1211
|
|
|
1200
1212
|
|
|
1201
|
-
def
|
|
1202
|
-
|
|
1203
|
-
schema = self.find(schema)
|
|
1204
|
-
if not isinstance(state, dict):
|
|
1205
|
-
return schema, state
|
|
1206
|
-
|
|
1207
|
-
merged_schema = {}
|
|
1208
|
-
merged_state = {}
|
|
1209
|
-
|
|
1210
|
-
for key in union_keys(schema, state):
|
|
1211
|
-
if is_schema_key(key):
|
|
1212
|
-
if key in state:
|
|
1213
|
-
merged_schema[key] = self.merge_schemas(
|
|
1214
|
-
schema.get(key, {}),
|
|
1215
|
-
state[key])
|
|
1216
|
-
else:
|
|
1217
|
-
merged_schema[key] = schema[key]
|
|
1218
|
-
else:
|
|
1219
|
-
subschema, merged_state[key] = self.merge_schema_keys(
|
|
1220
|
-
schema.get(key, {}),
|
|
1221
|
-
state.get(key, None))
|
|
1213
|
+
def sort(self, schema, state):
|
|
1214
|
+
schema = self.access(schema)
|
|
1222
1215
|
|
|
1223
|
-
|
|
1224
|
-
|
|
1216
|
+
sort_function = self.choose_method(
|
|
1217
|
+
schema,
|
|
1218
|
+
state,
|
|
1219
|
+
'sort')
|
|
1225
1220
|
|
|
1226
|
-
return
|
|
1221
|
+
return sort_function(
|
|
1222
|
+
self,
|
|
1223
|
+
schema,
|
|
1224
|
+
state)
|
|
1227
1225
|
|
|
1228
1226
|
|
|
1229
1227
|
def exists(self, type_key):
|
|
@@ -1279,7 +1277,7 @@ class TypeSystem(Registry):
|
|
|
1279
1277
|
found = {
|
|
1280
1278
|
key: self.access(
|
|
1281
1279
|
branch,
|
|
1282
|
-
strict=strict)
|
|
1280
|
+
strict=strict) if key != '_default' else branch
|
|
1283
1281
|
for key, branch in schema.items()}
|
|
1284
1282
|
|
|
1285
1283
|
elif isinstance(schema, int):
|
|
@@ -1573,7 +1571,6 @@ class TypeSystem(Registry):
|
|
|
1573
1571
|
pipes = '|'.join(colons)
|
|
1574
1572
|
return f'({pipes})'
|
|
1575
1573
|
else:
|
|
1576
|
-
print(f'no representation for {schema}')
|
|
1577
1574
|
return str(schema)
|
|
1578
1575
|
|
|
1579
1576
|
|
|
@@ -1886,9 +1883,14 @@ class TypeSystem(Registry):
|
|
|
1886
1883
|
for parameter in update['_type_parameters']:
|
|
1887
1884
|
parameter_key = f'_{parameter}'
|
|
1888
1885
|
if parameter in current['_type_parameters']:
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1886
|
+
if parameter_key in current:
|
|
1887
|
+
outcome[parameter_key] = self.resolve_schemas(
|
|
1888
|
+
current[parameter_key],
|
|
1889
|
+
update[parameter_key])
|
|
1890
|
+
elif parameter_key in update:
|
|
1891
|
+
outcome[parameter_key] = update[parameter_key]
|
|
1892
|
+
# else:
|
|
1893
|
+
# outcome[parameter_key] = {}
|
|
1892
1894
|
else:
|
|
1893
1895
|
outcome[parameter_key] = update[parameter_key]
|
|
1894
1896
|
elif key not in outcome or type_parameter_key(current, key):
|
|
@@ -2134,19 +2136,45 @@ class TypeSystem(Registry):
|
|
|
2134
2136
|
return self.set_update(schema, state, update)
|
|
2135
2137
|
|
|
2136
2138
|
|
|
2137
|
-
def
|
|
2138
|
-
|
|
2139
|
+
def merge_recur(self, schema, state, update):
|
|
2140
|
+
if is_empty(schema):
|
|
2141
|
+
merge_state = update
|
|
2139
2142
|
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2143
|
+
elif is_empty(update):
|
|
2144
|
+
merge_state = state
|
|
2145
|
+
|
|
2146
|
+
elif isinstance(update, dict):
|
|
2147
|
+
if isinstance(state, dict):
|
|
2148
|
+
for key, value in update.items():
|
|
2149
|
+
if is_schema_key(key):
|
|
2150
|
+
state[key] = value
|
|
2151
|
+
else:
|
|
2152
|
+
if isinstance(schema, str):
|
|
2153
|
+
schema = self.access(schema)
|
|
2154
|
+
|
|
2155
|
+
state[key] = self.merge_recur(
|
|
2156
|
+
schema.get(key),
|
|
2157
|
+
state.get(key),
|
|
2158
|
+
value)
|
|
2159
|
+
merge_state = state
|
|
2160
|
+
else:
|
|
2161
|
+
merge_state = update
|
|
2162
|
+
else:
|
|
2163
|
+
merge_state = update
|
|
2164
|
+
|
|
2165
|
+
return merge_state
|
|
2144
2166
|
|
|
2145
|
-
|
|
2167
|
+
|
|
2168
|
+
def merge(self, schema, state, path, update_schema, update_state, defer=False):
|
|
2169
|
+
top_schema, top_state = self.set_slice(
|
|
2146
2170
|
schema,
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2171
|
+
state,
|
|
2172
|
+
path,
|
|
2173
|
+
update_schema,
|
|
2174
|
+
update_state,
|
|
2175
|
+
defer)
|
|
2176
|
+
|
|
2177
|
+
return self.generate(top_schema, top_state)
|
|
2150
2178
|
|
|
2151
2179
|
|
|
2152
2180
|
def bind(self, schema, state, key, target_schema, target_state):
|
|
@@ -2167,12 +2195,25 @@ class TypeSystem(Registry):
|
|
|
2167
2195
|
|
|
2168
2196
|
|
|
2169
2197
|
def set_slice(self, schema, state, path, target_schema, target_state, defer=False):
|
|
2198
|
+
|
|
2199
|
+
'''
|
|
2200
|
+
Makes a local modification to the schema/state at the path, and
|
|
2201
|
+
returns the top_schema and top_state
|
|
2202
|
+
'''
|
|
2203
|
+
|
|
2170
2204
|
if len(path) == 0:
|
|
2171
|
-
|
|
2205
|
+
# deal with paths of length 0
|
|
2206
|
+
# this should never happen?
|
|
2207
|
+
merged_schema = self.resolve_schemas(
|
|
2172
2208
|
schema,
|
|
2209
|
+
target_schema)
|
|
2210
|
+
|
|
2211
|
+
merged_state = deep_merge(
|
|
2173
2212
|
state,
|
|
2174
2213
|
target_state)
|
|
2175
2214
|
|
|
2215
|
+
return merged_schema, merged_state
|
|
2216
|
+
|
|
2176
2217
|
elif len(path) == 1:
|
|
2177
2218
|
key = path[0]
|
|
2178
2219
|
destination_schema, destination_state = self.slice(
|
|
@@ -2185,13 +2226,13 @@ class TypeSystem(Registry):
|
|
|
2185
2226
|
target_schema)
|
|
2186
2227
|
|
|
2187
2228
|
if not defer:
|
|
2188
|
-
result_state = self.
|
|
2229
|
+
result_state = self.merge_recur(
|
|
2189
2230
|
final_schema,
|
|
2190
2231
|
destination_state,
|
|
2191
2232
|
target_state)
|
|
2192
2233
|
|
|
2193
2234
|
else:
|
|
2194
|
-
result_state = self.
|
|
2235
|
+
result_state = self.merge_recur(
|
|
2195
2236
|
final_schema,
|
|
2196
2237
|
target_state,
|
|
2197
2238
|
destination_state)
|
|
@@ -2566,6 +2607,9 @@ class TypeSystem(Registry):
|
|
|
2566
2607
|
for parameter in current['_type_parameters']:
|
|
2567
2608
|
parameter_key = f'_{parameter}'
|
|
2568
2609
|
if parameter_key in question:
|
|
2610
|
+
if parameter_key not in current:
|
|
2611
|
+
return False
|
|
2612
|
+
|
|
2569
2613
|
if not self.equivalent(current[parameter_key], question[parameter_key]):
|
|
2570
2614
|
return False
|
|
2571
2615
|
else:
|
|
@@ -2719,7 +2763,7 @@ class TypeSystem(Registry):
|
|
|
2719
2763
|
top_schema,
|
|
2720
2764
|
compound_schema)
|
|
2721
2765
|
|
|
2722
|
-
top_state = self.
|
|
2766
|
+
top_state = self.merge_recur(
|
|
2723
2767
|
top_schema,
|
|
2724
2768
|
compound_state,
|
|
2725
2769
|
top_state)
|
|
@@ -2874,32 +2918,32 @@ class TypeSystem(Registry):
|
|
|
2874
2918
|
|
|
2875
2919
|
|
|
2876
2920
|
def generate_recur(self, schema, state, top_schema=None, top_state=None, path=None):
|
|
2877
|
-
merged_schema, merged_state = self.merge_schema_keys(
|
|
2878
|
-
schema,
|
|
2879
|
-
state)
|
|
2880
|
-
|
|
2881
2921
|
found = self.retrieve(
|
|
2882
|
-
|
|
2922
|
+
schema)
|
|
2883
2923
|
|
|
2884
2924
|
generate_function = self.choose_method(
|
|
2885
2925
|
found,
|
|
2886
|
-
|
|
2926
|
+
state,
|
|
2887
2927
|
'generate')
|
|
2888
2928
|
|
|
2889
2929
|
return generate_function(
|
|
2890
2930
|
self,
|
|
2891
2931
|
found,
|
|
2892
|
-
|
|
2932
|
+
state,
|
|
2893
2933
|
top_schema=top_schema,
|
|
2894
2934
|
top_state=top_state,
|
|
2895
2935
|
path=path)
|
|
2896
2936
|
|
|
2897
2937
|
|
|
2898
2938
|
def generate(self, schema, state):
|
|
2899
|
-
|
|
2939
|
+
merged_schema, merged_state = self.sort(
|
|
2900
2940
|
schema,
|
|
2901
2941
|
state)
|
|
2902
2942
|
|
|
2943
|
+
_, _, top_schema, top_state = self.generate_recur(
|
|
2944
|
+
merged_schema,
|
|
2945
|
+
merged_state)
|
|
2946
|
+
|
|
2903
2947
|
return top_schema, top_state
|
|
2904
2948
|
|
|
2905
2949
|
|
|
@@ -3365,11 +3409,11 @@ def apply_map(schema, current, update, core=None):
|
|
|
3365
3409
|
for key, update_value in update.items():
|
|
3366
3410
|
if key == '_add':
|
|
3367
3411
|
for addition_key, addition in update_value.items():
|
|
3368
|
-
|
|
3412
|
+
generated_schema, generated_state = core.generate(
|
|
3369
3413
|
value_type,
|
|
3370
3414
|
addition)
|
|
3371
3415
|
|
|
3372
|
-
result[addition_key] =
|
|
3416
|
+
result[addition_key] = generated_state
|
|
3373
3417
|
|
|
3374
3418
|
elif key == '_remove':
|
|
3375
3419
|
for remove_key in update_value:
|
|
@@ -3378,10 +3422,11 @@ def apply_map(schema, current, update, core=None):
|
|
|
3378
3422
|
|
|
3379
3423
|
elif key not in current:
|
|
3380
3424
|
# This supports adding without the '_add' key, if the key is not in the state
|
|
3381
|
-
|
|
3425
|
+
generated_schema, generated_state = core.generate(
|
|
3382
3426
|
value_type,
|
|
3383
3427
|
update_value)
|
|
3384
|
-
|
|
3428
|
+
|
|
3429
|
+
result[key] = generated_state
|
|
3385
3430
|
|
|
3386
3431
|
# raise Exception(f'trying to update a key that does not exist:\n value: {current}\n update: {update}')
|
|
3387
3432
|
else:
|
|
@@ -3706,7 +3751,9 @@ def generate_map(core, schema, state, top_schema=None, top_state=None, path=None
|
|
|
3706
3751
|
# generated_schema = {}
|
|
3707
3752
|
# generated_state = {}
|
|
3708
3753
|
|
|
3709
|
-
|
|
3754
|
+
# TODO: can we assume this was already sorted at the top level?
|
|
3755
|
+
|
|
3756
|
+
generated_schema, generated_state = core.sort(
|
|
3710
3757
|
schema,
|
|
3711
3758
|
state)
|
|
3712
3759
|
|
|
@@ -3719,7 +3766,7 @@ def generate_map(core, schema, state, top_schema=None, top_state=None, path=None
|
|
|
3719
3766
|
schema.get(key))
|
|
3720
3767
|
|
|
3721
3768
|
else:
|
|
3722
|
-
subschema = schema.get(key)
|
|
3769
|
+
subschema = schema.get(key, value_type)
|
|
3723
3770
|
substate = state.get(key)
|
|
3724
3771
|
|
|
3725
3772
|
subschema = core.merge_schemas(
|
|
@@ -3747,14 +3794,17 @@ def generate_tree(core, schema, state, top_schema=None, top_state=None, path=Non
|
|
|
3747
3794
|
schema,
|
|
3748
3795
|
'leaf')
|
|
3749
3796
|
|
|
3750
|
-
|
|
3797
|
+
leaf_is_any = leaf_type == 'any' or (isinstance(leaf_type, dict) and leaf_type.get('_type') == 'any')
|
|
3798
|
+
|
|
3799
|
+
if not leaf_is_any and core.check(leaf_type, state):
|
|
3751
3800
|
generate_schema, generate_state, top_schema, top_state = core.generate_recur(
|
|
3752
3801
|
leaf_type,
|
|
3753
3802
|
state,
|
|
3754
3803
|
top_schema=top_schema,
|
|
3755
3804
|
top_state=top_state,
|
|
3756
3805
|
path=path)
|
|
3757
|
-
|
|
3806
|
+
|
|
3807
|
+
elif isinstance(state, dict):
|
|
3758
3808
|
generate_schema = {}
|
|
3759
3809
|
generate_state = {}
|
|
3760
3810
|
|
|
@@ -3797,6 +3847,9 @@ def generate_tree(core, schema, state, top_schema=None, top_state=None, path=Non
|
|
|
3797
3847
|
generate_schema[key] = schema[key]
|
|
3798
3848
|
else:
|
|
3799
3849
|
raise Exception(' the impossible has occurred now is the time for celebration')
|
|
3850
|
+
else:
|
|
3851
|
+
generate_schema = schema
|
|
3852
|
+
generate_state = state
|
|
3800
3853
|
|
|
3801
3854
|
return generate_schema, generate_state, top_schema, top_state
|
|
3802
3855
|
|
|
@@ -3821,7 +3874,8 @@ def generate_ports(core, schema, wires, top_schema=None, top_state=None, path=No
|
|
|
3821
3874
|
port_key)
|
|
3822
3875
|
|
|
3823
3876
|
if isinstance(subwires, dict):
|
|
3824
|
-
top_schema, top_state =
|
|
3877
|
+
top_schema, top_state = generate_ports(
|
|
3878
|
+
core,
|
|
3825
3879
|
port_schema,
|
|
3826
3880
|
subwires,
|
|
3827
3881
|
top_schema=top_schema,
|
|
@@ -3853,7 +3907,7 @@ def generate_edge(core, schema, state, top_schema=None, top_state=None, path=Non
|
|
|
3853
3907
|
top_state = top_state or state
|
|
3854
3908
|
path = path or []
|
|
3855
3909
|
|
|
3856
|
-
|
|
3910
|
+
generated_schema, generated_state, top_schema, top_state = generate_any(
|
|
3857
3911
|
core,
|
|
3858
3912
|
schema,
|
|
3859
3913
|
state,
|
|
@@ -3861,17 +3915,25 @@ def generate_edge(core, schema, state, top_schema=None, top_state=None, path=Non
|
|
|
3861
3915
|
top_state=top_state,
|
|
3862
3916
|
path=path)
|
|
3863
3917
|
|
|
3918
|
+
deserialized_state = core.deserialize(
|
|
3919
|
+
generated_schema,
|
|
3920
|
+
generated_state)
|
|
3921
|
+
|
|
3922
|
+
merged_schema, merged_state = core.sort(
|
|
3923
|
+
generated_schema,
|
|
3924
|
+
deserialized_state)
|
|
3925
|
+
|
|
3864
3926
|
top_schema, top_state = core.set_slice(
|
|
3865
3927
|
top_schema,
|
|
3866
3928
|
top_state,
|
|
3867
3929
|
path,
|
|
3868
|
-
|
|
3869
|
-
|
|
3930
|
+
merged_schema,
|
|
3931
|
+
merged_state)
|
|
3870
3932
|
|
|
3871
3933
|
for port_key in ['inputs', 'outputs']:
|
|
3872
|
-
port_schema =
|
|
3934
|
+
port_schema = merged_schema.get(
|
|
3873
3935
|
f'_{port_key}', {})
|
|
3874
|
-
ports =
|
|
3936
|
+
ports = merged_state.get(
|
|
3875
3937
|
port_key, {})
|
|
3876
3938
|
|
|
3877
3939
|
top_schema, top_state = generate_ports(
|
|
@@ -3882,7 +3944,7 @@ def generate_edge(core, schema, state, top_schema=None, top_state=None, path=Non
|
|
|
3882
3944
|
top_state=top_state,
|
|
3883
3945
|
path=path)
|
|
3884
3946
|
|
|
3885
|
-
return
|
|
3947
|
+
return merged_schema, merged_state, top_schema, top_state
|
|
3886
3948
|
|
|
3887
3949
|
|
|
3888
3950
|
def apply_edge(schema, current, update, core):
|
|
@@ -4455,12 +4517,13 @@ def default_enum(schema, core):
|
|
|
4455
4517
|
|
|
4456
4518
|
|
|
4457
4519
|
def default_edge(schema, core):
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4520
|
+
edge = {}
|
|
4521
|
+
for key in schema:
|
|
4522
|
+
if not is_schema_key(key):
|
|
4523
|
+
edge[key] = core.default(
|
|
4524
|
+
schema[key])
|
|
4525
|
+
|
|
4526
|
+
return edge
|
|
4464
4527
|
|
|
4465
4528
|
|
|
4466
4529
|
base_type_library = {
|
|
@@ -6489,7 +6552,7 @@ def test_merge(core):
|
|
|
6489
6552
|
'x': {
|
|
6490
6553
|
'o': 99999.11}}}}
|
|
6491
6554
|
|
|
6492
|
-
result = core.
|
|
6555
|
+
result = core.merge_recur(
|
|
6493
6556
|
current_schema,
|
|
6494
6557
|
current_state,
|
|
6495
6558
|
merge_state)
|
|
@@ -6942,9 +7005,59 @@ def test_edge_cycle(core):
|
|
|
6942
7005
|
# print(diff(schema_from_schema, schema_from_state))
|
|
6943
7006
|
# print(diff(state_from_schema, state_from_state))
|
|
6944
7007
|
|
|
7008
|
+
if schema_from_schema != schema_from_state:
|
|
7009
|
+
print(diff(schema_from_schema, schema_from_state))
|
|
7010
|
+
|
|
7011
|
+
if state_from_schema != state_from_state:
|
|
7012
|
+
print(diff(state_from_schema, state_from_state))
|
|
7013
|
+
|
|
6945
7014
|
assert schema_from_schema == schema_from_state
|
|
6946
7015
|
assert state_from_schema == state_from_state
|
|
6947
7016
|
|
|
7017
|
+
for key in ['A', 'B', 'C']:
|
|
7018
|
+
for result in [schema_from_schema, state_from_schema, schema_from_state, state_from_state]:
|
|
7019
|
+
assert key in result
|
|
7020
|
+
|
|
7021
|
+
|
|
7022
|
+
def test_merge(core):
|
|
7023
|
+
schema = {
|
|
7024
|
+
'A': 'float',
|
|
7025
|
+
'B': 'enum[one,two,three]',
|
|
7026
|
+
'units': 'map[float]'}
|
|
7027
|
+
|
|
7028
|
+
state = {
|
|
7029
|
+
'C': {
|
|
7030
|
+
'_type': 'enum[x,y,z]',
|
|
7031
|
+
'_default': 'y'},
|
|
7032
|
+
'units': {
|
|
7033
|
+
'x': 11.1111,
|
|
7034
|
+
'y': 22.833333}}
|
|
7035
|
+
|
|
7036
|
+
generated_schema, generated_state = core.generate(
|
|
7037
|
+
schema,
|
|
7038
|
+
state)
|
|
7039
|
+
|
|
7040
|
+
edge_state = {
|
|
7041
|
+
'_type': 'edge',
|
|
7042
|
+
'_inputs': {
|
|
7043
|
+
'input': 'float'},
|
|
7044
|
+
'_outputs': {
|
|
7045
|
+
'output': 'float'},
|
|
7046
|
+
'inputs': {
|
|
7047
|
+
'input': ['A']},
|
|
7048
|
+
'outputs': {
|
|
7049
|
+
'output': ['D']}}
|
|
7050
|
+
|
|
7051
|
+
top_schema, top_state = core.merge(
|
|
7052
|
+
generated_schema,
|
|
7053
|
+
generated_state,
|
|
7054
|
+
['edge'],
|
|
7055
|
+
{},
|
|
7056
|
+
edge_state)
|
|
7057
|
+
|
|
7058
|
+
assert 'D' in top_state
|
|
7059
|
+
assert top_schema['D']['_type'] == 'float'
|
|
7060
|
+
|
|
6948
7061
|
|
|
6949
7062
|
if __name__ == '__main__':
|
|
6950
7063
|
core = TypeSystem()
|
|
@@ -6994,3 +7107,4 @@ if __name__ == '__main__':
|
|
|
6994
7107
|
test_representation(core)
|
|
6995
7108
|
test_generate(core)
|
|
6996
7109
|
test_edge_cycle(core)
|
|
7110
|
+
test_merge(core)
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: bigraph-schema
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.46
|
|
4
4
|
Summary: A serializable type schema for compositional systems biology
|
|
5
5
|
Home-page: https://github.com/vivarium-collective/bigraph-schema
|
|
6
6
|
Author: Eran Agmon, Ryan Spangler
|
|
7
7
|
Author-email: agmon.eran@gmail.com, ryan.spangler@gmail.com
|
|
8
|
+
License: UNKNOWN
|
|
9
|
+
Platform: UNKNOWN
|
|
8
10
|
Classifier: Development Status :: 3 - Alpha
|
|
9
11
|
Classifier: Intended Audience :: Developers
|
|
10
12
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -52,3 +54,5 @@ This resource will guide you through the core concepts and methods, helping you
|
|
|
52
54
|
## License
|
|
53
55
|
|
|
54
56
|
Bigraph-schema is open-source software released under the [Apache 2 License](https://github.com/vivarium-collective/bigraph-schema/blob/main/LICENSE).
|
|
57
|
+
|
|
58
|
+
|
|
@@ -1,15 +1,7 @@
|
|
|
1
|
-
.gitignore
|
|
2
1
|
AUTHORS.md
|
|
3
|
-
CLA.md
|
|
4
|
-
CODE_OF_CONDUCT.md
|
|
5
|
-
CONTRIBUTING.md
|
|
6
2
|
LICENSE
|
|
7
3
|
README.md
|
|
8
|
-
pytest.ini
|
|
9
|
-
release.sh
|
|
10
4
|
setup.py
|
|
11
|
-
.github/workflows/notebook_to_html.yml
|
|
12
|
-
.github/workflows/pytest.yml
|
|
13
5
|
bigraph_schema/__init__.py
|
|
14
6
|
bigraph_schema/data.py
|
|
15
7
|
bigraph_schema/parse.py
|
|
@@ -22,10 +14,4 @@ bigraph_schema.egg-info/PKG-INFO
|
|
|
22
14
|
bigraph_schema.egg-info/SOURCES.txt
|
|
23
15
|
bigraph_schema.egg-info/dependency_links.txt
|
|
24
16
|
bigraph_schema.egg-info/requires.txt
|
|
25
|
-
bigraph_schema.egg-info/top_level.txt
|
|
26
|
-
notebooks/core.ipynb
|
|
27
|
-
notebooks/demo.ipynb
|
|
28
|
-
notebooks/images/place-link.png
|
|
29
|
-
notebooks/images/reaction-after.png
|
|
30
|
-
notebooks/images/reaction-before.png
|
|
31
|
-
notebooks/images/redex-reactum.png
|
|
17
|
+
bigraph_schema.egg-info/top_level.txt
|