bigraph-schema 0.0.56__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.56/bigraph_schema.egg-info → bigraph-schema-0.0.57}/PKG-INFO +1 -1
  2. bigraph-schema-0.0.56/bigraph_schema/type_system_tests.py → bigraph-schema-0.0.57/bigraph_schema/tests.py +54 -3
  3. {bigraph-schema-0.0.56 → bigraph-schema-0.0.57}/bigraph_schema/type_functions.py +127 -49
  4. {bigraph-schema-0.0.56 → bigraph-schema-0.0.57}/bigraph_schema/type_system.py +23 -33
  5. {bigraph-schema-0.0.56 → bigraph-schema-0.0.57}/bigraph_schema/utilities.py +0 -1
  6. {bigraph-schema-0.0.56 → bigraph-schema-0.0.57/bigraph_schema.egg-info}/PKG-INFO +1 -1
  7. {bigraph-schema-0.0.56 → bigraph-schema-0.0.57}/bigraph_schema.egg-info/SOURCES.txt +1 -1
  8. {bigraph-schema-0.0.56 → bigraph-schema-0.0.57}/setup.py +1 -1
  9. {bigraph-schema-0.0.56 → bigraph-schema-0.0.57}/AUTHORS.md +0 -0
  10. {bigraph-schema-0.0.56 → bigraph-schema-0.0.57}/LICENSE +0 -0
  11. {bigraph-schema-0.0.56 → bigraph-schema-0.0.57}/README.md +0 -0
  12. {bigraph-schema-0.0.56 → bigraph-schema-0.0.57}/bigraph_schema/__init__.py +0 -0
  13. {bigraph-schema-0.0.56 → bigraph-schema-0.0.57}/bigraph_schema/edge.py +0 -0
  14. {bigraph-schema-0.0.56 → bigraph-schema-0.0.57}/bigraph_schema/parse.py +0 -0
  15. {bigraph-schema-0.0.56 → bigraph-schema-0.0.57}/bigraph_schema/protocols.py +0 -0
  16. {bigraph-schema-0.0.56 → bigraph-schema-0.0.57}/bigraph_schema/registry.py +0 -0
  17. {bigraph-schema-0.0.56 → bigraph-schema-0.0.57}/bigraph_schema/units.py +0 -0
  18. {bigraph-schema-0.0.56 → bigraph-schema-0.0.57}/bigraph_schema.egg-info/dependency_links.txt +0 -0
  19. {bigraph-schema-0.0.56 → bigraph-schema-0.0.57}/bigraph_schema.egg-info/requires.txt +0 -0
  20. {bigraph-schema-0.0.56 → bigraph-schema-0.0.57}/bigraph_schema.egg-info/top_level.txt +0 -0
  21. {bigraph-schema-0.0.56 → bigraph-schema-0.0.57}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: bigraph-schema
3
- Version: 0.0.56
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
@@ -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)
@@ -1324,8 +1324,20 @@ def deserialize_map(schema, encoded, core=None):
1324
1324
  subvalue) if not is_schema_key(key) else subvalue
1325
1325
  for key, subvalue in encoded.items()}
1326
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
+
1327
1334
  def deserialize_enum(schema, state, core):
1328
- 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
+
1329
1341
 
1330
1342
  def deserialize_array(schema, encoded, core):
1331
1343
  if isinstance(encoded, np.ndarray):
@@ -1553,6 +1565,19 @@ def slice_tree(schema, state, path, core):
1553
1565
 
1554
1566
  return slice_schema, slice_state
1555
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 = {}
1556
1581
  if not head in state:
1557
1582
  state[head] = {}
1558
1583
 
