bigraph-schema 1.0.0__py3-none-any.whl
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.
- bigraph_schema/__init__.py +112 -0
- bigraph_schema/core.py +759 -0
- bigraph_schema/edge.py +138 -0
- bigraph_schema/methods/__init__.py +12 -0
- bigraph_schema/methods/apply.py +276 -0
- bigraph_schema/methods/check.py +213 -0
- bigraph_schema/methods/default.py +204 -0
- bigraph_schema/methods/generalize.py +309 -0
- bigraph_schema/methods/handle_parameters.py +182 -0
- bigraph_schema/methods/infer.py +217 -0
- bigraph_schema/methods/jump.py +432 -0
- bigraph_schema/methods/merge.py +405 -0
- bigraph_schema/methods/realize.py +527 -0
- bigraph_schema/methods/resolve.py +692 -0
- bigraph_schema/methods/serialize.py +491 -0
- bigraph_schema/methods/validate.py +249 -0
- bigraph_schema/package/__init__.py +1 -0
- bigraph_schema/package/discover.py +122 -0
- bigraph_schema/parse.py +183 -0
- bigraph_schema/protocols.py +57 -0
- bigraph_schema/schema.py +370 -0
- bigraph_schema/units.py +133 -0
- bigraph_schema-1.0.0.dist-info/METADATA +66 -0
- bigraph_schema-1.0.0.dist-info/RECORD +28 -0
- bigraph_schema-1.0.0.dist-info/WHEEL +5 -0
- bigraph_schema-1.0.0.dist-info/licenses/AUTHORS.md +6 -0
- bigraph_schema-1.0.0.dist-info/licenses/LICENSE +201 -0
- bigraph_schema-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
from ast import literal_eval
|
|
2
|
+
from pprint import pformat as pf
|
|
3
|
+
from plum import dispatch
|
|
4
|
+
import numpy as np
|
|
5
|
+
from numpy.random.mtrand import RandomState
|
|
6
|
+
from dataclasses import replace
|
|
7
|
+
|
|
8
|
+
from bigraph_schema.protocols import local_lookup
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
from bigraph_schema.schema import (
|
|
12
|
+
Node,
|
|
13
|
+
Empty,
|
|
14
|
+
NONE_SYMBOL,
|
|
15
|
+
Union,
|
|
16
|
+
Tuple,
|
|
17
|
+
Boolean,
|
|
18
|
+
Number,
|
|
19
|
+
Integer,
|
|
20
|
+
Float,
|
|
21
|
+
Delta,
|
|
22
|
+
Nonnegative,
|
|
23
|
+
NPRandom,
|
|
24
|
+
String,
|
|
25
|
+
Enum,
|
|
26
|
+
Wrap,
|
|
27
|
+
Maybe,
|
|
28
|
+
Overwrite,
|
|
29
|
+
List,
|
|
30
|
+
Map,
|
|
31
|
+
Tree,
|
|
32
|
+
Array,
|
|
33
|
+
Key,
|
|
34
|
+
Path,
|
|
35
|
+
Wires,
|
|
36
|
+
Protocol,
|
|
37
|
+
LocalProtocol,
|
|
38
|
+
Schema,
|
|
39
|
+
Link,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
from bigraph_schema.methods.serialize import render
|
|
44
|
+
from bigraph_schema.methods.default import default
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@dispatch
|
|
48
|
+
def realize(core, schema: Empty, encode, path=()):
|
|
49
|
+
return schema, encode, []
|
|
50
|
+
|
|
51
|
+
@dispatch
|
|
52
|
+
def realize(core, schema: Maybe, encode, path=()):
|
|
53
|
+
if encode is not None and encode != NONE_SYMBOL:
|
|
54
|
+
return realize(core, schema._value, encode)
|
|
55
|
+
else:
|
|
56
|
+
return schema, encode, []
|
|
57
|
+
|
|
58
|
+
@dispatch
|
|
59
|
+
def realize(core, schema: Wrap, encode, path=()):
|
|
60
|
+
return realize(core, schema._value, encode)
|
|
61
|
+
|
|
62
|
+
@dispatch
|
|
63
|
+
def realize(core, schema: Union, encode, path=()):
|
|
64
|
+
for option in schema._options:
|
|
65
|
+
decode_schema, decode_state, merges = realize(core, option, encode)
|
|
66
|
+
if decode_state is not None:
|
|
67
|
+
return decode_schema, decode_state, merges
|
|
68
|
+
return schema, None, []
|
|
69
|
+
|
|
70
|
+
@dispatch
|
|
71
|
+
def realize(core, schema: Tuple, encode, path=()):
|
|
72
|
+
merges = []
|
|
73
|
+
|
|
74
|
+
if isinstance(encode, str):
|
|
75
|
+
encode = literal_eval(encode)
|
|
76
|
+
|
|
77
|
+
if isinstance(encode, (list, tuple)):
|
|
78
|
+
subvalues = []
|
|
79
|
+
subtuple = []
|
|
80
|
+
for value, code, index in zip(schema._values, encode, range(len(encode))):
|
|
81
|
+
subvalue, subcode, submerges = realize(core, value, code, path+(index,))
|
|
82
|
+
subvalues.append(subvalue)
|
|
83
|
+
subtuple.append(subcode)
|
|
84
|
+
merges += submerges
|
|
85
|
+
|
|
86
|
+
result_schema = replace(schema, **{'_values': subvalues})
|
|
87
|
+
result_state = tuple(subtuple)
|
|
88
|
+
|
|
89
|
+
return result_schema, result_state, merges
|
|
90
|
+
|
|
91
|
+
else:
|
|
92
|
+
default_schema, default_state, merges = core.default_merges(schema, path=path)
|
|
93
|
+
return default_schema, default_state, merges
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def realize_default(core, schema, encode: dict, path=()):
|
|
97
|
+
default_state = encode.get('_default', default(schema))
|
|
98
|
+
return realize(core, schema, default_state, path=path)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@dispatch
|
|
102
|
+
def realize(core, schema: Boolean, encode, path=()):
|
|
103
|
+
if encode is None:
|
|
104
|
+
schema, state = core.default(schema, path=path)
|
|
105
|
+
return schema, state, []
|
|
106
|
+
elif isinstance(encode, dict):
|
|
107
|
+
return realize_default(core, schema, encode, path=path)
|
|
108
|
+
elif encode == 'true':
|
|
109
|
+
return schema, True, []
|
|
110
|
+
elif encode == 'false':
|
|
111
|
+
return schema, False, []
|
|
112
|
+
else:
|
|
113
|
+
return schema, encode, []
|
|
114
|
+
|
|
115
|
+
@dispatch
|
|
116
|
+
def realize(core, schema: Integer, encode, path=()):
|
|
117
|
+
if encode is None:
|
|
118
|
+
schema, state = core.default(schema, path=path)
|
|
119
|
+
return schema, state, []
|
|
120
|
+
if isinstance(encode, dict):
|
|
121
|
+
return realize_default(core, schema, encode, path=path)
|
|
122
|
+
|
|
123
|
+
try:
|
|
124
|
+
result = int(encode)
|
|
125
|
+
return schema, result, []
|
|
126
|
+
except Exception:
|
|
127
|
+
return schema, None, []
|
|
128
|
+
|
|
129
|
+
@dispatch
|
|
130
|
+
def realize(core, schema: Float, encode, path=()):
|
|
131
|
+
if encode is None:
|
|
132
|
+
schema, state = core.default(schema, path=path)
|
|
133
|
+
return schema, state, []
|
|
134
|
+
elif isinstance(encode, dict):
|
|
135
|
+
return realize_default(core, schema, encode, path=path)
|
|
136
|
+
else:
|
|
137
|
+
try:
|
|
138
|
+
result = float(encode)
|
|
139
|
+
return schema, result, []
|
|
140
|
+
except Exception:
|
|
141
|
+
return schema, None, []
|
|
142
|
+
|
|
143
|
+
@dispatch
|
|
144
|
+
def realize(core, schema: String, encode, path=()):
|
|
145
|
+
if isinstance(encode, dict):
|
|
146
|
+
return realize_default(core, schema, encode, path=path)
|
|
147
|
+
|
|
148
|
+
return schema, encode, []
|
|
149
|
+
|
|
150
|
+
@dispatch
|
|
151
|
+
def realize(core, schema: NPRandom, encode, path=()):
|
|
152
|
+
if isinstance(encode, RandomState):
|
|
153
|
+
return schema, encode, []
|
|
154
|
+
else:
|
|
155
|
+
state = realize(core, schema.state, encode)
|
|
156
|
+
random = RandomState()
|
|
157
|
+
random.set_state(state)
|
|
158
|
+
|
|
159
|
+
return schema, random, []
|
|
160
|
+
|
|
161
|
+
@dispatch
|
|
162
|
+
def realize(core, schema: List, encode, path=()):
|
|
163
|
+
decode = []
|
|
164
|
+
merges = []
|
|
165
|
+
|
|
166
|
+
if isinstance(encode, str):
|
|
167
|
+
encode = literal_eval(encode)
|
|
168
|
+
|
|
169
|
+
if isinstance(encode, (list, tuple)):
|
|
170
|
+
for index, element in enumerate(encode):
|
|
171
|
+
subschema, substate, submerges = realize(core, schema._element, element, path+(index,))
|
|
172
|
+
element_schema = core.resolve(schema._element, subschema)
|
|
173
|
+
schema = replace(schema, **{'_element': element_schema})
|
|
174
|
+
decode.append(substate)
|
|
175
|
+
merges += submerges
|
|
176
|
+
|
|
177
|
+
return schema, decode, merges
|
|
178
|
+
|
|
179
|
+
else:
|
|
180
|
+
return schema, None, []
|
|
181
|
+
|
|
182
|
+
@dispatch
|
|
183
|
+
def realize(core, schema: Map, encode, path=()):
|
|
184
|
+
if isinstance(encode, str):
|
|
185
|
+
encode = literal_eval(encode)
|
|
186
|
+
|
|
187
|
+
if isinstance(encode, dict):
|
|
188
|
+
decode = {}
|
|
189
|
+
merges = []
|
|
190
|
+
schema = replace(schema, **{'_default': encode})
|
|
191
|
+
value_schemas = []
|
|
192
|
+
|
|
193
|
+
for key, value in encode.items():
|
|
194
|
+
if key.startswith('_'):
|
|
195
|
+
continue
|
|
196
|
+
else:
|
|
197
|
+
subschema, substate, submerges = realize(core, schema._value, value, path+(key,))
|
|
198
|
+
value_schemas.append(subschema)
|
|
199
|
+
decode[key] = substate
|
|
200
|
+
merges += submerges
|
|
201
|
+
|
|
202
|
+
if value_schemas:
|
|
203
|
+
value_schema = core.resolve_schemas(
|
|
204
|
+
value_schemas)
|
|
205
|
+
value_schema = core.resolve(schema._value, value_schema)
|
|
206
|
+
|
|
207
|
+
schema = replace(schema, **{
|
|
208
|
+
'_value': value_schema})
|
|
209
|
+
|
|
210
|
+
return schema, decode, merges
|
|
211
|
+
|
|
212
|
+
else:
|
|
213
|
+
return schema, None, []
|
|
214
|
+
|
|
215
|
+
@dispatch
|
|
216
|
+
def realize(core, schema: Tree, encode, path=()):
|
|
217
|
+
decode = {}
|
|
218
|
+
|
|
219
|
+
if isinstance(encode, str):
|
|
220
|
+
try:
|
|
221
|
+
encode = literal_eval(encode)
|
|
222
|
+
except:
|
|
223
|
+
pass
|
|
224
|
+
|
|
225
|
+
leaf_schema, leaf_state, merges = realize(core, schema._leaf, encode)
|
|
226
|
+
if leaf_state is not None:
|
|
227
|
+
return leaf_schema, leaf_state, merges
|
|
228
|
+
|
|
229
|
+
elif isinstance(encode, dict):
|
|
230
|
+
decode = {}
|
|
231
|
+
for key, value in encode.items():
|
|
232
|
+
subschema, substate, submerges = realize(core, schema, value, path+(key,))
|
|
233
|
+
schema = core.resolve(schema, subschema)
|
|
234
|
+
decode[key] = substate
|
|
235
|
+
merges += submerges
|
|
236
|
+
|
|
237
|
+
return schema, decode, merges
|
|
238
|
+
|
|
239
|
+
else:
|
|
240
|
+
return schema, None, []
|
|
241
|
+
|
|
242
|
+
def dict_values(d):
|
|
243
|
+
result = []
|
|
244
|
+
for key, value in d.items():
|
|
245
|
+
if isinstance(value, dict):
|
|
246
|
+
value = dict_values(value)
|
|
247
|
+
result.append(value)
|
|
248
|
+
return result
|
|
249
|
+
|
|
250
|
+
@dispatch
|
|
251
|
+
def realize(core, schema: Array, encode, path=()):
|
|
252
|
+
if isinstance(encode, np.ndarray):
|
|
253
|
+
return schema, encode, []
|
|
254
|
+
elif isinstance(encode, dict):
|
|
255
|
+
encode = dict_values(encode)
|
|
256
|
+
|
|
257
|
+
state = np.array(
|
|
258
|
+
encode,
|
|
259
|
+
dtype=schema._data)
|
|
260
|
+
|
|
261
|
+
if state.shape != schema._shape:
|
|
262
|
+
state.reshape(schema._shape)
|
|
263
|
+
|
|
264
|
+
return schema, state, []
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def load_local_protocol(core, protocol, data):
|
|
268
|
+
if isinstance(data, str):
|
|
269
|
+
return local_lookup(core, data)
|
|
270
|
+
else:
|
|
271
|
+
raise Exception(f'address must be str, not {data}')
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
@dispatch
|
|
275
|
+
def load_protocol(core, protocol: LocalProtocol, data):
|
|
276
|
+
return load_local_protocol(core, protocol, data)
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
@dispatch
|
|
280
|
+
def load_protocol(core, protocol: Protocol, data):
|
|
281
|
+
raise Exception(f'protocol {protocol} with data {data} not implemented (!)')
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
@dispatch
|
|
285
|
+
def load_protocol(core, protocol, data):
|
|
286
|
+
raise Exception(f'value is not a protocol: {protocol}')
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
def port_merges(core, port_schema, wires, path):
|
|
290
|
+
if isinstance(wires, (list, tuple)):
|
|
291
|
+
subpath = path[:-1] + tuple(wires)
|
|
292
|
+
return [(subpath, port_schema)]
|
|
293
|
+
|
|
294
|
+
else:
|
|
295
|
+
merges = []
|
|
296
|
+
for key, subwires in wires.items():
|
|
297
|
+
down_schema, _ = core.jump(
|
|
298
|
+
port_schema,
|
|
299
|
+
{},
|
|
300
|
+
key)
|
|
301
|
+
|
|
302
|
+
submerges = port_merges(
|
|
303
|
+
core,
|
|
304
|
+
down_schema,
|
|
305
|
+
subwires,
|
|
306
|
+
path)
|
|
307
|
+
merges += submerges
|
|
308
|
+
|
|
309
|
+
return merges
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def default_wires(schema):
|
|
313
|
+
return {
|
|
314
|
+
key: [key]
|
|
315
|
+
for key in schema}
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
def realize_link(core, schema: Link, encode, path=()):
|
|
319
|
+
if 'instance' in encode:
|
|
320
|
+
return schema, encode, []
|
|
321
|
+
|
|
322
|
+
address = encode.get('address', 'local:edge')
|
|
323
|
+
if isinstance(address, str):
|
|
324
|
+
if ':' not in address:
|
|
325
|
+
protocol = 'local'
|
|
326
|
+
data = address
|
|
327
|
+
else:
|
|
328
|
+
protocol, data = address.split(':', 1)
|
|
329
|
+
|
|
330
|
+
address = {
|
|
331
|
+
'protocol': protocol,
|
|
332
|
+
'data': data}
|
|
333
|
+
|
|
334
|
+
protocol = address.get('protocol', 'local')
|
|
335
|
+
protocol_schema = core.access(protocol)
|
|
336
|
+
edge_class = load_protocol(core, protocol_schema, address['data'])
|
|
337
|
+
|
|
338
|
+
if edge_class is None:
|
|
339
|
+
raise Exception(f'no link found at address: {address}')
|
|
340
|
+
|
|
341
|
+
config_schema = edge_class.config_schema
|
|
342
|
+
encode_config = encode.get('config', {})
|
|
343
|
+
_, decode_config = core.realize(config_schema, encode_config)
|
|
344
|
+
config = core.fill(config_schema, decode_config)
|
|
345
|
+
|
|
346
|
+
# validate the config against the config_schema
|
|
347
|
+
message = f'config provided to {address} does not match the config_schema!\n\nconfig_schema: {pf(render(config_schema))}\n\nconfig: {pf(config)}\n\n'
|
|
348
|
+
core.validate(config_schema, config, message)
|
|
349
|
+
|
|
350
|
+
edge_instance = encode.get('instance', edge_class(config, core))
|
|
351
|
+
interface = edge_instance.interface()
|
|
352
|
+
|
|
353
|
+
decode = {
|
|
354
|
+
'address': address,
|
|
355
|
+
'config': config,
|
|
356
|
+
'instance': edge_instance}
|
|
357
|
+
merges = []
|
|
358
|
+
|
|
359
|
+
for port in ['inputs', 'outputs']:
|
|
360
|
+
port_key = f'_{port}'
|
|
361
|
+
port_schema = getattr(schema, port_key)
|
|
362
|
+
|
|
363
|
+
port_schema = core.resolve(
|
|
364
|
+
port_schema,
|
|
365
|
+
interface[port])
|
|
366
|
+
if port_key in encode and encode[port_key]:
|
|
367
|
+
port_schema = core.resolve(
|
|
368
|
+
port_schema,
|
|
369
|
+
encode[port_key])
|
|
370
|
+
|
|
371
|
+
decode[port_key] = port_schema
|
|
372
|
+
schema = replace(schema, **{port_key: port_schema})
|
|
373
|
+
|
|
374
|
+
if port_schema is None:
|
|
375
|
+
continue
|
|
376
|
+
|
|
377
|
+
if port not in encode or encode[port] is None:
|
|
378
|
+
decode[port] = default_wires(port_schema)
|
|
379
|
+
else:
|
|
380
|
+
subschema = getattr(schema, port)
|
|
381
|
+
|
|
382
|
+
subschema._default = encode[port]
|
|
383
|
+
wires_schema, wires_state, submerges = realize(core, subschema, encode[port], path+(port,))
|
|
384
|
+
if wires_state is None:
|
|
385
|
+
decode[port] = default_wires(port_schema)
|
|
386
|
+
else:
|
|
387
|
+
decode[port] = wires_state
|
|
388
|
+
merges += submerges
|
|
389
|
+
|
|
390
|
+
submerges = port_merges(
|
|
391
|
+
core,
|
|
392
|
+
port_schema,
|
|
393
|
+
decode[port],
|
|
394
|
+
path)
|
|
395
|
+
|
|
396
|
+
merges += submerges
|
|
397
|
+
|
|
398
|
+
# if 'shared' in encode and encode['shared'] is not None:
|
|
399
|
+
# decode['shared'] = {}
|
|
400
|
+
# for shared_name, shared_state in encode['shared'].items():
|
|
401
|
+
# link_schema, link_state, submerges = realize_link(core, schema, shared_state, path+('shared',))
|
|
402
|
+
# merges += submerges
|
|
403
|
+
|
|
404
|
+
# link_state['instance'].register_shared(edge_instance)
|
|
405
|
+
# decode['shared'][shared_name] = link_state
|
|
406
|
+
|
|
407
|
+
for key, value in encode.items():
|
|
408
|
+
if not key.startswith('_'):
|
|
409
|
+
if hasattr(schema, key):
|
|
410
|
+
getattr(schema, key)._default = value
|
|
411
|
+
else:
|
|
412
|
+
attr, decode[key], submerges = realize(
|
|
413
|
+
core, {}, value, path+(key,))
|
|
414
|
+
setattr(schema, key, attr)
|
|
415
|
+
merges += submerges
|
|
416
|
+
|
|
417
|
+
return schema, decode, merges
|
|
418
|
+
|
|
419
|
+
@dispatch
|
|
420
|
+
def realize(core, schema: Link, encode, path=()):
|
|
421
|
+
return realize_link(core, schema, encode, path=path)
|
|
422
|
+
|
|
423
|
+
@dispatch
|
|
424
|
+
def realize(core, schema: Node, encode, path=()):
|
|
425
|
+
if isinstance(encode, str):
|
|
426
|
+
try:
|
|
427
|
+
encode = literal_eval(encode)
|
|
428
|
+
except Exception as e:
|
|
429
|
+
return schema, encode, []
|
|
430
|
+
|
|
431
|
+
result = {}
|
|
432
|
+
merges = []
|
|
433
|
+
|
|
434
|
+
if isinstance(encode, dict):
|
|
435
|
+
for key in schema.__dataclass_fields__:
|
|
436
|
+
if key in encode:
|
|
437
|
+
attr = getattr(schema, key)
|
|
438
|
+
subschema, substate, submerges = realize(
|
|
439
|
+
core,
|
|
440
|
+
attr,
|
|
441
|
+
encode.get(key),
|
|
442
|
+
path+(key,))
|
|
443
|
+
schema = replace(schema, **{
|
|
444
|
+
key: core.resolve(attr, subschema)})
|
|
445
|
+
result[key] = substate
|
|
446
|
+
merges += submerges
|
|
447
|
+
|
|
448
|
+
if result:
|
|
449
|
+
return schema, result, merges
|
|
450
|
+
else:
|
|
451
|
+
return schema, encode, []
|
|
452
|
+
|
|
453
|
+
@dispatch
|
|
454
|
+
def realize(core, schema: None, encode, path=()):
|
|
455
|
+
if isinstance(encode, dict):
|
|
456
|
+
if '_type' in encode:
|
|
457
|
+
schema_keys = {
|
|
458
|
+
key: value
|
|
459
|
+
for key, value in encode.items()
|
|
460
|
+
if key.startswith('_')}
|
|
461
|
+
schema = core.access_type(schema_keys)
|
|
462
|
+
result_schema, result_state, merges = realize(
|
|
463
|
+
core, schema, encode, path=path)
|
|
464
|
+
|
|
465
|
+
return result_schema, result_state, merges
|
|
466
|
+
else:
|
|
467
|
+
merges = []
|
|
468
|
+
schema = {}
|
|
469
|
+
state = {}
|
|
470
|
+
for key, value in encode.items():
|
|
471
|
+
schema[key], state[key], submerges = realize(
|
|
472
|
+
core,
|
|
473
|
+
None,
|
|
474
|
+
value,
|
|
475
|
+
path+(key,))
|
|
476
|
+
merges += submerges
|
|
477
|
+
return schema, state, merges
|
|
478
|
+
else:
|
|
479
|
+
infer_schema, merges = core.infer_merges(
|
|
480
|
+
encode, path=path)
|
|
481
|
+
return infer_schema, encode, merges
|
|
482
|
+
|
|
483
|
+
@dispatch
|
|
484
|
+
def realize(core, schema: dict, encode, path=()):
|
|
485
|
+
if isinstance(encode, str):
|
|
486
|
+
try:
|
|
487
|
+
encode = literal_eval(encode)
|
|
488
|
+
except Exception as e:
|
|
489
|
+
return schema, encode, []
|
|
490
|
+
|
|
491
|
+
result_schema = {}
|
|
492
|
+
result_state = {}
|
|
493
|
+
merges = []
|
|
494
|
+
|
|
495
|
+
if isinstance(encode, dict):
|
|
496
|
+
for key, subschema in schema.items():
|
|
497
|
+
if key in encode:
|
|
498
|
+
outcome_schema, outcome_state, submerges = realize(
|
|
499
|
+
core,
|
|
500
|
+
subschema,
|
|
501
|
+
encode[key],
|
|
502
|
+
path+(key,))
|
|
503
|
+
|
|
504
|
+
if outcome_state is not None:
|
|
505
|
+
result_schema[key] = core.resolve(subschema, outcome_schema)
|
|
506
|
+
result_state[key] = outcome_state
|
|
507
|
+
merges += submerges
|
|
508
|
+
else:
|
|
509
|
+
if key != '_default':
|
|
510
|
+
result_schema[key], result_state[key], submerges = core.default_merges(
|
|
511
|
+
subschema,
|
|
512
|
+
path=path+(key,))
|
|
513
|
+
merges += submerges
|
|
514
|
+
|
|
515
|
+
for key in encode.keys():
|
|
516
|
+
if (isinstance(key, str) and not key.startswith('_')) and not key in schema:
|
|
517
|
+
result_schema[key], result_state[key], submerges = realize(
|
|
518
|
+
core, None, encode[key], path+(key,))
|
|
519
|
+
merges += submerges
|
|
520
|
+
|
|
521
|
+
if result_state:
|
|
522
|
+
return result_schema, result_state, merges
|
|
523
|
+
|
|
524
|
+
return schema, encode, merges
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
|