bigraph-schema 0.0.55__tar.gz → 0.0.57__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.55/bigraph_schema.egg-info → bigraph-schema-0.0.57}/PKG-INFO +1 -5
- bigraph-schema-0.0.55/bigraph_schema/type_system_tests.py → bigraph-schema-0.0.57/bigraph_schema/tests.py +54 -3
- {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema/type_functions.py +257 -54
- {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema/type_system.py +24 -44
- {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema/utilities.py +0 -1
- {bigraph-schema-0.0.55 → bigraph-schema-0.0.57/bigraph_schema.egg-info}/PKG-INFO +1 -5
- {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema.egg-info/SOURCES.txt +1 -1
- {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/setup.py +1 -1
- {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/AUTHORS.md +0 -0
- {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/LICENSE +0 -0
- {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/README.md +0 -0
- {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema/__init__.py +0 -0
- {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema/edge.py +0 -0
- {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema/parse.py +0 -0
- {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema/protocols.py +0 -0
- {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema/registry.py +0 -0
- {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema/units.py +0 -0
- {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema.egg-info/dependency_links.txt +0 -0
- {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema.egg-info/requires.txt +0 -0
- {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema.egg-info/top_level.txt +0 -0
- {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/setup.cfg +0 -0
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: bigraph-schema
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.57
|
|
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
|
|
10
8
|
Classifier: Development Status :: 3 - Alpha
|
|
11
9
|
Classifier: Intended Audience :: Developers
|
|
12
10
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -53,5 +51,3 @@ This resource will guide you through the core concepts and methods, helping you
|
|
|
53
51
|
## License
|
|
54
52
|
|
|
55
53
|
Bigraph-schema is open-source software released under the [Apache 2 License](https://github.com/vivarium-collective/bigraph-schema/blob/main/LICENSE).
|
|
56
|
-
|
|
57
|
-
|
|
@@ -838,7 +838,7 @@ def test_inherits_from(core):
|
|
|
838
838
|
|
|
839
839
|
assert core.inherits_from(
|
|
840
840
|
'tree[path]',
|
|
841
|
-
'tree[list[string]]')
|
|
841
|
+
'tree[list[string~integer]]')
|
|
842
842
|
|
|
843
843
|
assert not core.inherits_from(
|
|
844
844
|
'tree[path]',
|
|
@@ -2342,8 +2342,6 @@ def fix_test_slice_edge(core):
|
|
|
2342
2342
|
|
|
2343
2343
|
schema, state = core.generate(initial_schema, initial_state)
|
|
2344
2344
|
|
|
2345
|
-
import ipdb; ipdb.set_trace()
|
|
2346
|
-
|
|
2347
2345
|
inner_schema, inner_state = core.slice(
|
|
2348
2346
|
schema,
|
|
2349
2347
|
state,
|
|
@@ -2381,6 +2379,58 @@ def fix_test_complex_wiring(core):
|
|
|
2381
2379
|
assert state['AAAA']['AAAAA']['d'] == 0.0
|
|
2382
2380
|
|
|
2383
2381
|
|
|
2382
|
+
def test_tree_equivalence(core):
|
|
2383
|
+
initial_state = {
|
|
2384
|
+
'store1': {
|
|
2385
|
+
'store1.1': '1.0'}}
|
|
2386
|
+
|
|
2387
|
+
# create a nested store type and register it
|
|
2388
|
+
store11 = {
|
|
2389
|
+
'store1.1': {
|
|
2390
|
+
'_type': 'float',
|
|
2391
|
+
'_default': '1.0'}}
|
|
2392
|
+
|
|
2393
|
+
core.register('store1.1', store11)
|
|
2394
|
+
|
|
2395
|
+
# create a tree schema that uses this type
|
|
2396
|
+
store_tree = {
|
|
2397
|
+
'_type': 'tree',
|
|
2398
|
+
'_leaf': 'store1.1'}
|
|
2399
|
+
|
|
2400
|
+
# interpret the state as a simple tree of float
|
|
2401
|
+
store_schema, store_state = core.generate(
|
|
2402
|
+
'tree[float]',
|
|
2403
|
+
initial_state)
|
|
2404
|
+
|
|
2405
|
+
# use the nested type to fill in the state
|
|
2406
|
+
tree_schema, tree_state = core.generate(
|
|
2407
|
+
store_tree,
|
|
2408
|
+
{'store1': None})
|
|
2409
|
+
|
|
2410
|
+
# use the nested type but with an empty dict instead
|
|
2411
|
+
fill_schema, fill_state = core.generate(
|
|
2412
|
+
store_tree,
|
|
2413
|
+
{'store1': {}})
|
|
2414
|
+
|
|
2415
|
+
# supply the whole schema at once instead of registering
|
|
2416
|
+
inline_schema, inline_state = core.generate({
|
|
2417
|
+
'_type': 'tree',
|
|
2418
|
+
'_leaf': {
|
|
2419
|
+
'store1.1': {
|
|
2420
|
+
'_type': 'float',
|
|
2421
|
+
'_default': '1.0'}}},
|
|
2422
|
+
{'store1': {}})
|
|
2423
|
+
|
|
2424
|
+
# here is the state we expect from each of these calls
|
|
2425
|
+
# to generate
|
|
2426
|
+
target_state = {
|
|
2427
|
+
'store1': {
|
|
2428
|
+
'store1.1': 1.0}}
|
|
2429
|
+
|
|
2430
|
+
# all of the resulting generated states are the same
|
|
2431
|
+
assert store_state == tree_state == fill_state == inline_state == target_state
|
|
2432
|
+
|
|
2433
|
+
|
|
2384
2434
|
if __name__ == '__main__':
|
|
2385
2435
|
core = TypeSystem()
|
|
2386
2436
|
core = register_test_types(core)
|
|
@@ -2432,5 +2482,6 @@ if __name__ == '__main__':
|
|
|
2432
2482
|
test_merge(core)
|
|
2433
2483
|
test_remove_omitted(core)
|
|
2434
2484
|
test_union_key_error(core)
|
|
2485
|
+
test_tree_equivalence(core)
|
|
2435
2486
|
# test_slice_edge(core)
|
|
2436
2487
|
# test_complex_wiring(core)
|
|
@@ -75,6 +75,7 @@ import typing
|
|
|
75
75
|
from typing import NewType, Union, Mapping, List, Dict, Optional, Callable
|
|
76
76
|
from dataclasses import field, make_dataclass
|
|
77
77
|
|
|
78
|
+
from bigraph_schema import get_path, set_path
|
|
78
79
|
from bigraph_schema.units import units, render_units_type
|
|
79
80
|
from bigraph_schema.registry import (
|
|
80
81
|
is_schema_key, non_schema_keys, type_parameter_key, deep_merge, hierarchy_depth, establish_path
|
|
@@ -1083,8 +1084,50 @@ def serialize_edge(schema, value, core):
|
|
|
1083
1084
|
def serialize_enum(schema, value, core):
|
|
1084
1085
|
return value
|
|
1085
1086
|
|
|
1087
|
+
def recur_serialize_schema(schema, core, path=None, parents=None):
|
|
1088
|
+
""" Serialize schema to a string """
|
|
1089
|
+
path = path or []
|
|
1090
|
+
parents = parents or []
|
|
1091
|
+
schema_id = id(schema)
|
|
1092
|
+
|
|
1093
|
+
if schema_id in parents:
|
|
1094
|
+
index = parents.index(schema_id)
|
|
1095
|
+
reference = path[:index]
|
|
1096
|
+
output = '/'.join(reference)
|
|
1097
|
+
return f'/{output}'
|
|
1098
|
+
|
|
1099
|
+
if isinstance(schema, str):
|
|
1100
|
+
return schema
|
|
1101
|
+
|
|
1102
|
+
elif isinstance(schema, tuple):
|
|
1103
|
+
inner = [
|
|
1104
|
+
recur_serialize_schema(
|
|
1105
|
+
schema=element,
|
|
1106
|
+
core=core,
|
|
1107
|
+
path=path+[index],
|
|
1108
|
+
parents=parents+[schema_id])
|
|
1109
|
+
for index, element in enumerate(schema)]
|
|
1110
|
+
|
|
1111
|
+
return inner
|
|
1112
|
+
|
|
1113
|
+
elif isinstance(schema, dict):
|
|
1114
|
+
inner = {}
|
|
1115
|
+
for key in schema:
|
|
1116
|
+
subschema = recur_serialize_schema(
|
|
1117
|
+
schema=schema[key],
|
|
1118
|
+
core=core,
|
|
1119
|
+
path=path+[key],
|
|
1120
|
+
parents=parents+[schema_id])
|
|
1121
|
+
inner[key] = subschema
|
|
1122
|
+
|
|
1123
|
+
return inner
|
|
1124
|
+
|
|
1125
|
+
else:
|
|
1126
|
+
return schema
|
|
1127
|
+
|
|
1086
1128
|
def serialize_schema(schema, state, core):
|
|
1087
|
-
|
|
1129
|
+
""" Serialize schema to a string """
|
|
1130
|
+
return recur_serialize_schema(schema=state, core=core)
|
|
1088
1131
|
|
|
1089
1132
|
def serialize_array(schema, value, core):
|
|
1090
1133
|
""" Serialize numpy array to list """
|
|
@@ -1229,6 +1272,9 @@ def deserialize_maybe(schema, encoded, core):
|
|
|
1229
1272
|
|
|
1230
1273
|
return core.deserialize(value_type, encoded)
|
|
1231
1274
|
|
|
1275
|
+
def deserialize_quote(schema, state, core):
|
|
1276
|
+
return state
|
|
1277
|
+
|
|
1232
1278
|
def deserialize_boolean(schema, encoded, core) -> bool:
|
|
1233
1279
|
if encoded == 'true':
|
|
1234
1280
|
return True
|
|
@@ -1278,8 +1324,20 @@ def deserialize_map(schema, encoded, core=None):
|
|
|
1278
1324
|
subvalue) if not is_schema_key(key) else subvalue
|
|
1279
1325
|
for key, subvalue in encoded.items()}
|
|
1280
1326
|
|
|
1327
|
+
|
|
1328
|
+
def enum_list(enum_schema):
|
|
1329
|
+
return [
|
|
1330
|
+
enum_schema[f'_{parameter}']
|
|
1331
|
+
for parameter in enum_schema['_type_parameters']]
|
|
1332
|
+
|
|
1333
|
+
|
|
1281
1334
|
def deserialize_enum(schema, state, core):
|
|
1282
|
-
|
|
1335
|
+
enum = enum_list(schema)
|
|
1336
|
+
if state in enum:
|
|
1337
|
+
return state
|
|
1338
|
+
else:
|
|
1339
|
+
raise Exception(f'{state} not in enum: {enum}')
|
|
1340
|
+
|
|
1283
1341
|
|
|
1284
1342
|
def deserialize_array(schema, encoded, core):
|
|
1285
1343
|
if isinstance(encoded, np.ndarray):
|
|
@@ -1313,8 +1371,52 @@ def deserialize_array(schema, encoded, core):
|
|
|
1313
1371
|
def deserialize_edge(schema, encoded, core):
|
|
1314
1372
|
return encoded
|
|
1315
1373
|
|
|
1374
|
+
def recur_deserialize_schema(schema, core, top_state=None, path=None):
|
|
1375
|
+
top_state = top_state or schema
|
|
1376
|
+
path = path or []
|
|
1377
|
+
|
|
1378
|
+
if isinstance(schema, dict):
|
|
1379
|
+
subschema = {}
|
|
1380
|
+
for key, value in schema.items():
|
|
1381
|
+
subschema[key] = recur_deserialize_schema(
|
|
1382
|
+
value,
|
|
1383
|
+
core,
|
|
1384
|
+
top_state=top_state,
|
|
1385
|
+
path=path+[key])
|
|
1386
|
+
|
|
1387
|
+
return subschema
|
|
1388
|
+
|
|
1389
|
+
elif isinstance(schema, list):
|
|
1390
|
+
subschema = []
|
|
1391
|
+
for index, value in enumerate(schema):
|
|
1392
|
+
subschema.append(
|
|
1393
|
+
recur_deserialize_schema(
|
|
1394
|
+
value,
|
|
1395
|
+
core,
|
|
1396
|
+
top_state=top_state,
|
|
1397
|
+
path=path+[index]))
|
|
1398
|
+
|
|
1399
|
+
return tuple(subschema)
|
|
1400
|
+
|
|
1401
|
+
elif isinstance(schema, str):
|
|
1402
|
+
if schema.startswith('/'): # this is a reference to another schema
|
|
1403
|
+
local_path = schema.split('/')[1:]
|
|
1404
|
+
reference = get_path(top_state, local_path)
|
|
1405
|
+
|
|
1406
|
+
set_path(
|
|
1407
|
+
tree=top_state,
|
|
1408
|
+
path=path,
|
|
1409
|
+
value=reference)
|
|
1410
|
+
|
|
1411
|
+
return reference
|
|
1412
|
+
else:
|
|
1413
|
+
return schema
|
|
1414
|
+
else:
|
|
1415
|
+
return schema
|
|
1416
|
+
|
|
1417
|
+
|
|
1316
1418
|
def deserialize_schema(schema, state, core):
|
|
1317
|
-
return state
|
|
1419
|
+
return recur_deserialize_schema(schema=state, core=core)
|
|
1318
1420
|
|
|
1319
1421
|
|
|
1320
1422
|
# =========================
|
|
@@ -1463,6 +1565,19 @@ def slice_tree(schema, state, path, core):
|
|
|
1463
1565
|
|
|
1464
1566
|
return slice_schema, slice_state
|
|
1465
1567
|
|
|
1568
|
+
if not state:
|
|
1569
|
+
default = core.default(
|
|
1570
|
+
leaf_type)
|
|
1571
|
+
try:
|
|
1572
|
+
down_schema, down_state = core.slice(
|
|
1573
|
+
leaf_type,
|
|
1574
|
+
default,
|
|
1575
|
+
path)
|
|
1576
|
+
|
|
1577
|
+
if down_state:
|
|
1578
|
+
return down_schema, down_state
|
|
1579
|
+
except:
|
|
1580
|
+
state = {}
|
|
1466
1581
|
if not head in state:
|
|
1467
1582
|
state[head] = {}
|
|
1468
1583
|
|
|
@@ -2047,22 +2162,28 @@ def generate_any(core, schema, state, top_schema=None, top_state=None, path=None
|
|
|
2047
2162
|
|
|
2048
2163
|
generated_state[key] = substate
|
|
2049
2164
|
|
|
2050
|
-
if path:
|
|
2051
|
-
top_schema, top_state = core.set_slice(
|
|
2052
|
-
top_schema,
|
|
2053
|
-
top_state,
|
|
2054
|
-
path,
|
|
2055
|
-
generated_schema,
|
|
2056
|
-
generated_state)
|
|
2057
|
-
else:
|
|
2058
|
-
top_state = core.merge_recur(
|
|
2059
|
-
top_schema,
|
|
2060
|
-
top_state,
|
|
2061
|
-
generated_state)
|
|
2062
|
-
|
|
2063
2165
|
else:
|
|
2166
|
+
if not core.check(schema, state):
|
|
2167
|
+
deserialized_state = core.deserialize(schema, state)
|
|
2168
|
+
if core.check(schema, deserialized_state):
|
|
2169
|
+
state = deserialized_state
|
|
2170
|
+
else:
|
|
2171
|
+
raise Exception(f'cannot generate {state} as {schema}')
|
|
2064
2172
|
generated_schema, generated_state = schema, state
|
|
2065
2173
|
|
|
2174
|
+
if path:
|
|
2175
|
+
top_schema, top_state = core.set_slice(
|
|
2176
|
+
top_schema,
|
|
2177
|
+
top_state,
|
|
2178
|
+
path,
|
|
2179
|
+
generated_schema,
|
|
2180
|
+
generated_state)
|
|
2181
|
+
else:
|
|
2182
|
+
top_state = core.merge_recur(
|
|
2183
|
+
top_schema,
|
|
2184
|
+
top_state,
|
|
2185
|
+
generated_state)
|
|
2186
|
+
|
|
2066
2187
|
return generated_schema, generated_state, top_schema, top_state
|
|
2067
2188
|
|
|
2068
2189
|
def generate_quote(core, schema, state, top_schema=None, top_state=None, path=None):
|
|
@@ -2076,10 +2197,6 @@ def default_quote(schema, core):
|
|
|
2076
2197
|
return None
|
|
2077
2198
|
|
|
2078
2199
|
|
|
2079
|
-
def deserialize_quote(schema, state, core):
|
|
2080
|
-
return state
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
2200
|
def generate_map(core, schema, state, top_schema=None, top_state=None, path=None):
|
|
2084
2201
|
schema = schema or {}
|
|
2085
2202
|
state = state or core.default(schema)
|
|
@@ -2191,13 +2308,18 @@ def generate_tree(core, schema, state, top_schema=None, top_state=None, path=Non
|
|
|
2191
2308
|
elif key in schema:
|
|
2192
2309
|
generate_schema[key] = schema[key]
|
|
2193
2310
|
else:
|
|
2194
|
-
raise Exception('
|
|
2311
|
+
raise Exception('the impossible has occurred now is the time for celebration')
|
|
2195
2312
|
else:
|
|
2196
|
-
generate_schema =
|
|
2197
|
-
|
|
2313
|
+
generate_schema, generate_state, top_schema, top_state = core.generate_recur(
|
|
2314
|
+
leaf_type,
|
|
2315
|
+
state,
|
|
2316
|
+
top_schema=top_schema,
|
|
2317
|
+
top_state=top_state,
|
|
2318
|
+
path=path)
|
|
2198
2319
|
|
|
2199
2320
|
return generate_schema, generate_state, top_schema, top_state
|
|
2200
2321
|
|
|
2322
|
+
|
|
2201
2323
|
def generate_ports(core, schema, wires, top_schema=None, top_state=None, path=None):
|
|
2202
2324
|
schema = schema or {}
|
|
2203
2325
|
wires = wires or {}
|
|
@@ -2322,9 +2444,45 @@ def sort_any(core, schema, state):
|
|
|
2322
2444
|
|
|
2323
2445
|
return merged_schema, merged_state
|
|
2324
2446
|
|
|
2447
|
+
|
|
2325
2448
|
def sort_quote(core, schema, state):
|
|
2326
2449
|
return schema, state
|
|
2327
2450
|
|
|
2451
|
+
|
|
2452
|
+
def sort_map(core, schema, state):
|
|
2453
|
+
if not isinstance(schema, dict):
|
|
2454
|
+
schema = core.find(schema)
|
|
2455
|
+
if not isinstance(state, dict):
|
|
2456
|
+
return schema, state
|
|
2457
|
+
|
|
2458
|
+
merged_schema = {}
|
|
2459
|
+
merged_state = {}
|
|
2460
|
+
|
|
2461
|
+
value_schema = core.find_parameter(
|
|
2462
|
+
schema,
|
|
2463
|
+
'value')
|
|
2464
|
+
|
|
2465
|
+
for key in union_keys(schema, state):
|
|
2466
|
+
if is_schema_key(key):
|
|
2467
|
+
if key in state:
|
|
2468
|
+
merged_schema[key] = core.merge_schemas(
|
|
2469
|
+
schema.get(key, {}),
|
|
2470
|
+
state[key])
|
|
2471
|
+
else:
|
|
2472
|
+
merged_schema[key] = schema[key]
|
|
2473
|
+
else:
|
|
2474
|
+
subschema, merged_state[key] = core.sort(
|
|
2475
|
+
schema.get(key, {}),
|
|
2476
|
+
state.get(key, None))
|
|
2477
|
+
if subschema:
|
|
2478
|
+
value_schema = core.merge_schemas(
|
|
2479
|
+
value_schema,
|
|
2480
|
+
subschema)
|
|
2481
|
+
# merged_schema[key] = subschema
|
|
2482
|
+
|
|
2483
|
+
return merged_schema, merged_state
|
|
2484
|
+
|
|
2485
|
+
|
|
2328
2486
|
def find_union_type(core, schema, state):
|
|
2329
2487
|
parameters = core.parameters_for(schema)
|
|
2330
2488
|
|
|
@@ -2341,56 +2499,99 @@ def find_union_type(core, schema, state):
|
|
|
2341
2499
|
# Each function handles a specific type of schema and ensures that updates are resolved correctly.
|
|
2342
2500
|
|
|
2343
2501
|
def resolve_any(schema, update, core):
|
|
2344
|
-
|
|
2502
|
+
if not schema or schema == 'any':
|
|
2503
|
+
return update
|
|
2504
|
+
if not update or update == 'any':
|
|
2505
|
+
return schema
|
|
2506
|
+
|
|
2507
|
+
if isinstance(schema, str):
|
|
2508
|
+
schema = core.access(schema)
|
|
2509
|
+
|
|
2345
2510
|
outcome = schema.copy()
|
|
2346
2511
|
|
|
2347
2512
|
for key, subschema in update.items():
|
|
2348
2513
|
if key == '_type' and key in outcome:
|
|
2349
|
-
if
|
|
2350
|
-
if core.inherits_from(
|
|
2514
|
+
if schema[key] != subschema:
|
|
2515
|
+
if core.inherits_from(schema[key], subschema):
|
|
2351
2516
|
continue
|
|
2352
|
-
elif core.inherits_from(subschema,
|
|
2517
|
+
elif core.inherits_from(subschema, schema[key]):
|
|
2353
2518
|
outcome[key] = subschema
|
|
2354
2519
|
else:
|
|
2355
2520
|
raise Exception(f'cannot resolve types when updating\ncurrent type: {schema}\nupdate type: {update}')
|
|
2356
2521
|
|
|
2357
|
-
elif not key in
|
|
2522
|
+
elif not key in schema or type_parameter_key(schema, key):
|
|
2358
2523
|
if subschema:
|
|
2359
2524
|
outcome[key] = subschema
|
|
2360
2525
|
else:
|
|
2361
2526
|
outcome[key] = core.resolve_schemas(
|
|
2362
|
-
|
|
2527
|
+
schema.get(key),
|
|
2363
2528
|
subschema)
|
|
2364
2529
|
|
|
2365
2530
|
return outcome
|
|
2366
2531
|
|
|
2367
|
-
# def resolve_tree(schema, update, core):
|
|
2368
|
-
# if isinstance(update, dict):
|
|
2369
|
-
# leaf_schema = schema.get('_leaf', {})
|
|
2370
2532
|
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2533
|
+
def resolve_union(schema, update, core):
|
|
2534
|
+
if '_type' in schema and schema['_type'] == 'union':
|
|
2535
|
+
union_type, resolve_type = schema, update
|
|
2536
|
+
elif '_type' in update and update['_type'] == 'union':
|
|
2537
|
+
union_type, resolve_type = update, schema
|
|
2538
|
+
else:
|
|
2539
|
+
raise Exception(f'empty union?\n{schema}\n{update}')
|
|
2540
|
+
|
|
2541
|
+
if '_type_parameters' in union_type:
|
|
2542
|
+
parameters = union_type['_type_parameters']
|
|
2543
|
+
else:
|
|
2544
|
+
raise Exception(f'no type parameters in union?\n{union_type}')
|
|
2545
|
+
|
|
2546
|
+
for parameter in parameters:
|
|
2547
|
+
parameter_key = f'_{parameter}'
|
|
2548
|
+
parameter_type = union_type[parameter_key]
|
|
2549
|
+
try:
|
|
2550
|
+
resolved = core.resolve(
|
|
2551
|
+
parameter_type,
|
|
2552
|
+
resolve_type)
|
|
2553
|
+
return union_type
|
|
2554
|
+
except Exception as e:
|
|
2555
|
+
pass
|
|
2556
|
+
|
|
2557
|
+
raise Exception(f'could not resolve type with union:\n{update}\nunion:\n{schema}')
|
|
2558
|
+
|
|
2559
|
+
|
|
2560
|
+
def resolve_tree(schema, update, core):
|
|
2561
|
+
if not schema or schema == 'any':
|
|
2562
|
+
return update
|
|
2563
|
+
if not update or update == 'any':
|
|
2564
|
+
return schema
|
|
2565
|
+
|
|
2566
|
+
outcome = schema.copy()
|
|
2567
|
+
|
|
2568
|
+
for key, subschema in update.items():
|
|
2569
|
+
if key == '_type' and key in outcome:
|
|
2570
|
+
if outcome[key] != subschema:
|
|
2571
|
+
if core.inherits_from(outcome[key], subschema):
|
|
2572
|
+
continue
|
|
2573
|
+
elif core.inherits_from(subschema, outcome[key]):
|
|
2574
|
+
outcome[key] = subschema
|
|
2575
|
+
else:
|
|
2576
|
+
leaf_type = core.find_parameter(
|
|
2577
|
+
schema,
|
|
2578
|
+
'leaf')
|
|
2579
|
+
|
|
2580
|
+
return core.resolve(
|
|
2581
|
+
leaf_type,
|
|
2582
|
+
update)
|
|
2377
2583
|
|
|
2378
|
-
#
|
|
2379
|
-
# for key, subschema in update.items():
|
|
2380
|
-
# if not key.startswith('_'):
|
|
2381
|
-
# leaf_schema = core.resolve_schemas(
|
|
2382
|
-
# leaf_schema,
|
|
2383
|
-
# subschema)
|
|
2384
|
-
# else:
|
|
2385
|
-
# leaf_schema = core.resolve_schemas(
|
|
2386
|
-
# leaf_schema,
|
|
2387
|
-
# update)
|
|
2584
|
+
# raise Exception(f'cannot resolve types when updating\ncurrent type: {schema}\nupdate type: {update}')
|
|
2388
2585
|
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2586
|
+
elif not key in outcome or type_parameter_key(update, key):
|
|
2587
|
+
if subschema:
|
|
2588
|
+
outcome[key] = subschema
|
|
2589
|
+
else:
|
|
2590
|
+
outcome[key] = core.resolve_schemas(
|
|
2591
|
+
outcome.get(key),
|
|
2592
|
+
subschema)
|
|
2392
2593
|
|
|
2393
|
-
|
|
2594
|
+
return outcome
|
|
2394
2595
|
|
|
2395
2596
|
|
|
2396
2597
|
# ==========================
|
|
@@ -2584,6 +2785,7 @@ base_types = {
|
|
|
2584
2785
|
'_slice': slice_map,
|
|
2585
2786
|
'_fold': fold_map,
|
|
2586
2787
|
'_divide': divide_map,
|
|
2788
|
+
'_sort': sort_map,
|
|
2587
2789
|
'_type_parameters': ['value'],
|
|
2588
2790
|
'_description': 'flat mapping from keys of strings to values of any type'},
|
|
2589
2791
|
|
|
@@ -2599,7 +2801,7 @@ base_types = {
|
|
|
2599
2801
|
'_dataclass': dataclass_tree,
|
|
2600
2802
|
'_fold': fold_tree,
|
|
2601
2803
|
'_divide': divide_tree,
|
|
2602
|
-
|
|
2804
|
+
'_resolve': resolve_tree,
|
|
2603
2805
|
'_type_parameters': ['leaf'],
|
|
2604
2806
|
'_description': 'mapping from str to some type in a potentially nested form'},
|
|
2605
2807
|
|
|
@@ -2635,7 +2837,7 @@ base_types = {
|
|
|
2635
2837
|
|
|
2636
2838
|
'path': {
|
|
2637
2839
|
'_type': 'path',
|
|
2638
|
-
'_inherit': 'list[string]',
|
|
2840
|
+
'_inherit': 'list[string~integer]',
|
|
2639
2841
|
'_apply': apply_path},
|
|
2640
2842
|
|
|
2641
2843
|
'wires': {
|
|
@@ -2714,4 +2916,5 @@ registry_types = {
|
|
|
2714
2916
|
'_deserialize': deserialize_union,
|
|
2715
2917
|
'_dataclass': dataclass_union,
|
|
2716
2918
|
'_fold': fold_union,
|
|
2919
|
+
'_resolve': resolve_union,
|
|
2717
2920
|
'_description': 'union of a set of possible types'}}
|
|
@@ -274,6 +274,10 @@ class TypeSystem(Registry):
|
|
|
274
274
|
def merge_schemas(self, current, update):
|
|
275
275
|
if current == update:
|
|
276
276
|
return update
|
|
277
|
+
if current is None:
|
|
278
|
+
return update
|
|
279
|
+
if update is None:
|
|
280
|
+
return current
|
|
277
281
|
if not isinstance(current, dict):
|
|
278
282
|
return update
|
|
279
283
|
if not isinstance(update, dict):
|
|
@@ -349,20 +353,10 @@ class TypeSystem(Registry):
|
|
|
349
353
|
registry_type = self.retrieve(
|
|
350
354
|
schema['_type'])
|
|
351
355
|
|
|
352
|
-
# found = self.resolve(
|
|
353
|
-
# registry_type,
|
|
354
|
-
# schema)
|
|
355
|
-
|
|
356
356
|
found = self.merge_schemas(
|
|
357
357
|
registry_type,
|
|
358
358
|
schema)
|
|
359
359
|
|
|
360
|
-
# found = schema.copy()
|
|
361
|
-
|
|
362
|
-
# for key, value in registry_type.items():
|
|
363
|
-
# if key == '_type' or key not in found:
|
|
364
|
-
# found[key] = value
|
|
365
|
-
|
|
366
360
|
else:
|
|
367
361
|
found = {
|
|
368
362
|
key: self.access(
|
|
@@ -973,6 +967,9 @@ class TypeSystem(Registry):
|
|
|
973
967
|
|
|
974
968
|
|
|
975
969
|
def resolve_schemas(self, initial_current, initial_update):
|
|
970
|
+
if initial_current == initial_update:
|
|
971
|
+
return initial_current
|
|
972
|
+
|
|
976
973
|
current = self.access(initial_current)
|
|
977
974
|
update = self.access(initial_update)
|
|
978
975
|
|
|
@@ -986,7 +983,7 @@ class TypeSystem(Registry):
|
|
|
986
983
|
outcome = update
|
|
987
984
|
|
|
988
985
|
elif '_type' in current and '_type' in update and current['_type'] == update['_type']:
|
|
989
|
-
outcome =
|
|
986
|
+
outcome = {}
|
|
990
987
|
|
|
991
988
|
for key in update:
|
|
992
989
|
if key == '_type_parameters' and '_type_parameters' in current:
|
|
@@ -994,23 +991,27 @@ class TypeSystem(Registry):
|
|
|
994
991
|
parameter_key = f'_{parameter}'
|
|
995
992
|
if parameter in current['_type_parameters']:
|
|
996
993
|
if parameter_key in current:
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
994
|
+
if parameter_key in update:
|
|
995
|
+
outcome[parameter_key] = self.resolve_schemas(
|
|
996
|
+
current[parameter_key],
|
|
997
|
+
update[parameter_key])
|
|
998
|
+
else:
|
|
999
|
+
outcome[parameter_key] = current[parameter_key]
|
|
1000
1000
|
elif parameter_key in update:
|
|
1001
1001
|
outcome[parameter_key] = update[parameter_key]
|
|
1002
|
-
# else:
|
|
1003
|
-
# outcome[parameter_key] = {}
|
|
1004
1002
|
else:
|
|
1005
1003
|
outcome[parameter_key] = update[parameter_key]
|
|
1006
|
-
elif key not in
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1004
|
+
elif key not in current or type_parameter_key(current, key):
|
|
1005
|
+
if update[key]:
|
|
1006
|
+
outcome[key] = update[key]
|
|
1007
|
+
else:
|
|
1008
|
+
outcome[key] = current.get(key)
|
|
1009
|
+
elif key in current and current[key]:
|
|
1011
1010
|
outcome[key] = self.resolve_schemas(
|
|
1012
|
-
|
|
1011
|
+
current[key],
|
|
1013
1012
|
update[key])
|
|
1013
|
+
else:
|
|
1014
|
+
outcome[key] = update[key]
|
|
1014
1015
|
|
|
1015
1016
|
elif '_type' in update and '_type' not in current:
|
|
1016
1017
|
outcome = self.resolve(update, current)
|
|
@@ -1018,26 +1019,6 @@ class TypeSystem(Registry):
|
|
|
1018
1019
|
else:
|
|
1019
1020
|
outcome = self.resolve(current, update)
|
|
1020
1021
|
|
|
1021
|
-
# elif '_type' in current:
|
|
1022
|
-
# outcome = self.resolve(current, update)
|
|
1023
|
-
|
|
1024
|
-
# elif '_type' in update:
|
|
1025
|
-
# outcome = self.resolve(update, current)
|
|
1026
|
-
|
|
1027
|
-
# else:
|
|
1028
|
-
# outcome = self.resolve(current, update)
|
|
1029
|
-
# outcome = current.copy()
|
|
1030
|
-
|
|
1031
|
-
# for key in update:
|
|
1032
|
-
# if not key in outcome or is_schema_key(update, key):
|
|
1033
|
-
# key_update = update[key]
|
|
1034
|
-
# if key_update:
|
|
1035
|
-
# outcome[key] = key_update
|
|
1036
|
-
# else:
|
|
1037
|
-
# outcome[key] = self.resolve_schemas(
|
|
1038
|
-
# outcome.get(key),
|
|
1039
|
-
# update[key])
|
|
1040
|
-
|
|
1041
1022
|
return outcome
|
|
1042
1023
|
|
|
1043
1024
|
|
|
@@ -1326,7 +1307,6 @@ class TypeSystem(Registry):
|
|
|
1326
1307
|
|
|
1327
1308
|
|
|
1328
1309
|
def set_slice(self, schema, state, path, target_schema, target_state, defer=False):
|
|
1329
|
-
|
|
1330
1310
|
'''
|
|
1331
1311
|
Makes a local modification to the schema/state at the path, and
|
|
1332
1312
|
returns the top_schema and top_state
|
|
@@ -1610,7 +1590,7 @@ class TypeSystem(Registry):
|
|
|
1610
1590
|
if inner_view is not None:
|
|
1611
1591
|
result[port_key] = inner_view
|
|
1612
1592
|
else:
|
|
1613
|
-
raise Exception(f'trying to
|
|
1593
|
+
raise Exception(f'trying to view state with these ports:\n{schema}\nbut not sure what these wires are:\n{wires}')
|
|
1614
1594
|
|
|
1615
1595
|
return result
|
|
1616
1596
|
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: bigraph-schema
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.57
|
|
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
|
|
10
8
|
Classifier: Development Status :: 3 - Alpha
|
|
11
9
|
Classifier: Intended Audience :: Developers
|
|
12
10
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -53,5 +51,3 @@ This resource will guide you through the core concepts and methods, helping you
|
|
|
53
51
|
## License
|
|
54
52
|
|
|
55
53
|
Bigraph-schema is open-source software released under the [Apache 2 License](https://github.com/vivarium-collective/bigraph-schema/blob/main/LICENSE).
|
|
56
|
-
|
|
57
|
-
|
|
@@ -7,9 +7,9 @@ bigraph_schema/edge.py
|
|
|
7
7
|
bigraph_schema/parse.py
|
|
8
8
|
bigraph_schema/protocols.py
|
|
9
9
|
bigraph_schema/registry.py
|
|
10
|
+
bigraph_schema/tests.py
|
|
10
11
|
bigraph_schema/type_functions.py
|
|
11
12
|
bigraph_schema/type_system.py
|
|
12
|
-
bigraph_schema/type_system_tests.py
|
|
13
13
|
bigraph_schema/units.py
|
|
14
14
|
bigraph_schema/utilities.py
|
|
15
15
|
bigraph_schema.egg-info/PKG-INFO
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|