@@ -2137,24 +2162,28 @@ def generate_any(core, schema, state, top_schema=None, top_state=None, path=None
2137
2162
 
2138
2163
  generated_state[key] = substate
2139
2164
 
2140
- if path:
2141
- top_schema, top_state = core.set_slice(
2142
- top_schema,
2143
- top_state,
2144
- path,
2145
- generated_schema,
2146
- generated_state)
2147
- else:
2148
- top_state = core.merge_recur(
2149
- top_schema,
2150
- top_state,
2151
- generated_state)
2152
-
2153
2165
  else:
2154
2166
  if not core.check(schema, state):
2155
- state = core.deserialize(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}')
2156
2172
  generated_schema, generated_state = schema, state
2157
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
+
2158
2187
  return generated_schema, generated_state, top_schema, top_state
2159
2188
 
2160
2189
  def generate_quote(core, schema, state, top_schema=None, top_state=None, path=None):
@@ -2279,13 +2308,18 @@ def generate_tree(core, schema, state, top_schema=None, top_state=None, path=Non
2279
2308
  elif key in schema:
2280
2309
  generate_schema[key] = schema[key]
2281
2310
  else:
2282
- 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')
2283
2312
  else:
2284
- generate_schema = schema
2285
- 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)
2286
2319
 
2287
2320
  return generate_schema, generate_state, top_schema, top_state
2288
2321
 
2322
+
2289
2323
  def generate_ports(core, schema, wires, top_schema=None, top_state=None, path=None):
2290
2324
  schema = schema or {}
2291
2325
  wires = wires or {}
@@ -2465,56 +2499,99 @@ def find_union_type(core, schema, state):
2465
2499
  # Each function handles a specific type of schema and ensures that updates are resolved correctly.
2466
2500
 
2467
2501
  def resolve_any(schema, update, core):
2468
- 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
+
2469
2510
  outcome = schema.copy()
2470
2511
 
2471
2512
  for key, subschema in update.items():
2472
2513
  if key == '_type' and key in outcome:
2473
- if outcome[key] != subschema:
2474
- if core.inherits_from(outcome[key], subschema):
2514
+ if schema[key] != subschema:
2515
+ if core.inherits_from(schema[key], subschema):
2475
2516
  continue
2476
- elif core.inherits_from(subschema, outcome[key]):
2517
+ elif core.inherits_from(subschema, schema[key]):
2477
2518
  outcome[key] = subschema
2478
2519
  else:
2479
2520
  raise Exception(f'cannot resolve types when updating\ncurrent type: {schema}\nupdate type: {update}')
2480
2521
 
2481
- elif not key in outcome or type_parameter_key(update, key):
2522
+ elif not key in schema or type_parameter_key(schema, key):
2482
2523
  if subschema:
2483
2524
  outcome[key] = subschema
2484
2525
  else:
2485
2526
  outcome[key] = core.resolve_schemas(
2486
- outcome.get(key),
2527
+ schema.get(key),
2487
2528
  subschema)
2488
2529
 
2489
2530
  return outcome
2490
2531
 
2491
- # def resolve_tree(schema, update, core):
2492
- # if isinstance(update, dict):
2493
- # leaf_schema = schema.get('_leaf', {})
2494
2532
 
2495
- # if '_type' in update:
2496
- # if update['_type'] == 'map':
2497
- # value_schema = update.get('_value', {})
2498
- # leaf_schema = core.resolve_schemas(
2499
- # leaf_schema,
2500
- # 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
2501
2556
 
2502
- # elif update['_type'] == 'tree':
2503
- # for key, subschema in update.items():
2504
- # if not key.startswith('_'):
2505
- # leaf_schema = core.resolve_schemas(
2506
- # leaf_schema,
2507
- # subschema)
2508
- # else:
2509
- # leaf_schema = core.resolve_schemas(
2510
- # leaf_schema,
2511
- # update)
2557
+ raise Exception(f'could not resolve type with union:\n{update}\nunion:\n{schema}')
2512
2558
 
2513
- # schema['_leaf'] = leaf_schema
2514
- # else:
2515
- # for key, subupdate in
2516
2559
 
2517
- # return schema
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)
2583
+
2584
+ # raise Exception(f'cannot resolve types when updating\ncurrent type: {schema}\nupdate type: {update}')
2585
+
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)
2593
+
2594
+ return outcome
2518
2595
 
2519
2596
 
2520
2597
  # ==========================
@@ -2724,7 +2801,7 @@ base_types = {
2724
2801
  '_dataclass': dataclass_tree,
2725
2802
  '_fold': fold_tree,
2726
2803
  '_divide': divide_tree,
2727
- # '_resolve': resolve_tree,
2804
+ '_resolve': resolve_tree,
2728
2805
  '_type_parameters': ['leaf'],
2729
2806
  '_description': 'mapping from str to some type in a potentially nested form'},
