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.

Files changed (21) hide show
  1. {bigraph-schema-0.0.55/bigraph_schema.egg-info → bigraph-schema-0.0.57}/PKG-INFO +1 -5
  2. bigraph-schema-0.0.55/bigraph_schema/type_system_tests.py → bigraph-schema-0.0.57/bigraph_schema/tests.py +54 -3
  3. {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema/type_functions.py +257 -54
  4. {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema/type_system.py +24 -44
  5. {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema/utilities.py +0 -1
  6. {bigraph-schema-0.0.55 → bigraph-schema-0.0.57/bigraph_schema.egg-info}/PKG-INFO +1 -5
  7. {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema.egg-info/SOURCES.txt +1 -1
  8. {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/setup.py +1 -1
  9. {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/AUTHORS.md +0 -0
  10. {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/LICENSE +0 -0
  11. {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/README.md +0 -0
  12. {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema/__init__.py +0 -0
  13. {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema/edge.py +0 -0
  14. {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema/parse.py +0 -0
  15. {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema/protocols.py +0 -0
  16. {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema/registry.py +0 -0
  17. {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema/units.py +0 -0
  18. {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema.egg-info/dependency_links.txt +0 -0
  19. {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema.egg-info/requires.txt +0 -0
  20. {bigraph-schema-0.0.55 → bigraph-schema-0.0.57}/bigraph_schema.egg-info/top_level.txt +0 -0
  21. {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.55
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
- return state
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
- return state # TODO check this
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(' the impossible has occurred now is the time for celebration')
2311
+ raise Exception('the impossible has occurred now is the time for celebration')
2195
2312
  else:
2196
- generate_schema = schema
2197
- generate_state = state
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
- schema = schema or {}
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 outcome[key] != subschema:
2350
- if core.inherits_from(outcome[key], subschema):
2514
+ if schema[key] != subschema:
2515
+ if core.inherits_from(schema[key], subschema):
2351
2516
  continue
2352
- elif core.inherits_from(subschema, outcome[key]):
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 outcome or type_parameter_key(update, key):
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
- outcome.get(key),
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
- # if '_type' in update:
2372
- # if update['_type'] == 'map':
2373
- # value_schema = update.get('_value', {})
2374
- # leaf_schema = core.resolve_schemas(
2375
- # leaf_schema,
2376
- # value_schema)
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
- # elif update['_type'] == 'tree':
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
- # schema['_leaf'] = leaf_schema
2390
- # else:
2391
- # for key, subupdate in
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
- # return schema
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
- # '_resolve': resolve_tree,
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 = current.copy()
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
- outcome[parameter_key] = self.resolve_schemas(
998
- current[parameter_key],
999
- update[parameter_key])
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 outcome or type_parameter_key(current, key):
1007
- key_update = update[key]
1008
- if key_update:
1009
- outcome[key] = key_update
1010
- else:
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
- outcome.get(key),
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 project state with these ports:\n{schema}\nbut not sure what these wires are:\n{wires}')
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
 
@@ -146,7 +146,6 @@ def lookup_dtype(data_name):
146
146
 
147
147
 
148
148
  def read_datatype(data_schema):
149
- print(f'reading datatype from {data_schema}')
150
149
  return lookup_dtype(
151
150
  data_schema['_type'])
152
151
 
@@ -1,12 +1,10 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: bigraph-schema
3
- Version: 0.0.55
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
@@ -1,7 +1,7 @@
1
1
  from setuptools import setup, find_packages
2
2
 
3
3
 
4
- VERSION = '0.0.55'
4
+ VERSION = '0.0.57'
5
5
 
6
6
 
7
7
  with open("README.md", "r") as readme:
File without changes