bigraph-schema 0.0.59__tar.gz → 0.0.62__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.59 → bigraph-schema-0.0.62}/.gitignore +4 -1
- {bigraph-schema-0.0.59/bigraph_schema.egg-info → bigraph-schema-0.0.62}/PKG-INFO +1 -1
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/bigraph_schema/__init__.py +3 -1
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/bigraph_schema/registry.py +43 -28
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/bigraph_schema/tests.py +184 -117
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/bigraph_schema/type_functions.py +702 -243
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/bigraph_schema/type_system.py +399 -757
- bigraph-schema-0.0.62/bigraph_schema/type_system_adjunct.py +502 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/bigraph_schema/utilities.py +21 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62/bigraph_schema.egg-info}/PKG-INFO +1 -1
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/bigraph_schema.egg-info/SOURCES.txt +2 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/bigraph_schema.egg-info/requires.txt +4 -2
- bigraph-schema-0.0.62/pyproject.toml +19 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/setup.py +1 -1
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/.github/workflows/notebook_to_html.yml +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/.github/workflows/pytest.yml +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/AUTHORS.md +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/CLA.md +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/CODE_OF_CONDUCT.md +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/CONTRIBUTING.md +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/LICENSE +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/README.md +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/bigraph_schema/edge.py +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/bigraph_schema/parse.py +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/bigraph_schema/protocols.py +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/bigraph_schema/units.py +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/bigraph_schema.egg-info/dependency_links.txt +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/bigraph_schema.egg-info/top_level.txt +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/notebooks/core.ipynb +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/notebooks/demo.ipynb +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/notebooks/images/place-link.png +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/notebooks/images/reaction-after.png +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/notebooks/images/reaction-before.png +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/notebooks/images/redex-reactum.png +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/pytest.ini +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/release.sh +0 -0
- {bigraph-schema-0.0.59 → bigraph-schema-0.0.62}/setup.cfg +0 -0
|
@@ -3,4 +3,6 @@ from bigraph_schema.registry import (
|
|
|
3
3
|
strip_schema_keys, type_parameter_key, non_schema_keys, set_path, transform_path)
|
|
4
4
|
from bigraph_schema.utilities import get_path, visit_method
|
|
5
5
|
from bigraph_schema.edge import Edge
|
|
6
|
-
from bigraph_schema.type_system import TypeSystem
|
|
6
|
+
from bigraph_schema.type_system import TypeSystem
|
|
7
|
+
from bigraph_schema.protocols import local_lookup_module
|
|
8
|
+
from bigraph_schema.type_functions import FUNCTION_TYPE, METHOD_TYPE, type_schema_keys, resolve_path
|
|
@@ -23,10 +23,13 @@ def deep_merge_copy(dct, merge_dct):
|
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
def deep_merge(dct, merge_dct):
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
"""
|
|
27
|
+
Recursive dict merge
|
|
28
|
+
|
|
29
|
+
This mutates dct - the contents of merge_dct are added to dct (which is
|
|
30
|
+
also returned).
|
|
31
|
+
|
|
32
|
+
If you want to keep dct you could use deep_merge_copy
|
|
30
33
|
"""
|
|
31
34
|
if dct is None:
|
|
32
35
|
dct = {}
|
|
@@ -45,10 +48,14 @@ def deep_merge(dct, merge_dct):
|
|
|
45
48
|
|
|
46
49
|
|
|
47
50
|
def validate_merge(state, dct, merge_dct):
|
|
48
|
-
"""
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
"""
|
|
52
|
+
Recursive dict merge
|
|
53
|
+
|
|
54
|
+
This mutates dct - the contents of merge_dct are added to dct (which is
|
|
55
|
+
also returned).
|
|
56
|
+
|
|
57
|
+
If you want to keep dct you could call it like
|
|
58
|
+
deep_merge(copy.deepcopy(dct), merge_dct)
|
|
52
59
|
"""
|
|
53
60
|
dct = dct or {}
|
|
54
61
|
merge_dct = merge_dct or {}
|
|
@@ -77,16 +84,16 @@ def validate_merge(state, dct, merge_dct):
|
|
|
77
84
|
|
|
78
85
|
def establish_path(tree, path, top=None, cursor=()):
|
|
79
86
|
"""
|
|
80
|
-
Given a tree and a path in the tree that may or may not yet exist,
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
87
|
+
Given a tree and a path in the tree that may or may not yet exist, add
|
|
88
|
+
nodes along the path and return the final node which is now at the given
|
|
89
|
+
path.
|
|
90
|
+
|
|
84
91
|
Args:
|
|
85
92
|
- tree: the tree we are establishing a path in
|
|
86
93
|
- path: where the new subtree will be located in the tree
|
|
87
94
|
- top: (None) a reference to the top of the tree
|
|
88
95
|
- cursor: (()) the current location we are visiting in the tree
|
|
89
|
-
|
|
96
|
+
|
|
90
97
|
Returns:
|
|
91
98
|
- node: the new node of the tree that exists at the given path
|
|
92
99
|
"""
|
|
@@ -127,14 +134,14 @@ def set_path(tree, path, value, top=None, cursor=None):
|
|
|
127
134
|
"""
|
|
128
135
|
Given a tree, a path, and a value, sets the location
|
|
129
136
|
in the tree corresponding to the path to the given value
|
|
130
|
-
|
|
137
|
+
|
|
131
138
|
Args:
|
|
132
139
|
- tree: the tree we are setting a value in
|
|
133
140
|
- path: where the new value will be located in the tree
|
|
134
141
|
- value: the value to set at the given path in the tree
|
|
135
142
|
- top: (None) a reference to the top of the tree
|
|
136
143
|
- cursor: (()) the current location we are visiting in the tree
|
|
137
|
-
|
|
144
|
+
|
|
138
145
|
Returns:
|
|
139
146
|
- node: the new node of the tree that exists at the given path
|
|
140
147
|
"""
|
|
@@ -199,14 +206,16 @@ def set_star_path(tree, path, value, top=None, cursor=()):
|
|
|
199
206
|
|
|
200
207
|
def transform_path(tree, path, transform):
|
|
201
208
|
"""
|
|
202
|
-
Given a tree, a path, and a transform (function), mutate the tree by
|
|
203
|
-
|
|
204
|
-
|
|
209
|
+
Given a tree, a path, and a transform (function), mutate the tree by
|
|
210
|
+
replacing the subtree at the path by whatever is returned from applying the
|
|
211
|
+
transform to the existing value.
|
|
212
|
+
|
|
205
213
|
Args:
|
|
206
214
|
- tree: the tree we are setting a value in
|
|
207
215
|
- path: where the new value will be located in the tree
|
|
208
|
-
- transform: the function to apply to whatever currently lives at the given
|
|
209
|
-
|
|
216
|
+
- transform: the function to apply to whatever currently lives at the given
|
|
217
|
+
path in the tree
|
|
218
|
+
|
|
210
219
|
Returns:
|
|
211
220
|
- node: the node of the tree that exists at the given path
|
|
212
221
|
"""
|
|
@@ -278,7 +287,9 @@ def non_schema_keys(schema):
|
|
|
278
287
|
|
|
279
288
|
|
|
280
289
|
def strip_schema_keys(state):
|
|
281
|
-
"""
|
|
290
|
+
"""
|
|
291
|
+
remove schema keys from a state dictionary, including nested dictionaries
|
|
292
|
+
"""
|
|
282
293
|
if isinstance(state, dict):
|
|
283
294
|
output = {}
|
|
284
295
|
for key, value in state.items():
|
|
@@ -300,7 +311,9 @@ def default(type, default):
|
|
|
300
311
|
|
|
301
312
|
|
|
302
313
|
class Registry(object):
|
|
303
|
-
"""
|
|
314
|
+
"""
|
|
315
|
+
A Registry holds a collection of functions or objects
|
|
316
|
+
"""
|
|
304
317
|
|
|
305
318
|
def __init__(self, function_keys=None):
|
|
306
319
|
function_keys = function_keys or []
|
|
@@ -315,10 +328,12 @@ class Registry(object):
|
|
|
315
328
|
Args:
|
|
316
329
|
- key: Item key.
|
|
317
330
|
- item: The item to add.
|
|
318
|
-
- alternate_keys: Additional keys under which to register the item.
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
331
|
+
- alternate_keys: Additional keys under which to register the item.
|
|
332
|
+
These keys will not be included in the list returned by
|
|
333
|
+
``Registry.list()``. This may be useful if you want to be able to
|
|
334
|
+
look up an item in the registry under multiple keys.
|
|
335
|
+
- strict (bool): Disallow re-registration, overriding existing keys.
|
|
336
|
+
False by default.
|
|
322
337
|
"""
|
|
323
338
|
|
|
324
339
|
# check that registered function have the required function keys
|
|
@@ -367,7 +382,7 @@ class Registry(object):
|
|
|
367
382
|
elif inspect.isfunction(function):
|
|
368
383
|
found = function
|
|
369
384
|
module_key = function_module(found)
|
|
370
|
-
|
|
385
|
+
|
|
371
386
|
function_name = module_key.split('.')[-1]
|
|
372
387
|
self.register(function_name, found)
|
|
373
388
|
self.register(module_key, found)
|
|
@@ -381,7 +396,7 @@ class Registry(object):
|
|
|
381
396
|
|
|
382
397
|
def find(self, key):
|
|
383
398
|
return self.registry.get(key)
|
|
384
|
-
|
|
399
|
+
|
|
385
400
|
|
|
386
401
|
def access(self, key):
|
|
387
402
|
"""
|
|
@@ -7,10 +7,11 @@ import pprint
|
|
|
7
7
|
import numpy as np
|
|
8
8
|
from dataclasses import asdict
|
|
9
9
|
|
|
10
|
+
from bigraph_schema import local_lookup_module, TypeSystem
|
|
10
11
|
from bigraph_schema.type_functions import (
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
from bigraph_schema import
|
|
12
|
+
accumulate, base_types, data_module, deserialize_integer,
|
|
13
|
+
divide_longest, to_string)
|
|
14
|
+
from bigraph_schema.utilities import compare_dicts, NONE_SYMBOL, state_instance
|
|
14
15
|
from bigraph_schema.units import units
|
|
15
16
|
from bigraph_schema.registry import establish_path, remove_omitted
|
|
16
17
|
|
|
@@ -21,7 +22,30 @@ def core():
|
|
|
21
22
|
return register_test_types(core)
|
|
22
23
|
|
|
23
24
|
|
|
25
|
+
def register_test_types(core):
|
|
26
|
+
"""
|
|
27
|
+
defines the test schemas
|
|
28
|
+
"""
|
|
29
|
+
register_cube(core)
|
|
30
|
+
|
|
31
|
+
core.register('compartment', {
|
|
32
|
+
'counts': 'tree[float]',
|
|
33
|
+
'inner': 'tree[compartment]'})
|
|
34
|
+
|
|
35
|
+
core.register('metaedge', {
|
|
36
|
+
'_inherit': 'edge',
|
|
37
|
+
'_inputs': {
|
|
38
|
+
'before': 'metaedge'},
|
|
39
|
+
'_outputs': {
|
|
40
|
+
'after': 'metaedge'}})
|
|
41
|
+
|
|
42
|
+
return core
|
|
43
|
+
|
|
44
|
+
|
|
24
45
|
def register_cube(core):
|
|
46
|
+
"""
|
|
47
|
+
adds an additional simple schema for the test fixture
|
|
48
|
+
"""
|
|
25
49
|
cube_schema = {
|
|
26
50
|
'shape': {
|
|
27
51
|
'_type': 'shape',
|
|
@@ -50,24 +74,24 @@ def register_cube(core):
|
|
|
50
74
|
return core
|
|
51
75
|
|
|
52
76
|
|
|
53
|
-
def
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
core.register('compartment', {
|
|
57
|
-
'counts': 'tree[float]',
|
|
58
|
-
'inner': 'tree[compartment]'})
|
|
77
|
+
def test_basic_types(core):
|
|
78
|
+
assert core.find('integer')
|
|
79
|
+
assert core.find('cube')['depth']['_type'] == 'integer'
|
|
59
80
|
|
|
60
|
-
core.register('metaedge', {
|
|
61
|
-
'_inherit': 'edge',
|
|
62
|
-
'_inputs': {
|
|
63
|
-
'before': 'metaedge'},
|
|
64
|
-
'_outputs': {
|
|
65
|
-
'after': 'metaedge'}})
|
|
66
81
|
|
|
67
|
-
|
|
82
|
+
def test_update_types(core):
|
|
83
|
+
core.update_types({'A': "payload"})
|
|
84
|
+
desc = "a placeholder type with no structure"
|
|
85
|
+
core.update_types({'A': {'_description':desc}})
|
|
86
|
+
assert core.access('A') == {'_type': 'payload', '_description': desc}
|
|
68
87
|
|
|
69
88
|
|
|
70
89
|
def test_reregister_type(core):
|
|
90
|
+
"""
|
|
91
|
+
register raises an exception if replacing a schema with strict
|
|
92
|
+
|
|
93
|
+
it replaces the schema if not strict
|
|
94
|
+
"""
|
|
71
95
|
core.register('A', {'_default': 'a'})
|
|
72
96
|
with pytest.raises(Exception) as e:
|
|
73
97
|
core.register(
|
|
@@ -79,6 +103,18 @@ def test_reregister_type(core):
|
|
|
79
103
|
assert core.access('A')['_default'] == 'b'
|
|
80
104
|
|
|
81
105
|
|
|
106
|
+
def test_merge_schemas(core):
|
|
107
|
+
a = {'foo': {'bar': [1],
|
|
108
|
+
'baz': [2]}}
|
|
109
|
+
b = {'foo': {'bar': 3},
|
|
110
|
+
'baz': 12}
|
|
111
|
+
|
|
112
|
+
assert core.merge_schemas(a, b) == \
|
|
113
|
+
{'foo': {'bar': 3,
|
|
114
|
+
'baz': [2]},
|
|
115
|
+
'baz': 12}
|
|
116
|
+
|
|
117
|
+
|
|
82
118
|
def test_generate_default(core):
|
|
83
119
|
int_default = core.default(
|
|
84
120
|
{'_type': 'integer'}
|
|
@@ -126,6 +162,15 @@ def test_apply_update(core):
|
|
|
126
162
|
|
|
127
163
|
|
|
128
164
|
def print_schema_validation(core, library, should_pass):
|
|
165
|
+
"""
|
|
166
|
+
validate_schema returns nothing for a valid schema declaration
|
|
167
|
+
|
|
168
|
+
this helper function makes clearer reports out of the test
|
|
169
|
+
failures
|
|
170
|
+
|
|
171
|
+
this is also why running the file outside pytest prints out
|
|
172
|
+
a huge wall of text
|
|
173
|
+
"""
|
|
129
174
|
for key, declaration in library.items():
|
|
130
175
|
report = core.validate_schema(declaration)
|
|
131
176
|
if len(report) == 0:
|
|
@@ -605,7 +650,8 @@ def test_link_place(core):
|
|
|
605
650
|
|
|
606
651
|
def test_units(core):
|
|
607
652
|
schema_length = {
|
|
608
|
-
'distance': {
|
|
653
|
+
'distance': {
|
|
654
|
+
'_type': 'length'}}
|
|
609
655
|
|
|
610
656
|
state = {'distance': 11 * units.meter}
|
|
611
657
|
update = {'distance': -5 * units.feet}
|
|
@@ -838,7 +884,7 @@ def test_inherits_from(core):
|
|
|
838
884
|
|
|
839
885
|
assert core.inherits_from(
|
|
840
886
|
'tree[path]',
|
|
841
|
-
'tree[list[
|
|
887
|
+
'tree[list[mark]]')
|
|
842
888
|
|
|
843
889
|
assert not core.inherits_from(
|
|
844
890
|
'tree[path]',
|
|
@@ -1229,6 +1275,29 @@ def test_reaction(core):
|
|
|
1229
1275
|
{'id': 'daughter2', 'ratio': 0.7}]}}}
|
|
1230
1276
|
|
|
1231
1277
|
|
|
1278
|
+
def A(a):
|
|
1279
|
+
return a * 5
|
|
1280
|
+
|
|
1281
|
+
def B(b):
|
|
1282
|
+
return b + 11
|
|
1283
|
+
|
|
1284
|
+
def test_function_type(core):
|
|
1285
|
+
A_serialized = core.serialize(
|
|
1286
|
+
'function',
|
|
1287
|
+
A)
|
|
1288
|
+
|
|
1289
|
+
A_deserialized = core.deserialize(
|
|
1290
|
+
'function',
|
|
1291
|
+
A_serialized)
|
|
1292
|
+
|
|
1293
|
+
C = core.apply(
|
|
1294
|
+
'function',
|
|
1295
|
+
A_deserialized,
|
|
1296
|
+
B)
|
|
1297
|
+
|
|
1298
|
+
assert C(6) == 41
|
|
1299
|
+
|
|
1300
|
+
|
|
1232
1301
|
def test_map_type(core):
|
|
1233
1302
|
schema = 'map[integer]'
|
|
1234
1303
|
|
|
@@ -1345,106 +1414,108 @@ def test_maybe_type(core):
|
|
|
1345
1414
|
|
|
1346
1415
|
|
|
1347
1416
|
def test_tuple_type(core):
|
|
1348
|
-
|
|
1417
|
+
schemas = [{
|
|
1349
1418
|
'_type': 'tuple',
|
|
1350
1419
|
'_type_parameters': ['0', '1', '2'],
|
|
1351
1420
|
'_0': 'string',
|
|
1352
|
-
'_1': '
|
|
1353
|
-
'_2': 'map[maybe[float]]'}
|
|
1421
|
+
'_1': 'integer',
|
|
1422
|
+
'_2': 'map[maybe[float]]'},
|
|
1354
1423
|
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1424
|
+
('string', 'integer', 'map[maybe[float]]'),
|
|
1425
|
+
'tuple[string,integer,map[maybe[float]]]',
|
|
1426
|
+
'string|integer|map[maybe[float]]']
|
|
1358
1427
|
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1428
|
+
for schema in schemas:
|
|
1429
|
+
state = (
|
|
1430
|
+
'aaaaa',
|
|
1431
|
+
13, {
|
|
1432
|
+
'a': 1.1,
|
|
1433
|
+
'b': None})
|
|
1364
1434
|
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1435
|
+
update = (
|
|
1436
|
+
'bbbbbb',
|
|
1437
|
+
10, {
|
|
1438
|
+
'a': 33.33,
|
|
1439
|
+
'b': 4.44444})
|
|
1370
1440
|
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1441
|
+
assert core.check(schema, state)
|
|
1442
|
+
assert core.check(schema, update)
|
|
1443
|
+
assert not core.check(schema, 15)
|
|
1374
1444
|
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1445
|
+
result = core.apply(
|
|
1446
|
+
schema,
|
|
1447
|
+
state,
|
|
1448
|
+
update)
|
|
1379
1449
|
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1450
|
+
assert len(result) == 3
|
|
1451
|
+
assert result[0] == update[0]
|
|
1452
|
+
assert result[1] == 23
|
|
1453
|
+
assert result[2]['a'] == 34.43
|
|
1454
|
+
assert result[2]['b'] == update[2]['b']
|
|
1385
1455
|
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1456
|
+
encode = core.serialize(schema, state)
|
|
1457
|
+
assert encode[2]['b'] == NONE_SYMBOL
|
|
1458
|
+
assert encode[1] == '13'
|
|
1389
1459
|
|
|
1390
|
-
|
|
1391
|
-
|
|
1460
|
+
decode = core.deserialize(schema, encode)
|
|
1461
|
+
assert decode == state
|
|
1392
1462
|
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1463
|
+
tuple_type = core.access('(3|4|10)')
|
|
1464
|
+
assert '_2' in tuple_type
|
|
1465
|
+
assert tuple_type['_2'] == '10'
|
|
1396
1466
|
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1467
|
+
tuple_type = core.access('tuple[9,float,7]')
|
|
1468
|
+
assert '_2' in tuple_type
|
|
1469
|
+
assert tuple_type['_2'] == '7'
|
|
1400
1470
|
|
|
1401
1471
|
|
|
1402
1472
|
def test_union_type(core):
|
|
1403
|
-
|
|
1473
|
+
schemas = [{
|
|
1404
1474
|
'_type': 'union',
|
|
1405
1475
|
'_type_parameters': ['0', '1', '2'],
|
|
1406
1476
|
'_0': 'string',
|
|
1407
1477
|
'_1': 'integer',
|
|
1408
|
-
'_2': 'map[maybe[float]]'}
|
|
1478
|
+
'_2': 'map[maybe[float]]'},
|
|
1409
1479
|
|
|
1410
|
-
|
|
1480
|
+
'string~integer~map[maybe[float]]']
|
|
1411
1481
|
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1482
|
+
for schema in schemas:
|
|
1483
|
+
state = {
|
|
1484
|
+
'a': 1.1,
|
|
1485
|
+
'b': None}
|
|
1415
1486
|
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1487
|
+
update = {
|
|
1488
|
+
'a': 33.33,
|
|
1489
|
+
'b': 4.44444}
|
|
1419
1490
|
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1491
|
+
assert core.check(schema, state)
|
|
1492
|
+
assert core.check(schema, update)
|
|
1493
|
+
assert core.check(schema, 15)
|
|
1423
1494
|
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1495
|
+
wrong_state = {
|
|
1496
|
+
'a': 1.1,
|
|
1497
|
+
'b': None}
|
|
1427
1498
|
|
|
1428
|
-
|
|
1499
|
+
wrong_update = 'a different type'
|
|
1429
1500
|
|
|
1430
|
-
|
|
1431
|
-
|
|
1501
|
+
assert core.check(schema, wrong_state)
|
|
1502
|
+
assert core.check(schema, wrong_update)
|
|
1432
1503
|
|
|
1433
|
-
|
|
1504
|
+
# TODO: deal with union apply of different types
|
|
1434
1505
|
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1506
|
+
result = core.apply(
|
|
1507
|
+
schema,
|
|
1508
|
+
state,
|
|
1509
|
+
update)
|
|
1439
1510
|
|
|
1440
|
-
|
|
1441
|
-
|
|
1511
|
+
assert result['a'] == 34.43
|
|
1512
|
+
assert result['b'] == update['b']
|
|
1442
1513
|
|
|
1443
|
-
|
|
1444
|
-
|
|
1514
|
+
encode = core.serialize(schema, state)
|
|
1515
|
+
assert encode['b'] == NONE_SYMBOL
|
|
1445
1516
|
|
|
1446
|
-
|
|
1447
|
-
|
|
1517
|
+
decode = core.deserialize(schema, encode)
|
|
1518
|
+
assert decode == state
|
|
1448
1519
|
|
|
1449
1520
|
|
|
1450
1521
|
def test_union_values(core):
|
|
@@ -1969,27 +2040,6 @@ def test_set_slice(core):
|
|
|
1969
2040
|
1])[1] == 33
|
|
1970
2041
|
|
|
1971
2042
|
|
|
1972
|
-
def from_state(dataclass, state):
|
|
1973
|
-
if hasattr(dataclass, '__dataclass_fields__'):
|
|
1974
|
-
fields = dataclass.__dataclass_fields__
|
|
1975
|
-
state = state or {}
|
|
1976
|
-
|
|
1977
|
-
init = {}
|
|
1978
|
-
for key, field in fields.items():
|
|
1979
|
-
substate = from_state(
|
|
1980
|
-
field.type,
|
|
1981
|
-
state.get(key))
|
|
1982
|
-
init[key] = substate
|
|
1983
|
-
instance = dataclass(**init)
|
|
1984
|
-
# elif get_origin(dataclass) in [typing.Union, typing.Mapping]:
|
|
1985
|
-
# instance = state
|
|
1986
|
-
else:
|
|
1987
|
-
instance = state
|
|
1988
|
-
# instance = dataclass(state)
|
|
1989
|
-
|
|
1990
|
-
return instance
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
2043
|
def test_dataclass(core):
|
|
1994
2044
|
simple_schema = {
|
|
1995
2045
|
'a': 'float',
|
|
@@ -2000,7 +2050,7 @@ def test_dataclass(core):
|
|
|
2000
2050
|
# TODO: accept just a string instead of only a path
|
|
2001
2051
|
simple_dataclass = core.dataclass(
|
|
2002
2052
|
simple_schema,
|
|
2003
|
-
|
|
2053
|
+
'simple')
|
|
2004
2054
|
|
|
2005
2055
|
simple_state = {
|
|
2006
2056
|
'a': 88.888,
|
|
@@ -2014,10 +2064,14 @@ def test_dataclass(core):
|
|
|
2014
2064
|
c=True,
|
|
2015
2065
|
x='what')
|
|
2016
2066
|
|
|
2017
|
-
simple_from =
|
|
2067
|
+
simple_from = state_instance(
|
|
2018
2068
|
simple_dataclass,
|
|
2019
2069
|
simple_state)
|
|
2020
2070
|
|
|
2071
|
+
default_simple = core.default_instance(
|
|
2072
|
+
simple_schema,
|
|
2073
|
+
'simple_default')
|
|
2074
|
+
|
|
2021
2075
|
nested_schema = {
|
|
2022
2076
|
'a': {
|
|
2023
2077
|
'a': {
|
|
@@ -2027,7 +2081,7 @@ def test_dataclass(core):
|
|
|
2027
2081
|
|
|
2028
2082
|
nested_dataclass = core.dataclass(
|
|
2029
2083
|
nested_schema,
|
|
2030
|
-
|
|
2084
|
+
'nested')
|
|
2031
2085
|
|
|
2032
2086
|
nested_state = {
|
|
2033
2087
|
'a': {
|
|
@@ -2043,7 +2097,7 @@ def test_dataclass(core):
|
|
|
2043
2097
|
b=3.3333),
|
|
2044
2098
|
5555.55))
|
|
2045
2099
|
|
|
2046
|
-
nested_from =
|
|
2100
|
+
nested_from = state_instance(
|
|
2047
2101
|
nested_dataclass,
|
|
2048
2102
|
nested_state)
|
|
2049
2103
|
|
|
@@ -2056,7 +2110,7 @@ def test_dataclass(core):
|
|
|
2056
2110
|
|
|
2057
2111
|
complex_dataclass = core.dataclass(
|
|
2058
2112
|
complex_schema,
|
|
2059
|
-
|
|
2113
|
+
'complex')
|
|
2060
2114
|
|
|
2061
2115
|
complex_state = {
|
|
2062
2116
|
'a': {
|
|
@@ -2080,7 +2134,7 @@ def test_dataclass(core):
|
|
|
2080
2134
|
'OOO': ['..', '..', 'a', 'w']}}},
|
|
2081
2135
|
'e': np.zeros((3, 4, 10))}}
|
|
2082
2136
|
|
|
2083
|
-
complex_from =
|
|
2137
|
+
complex_from = state_instance(
|
|
2084
2138
|
complex_dataclass,
|
|
2085
2139
|
complex_state)
|
|
2086
2140
|
|
|
@@ -2098,6 +2152,7 @@ def test_enum_type(core):
|
|
|
2098
2152
|
'planet',
|
|
2099
2153
|
'enum[mercury,venus,earth,mars,jupiter,saturn,neptune]')
|
|
2100
2154
|
|
|
2155
|
+
# this is equivalent to the above (TODO: test this)
|
|
2101
2156
|
# core.register('planet', {
|
|
2102
2157
|
# '_type': 'enum',
|
|
2103
2158
|
# '_type_parameters': ['0', '1', '2', '3', '4', '5', '6'],
|
|
@@ -2224,8 +2279,8 @@ def test_generate(core):
|
|
|
2224
2279
|
'_type': 'enum[x,y,z]',
|
|
2225
2280
|
'_default': 'y'},
|
|
2226
2281
|
'units': {
|
|
2227
|
-
'
|
|
2228
|
-
'
|
|
2282
|
+
'meters': 11.1111,
|
|
2283
|
+
'seconds': 22.833333}}
|
|
2229
2284
|
|
|
2230
2285
|
generated_schema, generated_state = core.generate(
|
|
2231
2286
|
schema,
|
|
@@ -2234,8 +2289,8 @@ def test_generate(core):
|
|
|
2234
2289
|
assert generated_state['A'] == 0.0
|
|
2235
2290
|
assert generated_state['B'] == 'one'
|
|
2236
2291
|
assert generated_state['C'] == 'y'
|
|
2237
|
-
assert generated_state['units']['
|
|
2238
|
-
assert '
|
|
2292
|
+
assert generated_state['units']['seconds'] == 22.833333
|
|
2293
|
+
assert 'meters' not in generated_schema['units']
|
|
2239
2294
|
|
|
2240
2295
|
|
|
2241
2296
|
def test_edge_cycle(core):
|
|
@@ -2359,6 +2414,14 @@ def test_union_key_error(core):
|
|
|
2359
2414
|
result = generate_method(core, schema, state)
|
|
2360
2415
|
|
|
2361
2416
|
|
|
2417
|
+
def test_update_removed(core):
|
|
2418
|
+
schema = 'map[float]'
|
|
2419
|
+
state = {
|
|
2420
|
+
'a': 11.11,
|
|
2421
|
+
'b': 12.2222,
|
|
2422
|
+
'c': 13.33333333}
|
|
2423
|
+
|
|
2424
|
+
|
|
2362
2425
|
def fix_test_slice_edge(core):
|
|
2363
2426
|
initial_schema = {
|
|
2364
2427
|
'edge': {
|
|
@@ -2481,6 +2544,7 @@ if __name__ == '__main__':
|
|
|
2481
2544
|
core = TypeSystem()
|
|
2482
2545
|
core = register_test_types(core)
|
|
2483
2546
|
|
|
2547
|
+
test_basic_types(core)
|
|
2484
2548
|
test_reregister_type(core)
|
|
2485
2549
|
test_generate_default(core)
|
|
2486
2550
|
test_apply_update(core)
|
|
@@ -2508,6 +2572,7 @@ if __name__ == '__main__':
|
|
|
2508
2572
|
test_maybe_type(core)
|
|
2509
2573
|
test_tuple_type(core)
|
|
2510
2574
|
test_array_type(core)
|
|
2575
|
+
test_function_type(core)
|
|
2511
2576
|
test_union_type(core)
|
|
2512
2577
|
test_union_values(core)
|
|
2513
2578
|
test_infer_edge(core)
|
|
@@ -2530,6 +2595,8 @@ if __name__ == '__main__':
|
|
|
2530
2595
|
test_union_key_error(core)
|
|
2531
2596
|
test_tree_equivalence(core)
|
|
2532
2597
|
test_star_view_project(core)
|
|
2598
|
+
test_update_removed(core)
|
|
2599
|
+
test_merge_schemas(core)
|
|
2533
2600
|
|
|
2534
2601
|
# test_slice_edge(core)
|
|
2535
2602
|
# test_complex_wiring(core)
|