2730
2807
 
@@ -2760,7 +2837,7 @@ base_types = {
2760
2837
 
2761
2838
  'path': {
2762
2839
  '_type': 'path',
2763
- '_inherit': 'list[string]',
2840
+ '_inherit': 'list[string~integer]',
2764
2841
  '_apply': apply_path},
2765
2842
 
2766
2843
  'wires': {
@@ -2839,4 +2916,5 @@ registry_types = {
2839
2916
  '_deserialize': deserialize_union,
2840
2917
  '_dataclass': dataclass_union,
2841
2918
  '_fold': fold_union,
2919
+ '_resolve': resolve_union,
2842
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):
@@ -963,6 +967,9 @@ class TypeSystem(Registry):
963
967
 
964
968
 
965
969
  def resolve_schemas(self, initial_current, initial_update):
970
+ if initial_current == initial_update:
971
+ return initial_current
972
+
966
973
  current = self.access(initial_current)
967
974
  update = self.access(initial_update)
968
975
 
@@ -976,7 +983,7 @@ class TypeSystem(Registry):
976
983
  outcome = update
977
984
 
978
985
  elif '_type' in current and '_type' in update and current['_type'] == update['_type']:
979
- outcome = current.copy()
986
+ outcome = {}
980
987
 
981
988
  for key in update:
982
989
  if key == '_type_parameters' and '_type_parameters' in current:
@@ -984,23 +991,27 @@ class TypeSystem(Registry):
984
991
  parameter_key = f'_{parameter}'
985
992
  if parameter in current['_type_parameters']:
986
993
  if parameter_key in current:
987
- outcome[parameter_key] = self.resolve_schemas(
988
- current[parameter_key],
989
- 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]
990
1000
  elif parameter_key in update:
991
1001
  outcome[parameter_key] = update[parameter_key]
992
- # else:
993
- # outcome[parameter_key] = {}
994
1002
  else:
995
1003
  outcome[parameter_key] = update[parameter_key]
996
- elif key not in outcome or type_parameter_key(current, key):
997
- key_update = update[key]
998
- if key_update:
999
- outcome[key] = key_update
1000
- 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]:
1001
1010
  outcome[key] = self.resolve_schemas(
1002
- outcome.get(key),
1011
+ current[key],
1003
1012
  update[key])
1013
+ else:
1014
+ outcome[key] = update[key]
1004
1015
 
1005
1016
  elif '_type' in update and '_type' not in current:
1006
1017
  outcome = self.resolve(update, current)
@@ -1008,26 +1019,6 @@ class TypeSystem(Registry):
1008
1019
  else:
1009
1020
  outcome = self.resolve(current, update)
1010
1021
 
1011
- # elif '_type' in current:
1012
- # outcome = self.resolve(current, update)
1013
-
1014
- # elif '_type' in update:
1015
- # outcome = self.resolve(update, current)
1016
-
1017
- # else:
1018
- # outcome = self.resolve(current, update)
1019
- # outcome = current.copy()
1020
-
1021
- # for key in update:
1022
- # if not key in outcome or is_schema_key(update, key):
1023
- # key_update = update[key]
1024
- # if key_update:
1025
- # outcome[key] = key_update
1026
- # else:
1027
- # outcome[key] = self.resolve_schemas(
1028
- # outcome.get(key),
1029
- # update[key])
1030
-
1031
1022
  return outcome
1032
1023
 
1033
1024
 
@@ -1316,7 +1307,6 @@ class TypeSystem(Registry):
1316
1307
 
1317
1308
 
1318
1309
  def set_slice(self, schema, state, path, target_schema, target_state, defer=False):
1319
-
1320
1310
  '''
1321
1311
  Makes a local modification to the schema/state at the path, and
1322
1312
  returns the top_schema and top_state
@@ -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,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: bigraph-schema
3
- Version: 0.0.56
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,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.56'
4
+ VERSION = '0.0.57'
5
5
 
6
6
 
7
7
  with open("README.md", "r") as readme:
File without changes