PySimultan 0.4.22__py3-none-any.whl → 0.5.2.5__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- PySimultan2/CHANGELOG.md +4 -0
- PySimultan2/__about__.py +1 -1
- PySimultan2/__init__.py +1 -0
- PySimultan2/data_model.py +185 -80
- PySimultan2/default_types.py +125 -23
- PySimultan2/files.py +55 -5
- PySimultan2/object_mapper.py +146 -9
- PySimultan2/resources/ComponentBuilder.dll +0 -0
- PySimultan2/resources/ComponentBuilder.runtimeconfig.json +2 -1
- PySimultan2/resources/ComponentBuilder.xml +47 -1
- PySimultan2/resources/SIMULTAN.AutoUpdate.Client.dll +0 -0
- PySimultan2/resources/SIMULTAN.AutoUpdate.DataTransferLibrary.dll +0 -0
- PySimultan2/resources/SIMULTAN.Lang.dll +0 -0
- PySimultan2/resources/SIMULTAN.Lang.xml +94 -7
- PySimultan2/resources/SIMULTAN.Plugins.dll +0 -0
- PySimultan2/resources/SIMULTAN.UI.dll +0 -0
- PySimultan2/resources/SIMULTAN.UI.xml +136 -43
- PySimultan2/resources/SIMULTAN.dll +0 -0
- PySimultan2/resources/SIMULTAN.xml +364 -97
- PySimultan2/resources/System.Collections.Immutable.dll +0 -0
- PySimultan2/resources/System.Reflection.Metadata.dll +0 -0
- PySimultan2/resources/System.Reflection.MetadataLoadContext.dll +0 -0
- PySimultan2/resources/componentmanager.user +0 -0
- PySimultan2/simultan_object.py +64 -15
- PySimultan2/taxonomy_maps.py +20 -12
- PySimultan2/type_setter_lookup.py +46 -33
- PySimultan2/utils.py +79 -14
- {pysimultan-0.4.22.dist-info → pysimultan-0.5.2.5.dist-info}/METADATA +2 -3
- {pysimultan-0.4.22.dist-info → pysimultan-0.5.2.5.dist-info}/RECORD +31 -32
- {pysimultan-0.4.22.dist-info → pysimultan-0.5.2.5.dist-info}/WHEEL +1 -1
- PySimultan2/resources/GeometryViewer.dll +0 -0
- PySimultan2/resources/GeometryViewer.dll.config +0 -42
- PySimultan2/resources/GeometryViewer.xml +0 -6425
- PySimultan2/resources/SitePlanner.dll +0 -0
- PySimultan2/resources/SitePlanner.dll.config +0 -11
- PySimultan2/resources/SitePlanner.xml +0 -2736
- {pysimultan-0.4.22.dist-info → pysimultan-0.5.2.5.dist-info}/licenses/LICENSE.txt +0 -0
PySimultan2/default_types.py
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
import xxsubtype
|
4
3
|
from collections.abc import Iterable
|
5
4
|
import numpy as np
|
6
|
-
import pandas as pd
|
7
5
|
import colorlog
|
8
6
|
from typing import Union, List, Type, Set, Tuple, Any, Optional
|
9
7
|
|
@@ -139,11 +137,19 @@ class ComponentList(SimultanObject):
|
|
139
137
|
|
140
138
|
def append(self, values: Union[SimultanObject, List]):
|
141
139
|
|
140
|
+
return_val = []
|
141
|
+
|
142
|
+
as_list = True
|
142
143
|
if not isinstance(values, Iterable):
|
144
|
+
as_list = False
|
143
145
|
values = [values]
|
144
146
|
|
145
147
|
for i, value in enumerate(values, start=len(self.data)):
|
146
|
-
self._set_value(value, i)
|
148
|
+
return_val.append(self._set_value(value, i))
|
149
|
+
|
150
|
+
if not as_list:
|
151
|
+
return return_val[0]
|
152
|
+
return return_val
|
147
153
|
|
148
154
|
def _update_slot_extensions(self, index: int):
|
149
155
|
|
@@ -160,6 +166,9 @@ class ComponentList(SimultanObject):
|
|
160
166
|
|
161
167
|
def _set_value(self, value, i):
|
162
168
|
|
169
|
+
if isinstance(value, FileInfo):
|
170
|
+
raise ValueError(f'FileInfos cannot be added to ComponentLists')
|
171
|
+
|
163
172
|
if isinstance(value, SimultanObject):
|
164
173
|
slot = value._wrapped_obj.Slots.Items[0]
|
165
174
|
|
@@ -171,6 +180,9 @@ class ComponentList(SimultanObject):
|
|
171
180
|
self.add_referenced_component(value._wrapped_obj,
|
172
181
|
slot_extension=str(i),
|
173
182
|
slot=slot)
|
183
|
+
|
184
|
+
return value
|
185
|
+
|
174
186
|
else:
|
175
187
|
new_val = create_mapped_python_object(value,
|
176
188
|
data_model=self._data_model,
|
@@ -193,6 +205,8 @@ class ComponentList(SimultanObject):
|
|
193
205
|
slot_extension=str(i),
|
194
206
|
slot=taxonomy_entry)
|
195
207
|
|
208
|
+
return new_val
|
209
|
+
|
196
210
|
def __setitem__(self, i, value):
|
197
211
|
if isinstance(i, slice):
|
198
212
|
for j, val in enumerate(value):
|
@@ -210,7 +224,7 @@ class ComponentList(SimultanObject):
|
|
210
224
|
self._set_value(value, i)
|
211
225
|
|
212
226
|
def extend(self, values: List):
|
213
|
-
self.append(values)
|
227
|
+
return self.append(values)
|
214
228
|
|
215
229
|
def remove(self, value: SimultanObject):
|
216
230
|
self.discard(value)
|
@@ -292,6 +306,41 @@ class ComponentList(SimultanObject):
|
|
292
306
|
self._wrapped_obj.Components.Clear()
|
293
307
|
self._wrapped_obj.ReferencedComponents.Clear()
|
294
308
|
|
309
|
+
def to_json(self) -> dict[Any: Any]:
|
310
|
+
|
311
|
+
return_val = [None] * len(self.data)
|
312
|
+
|
313
|
+
for i, val in enumerate(self.data):
|
314
|
+
|
315
|
+
if hasattr(val, 'json_ref'):
|
316
|
+
return_val[i] = val.json_ref()
|
317
|
+
elif isinstance(val, list):
|
318
|
+
return_val[i] = [v.json_ref() if hasattr(v, 'json_ref') else v for v in val]
|
319
|
+
elif isinstance(val, dict):
|
320
|
+
return_val[i] = {k: v.json_ref() if hasattr(v, 'json_ref') else v for k, v in val.items()}
|
321
|
+
elif isinstance(val, np.ndarray):
|
322
|
+
return_val[i] = val.tolist()
|
323
|
+
else:
|
324
|
+
return_val[i] = val
|
325
|
+
|
326
|
+
return {
|
327
|
+
str(self.id): {
|
328
|
+
'name': self.name,
|
329
|
+
'taxonomies': self.taxonomy_keys,
|
330
|
+
'items': return_val
|
331
|
+
}
|
332
|
+
}
|
333
|
+
|
334
|
+
def json_ref(self):
|
335
|
+
return {"$ref": {
|
336
|
+
"$type": 'ComponentList',
|
337
|
+
"$taxonomies": self.taxonomy_keys,
|
338
|
+
"$id": {'local_id': self.id.LocalId,
|
339
|
+
'global_id': str(self.id.GlobalId)
|
340
|
+
},
|
341
|
+
"length": len(self)
|
342
|
+
}
|
343
|
+
}
|
295
344
|
|
296
345
|
component_list_map = TaxonomyMap(taxonomy_name='PySimultan',
|
297
346
|
taxonomy_key='PySimultan',
|
@@ -319,9 +368,11 @@ class ComponentDictionary(SimultanObject):
|
|
319
368
|
self._dict = {}
|
320
369
|
super().__init__(*args, **kwargs)
|
321
370
|
self.component_policy = kwargs.get('component_policy', 'subcomponent') # component add policy of the content/parameter/property, 'reference' or 'subcomponent'
|
371
|
+
self._generate_internal_dict()
|
322
372
|
|
323
373
|
def __load_init__(self, *args, **kwargs):
|
324
374
|
self._dict = {}
|
375
|
+
self._generate_internal_dict()
|
325
376
|
|
326
377
|
@classmethod
|
327
378
|
def create_from_values(cls,
|
@@ -348,15 +399,20 @@ class ComponentDictionary(SimultanObject):
|
|
348
399
|
for key, value in values.items():
|
349
400
|
new_component_dict[key] = value
|
350
401
|
|
402
|
+
new_component_dict._generate_internal_dict()
|
403
|
+
|
351
404
|
return new_component_dict
|
352
405
|
|
353
406
|
def __getitem__(self, key, *args, **kwargs):
|
354
407
|
|
355
408
|
comp_dict = object.__getattribute__(self, '_dict')
|
356
409
|
|
357
|
-
if kwargs.get('check_dict',
|
358
|
-
|
359
|
-
|
410
|
+
if (kwargs.get('check_dict', False) and comp_dict is not None and
|
411
|
+
(key in comp_dict.keys() or '__dict_key__' + key in comp_dict.keys())):
|
412
|
+
if key in comp_dict.keys():
|
413
|
+
return comp_dict.get(key, None)
|
414
|
+
else:
|
415
|
+
return comp_dict.get('__dict_key__' + key, None)
|
360
416
|
else:
|
361
417
|
# data_model = config.default_data_model
|
362
418
|
# obj = get_component_taxonomy_entry(self._wrapped_obj, key)
|
@@ -406,6 +462,8 @@ class ComponentDictionary(SimultanObject):
|
|
406
462
|
object_mapper=object_mapper)
|
407
463
|
|
408
464
|
if val is not None:
|
465
|
+
if key.startswith('__dict_key__'):
|
466
|
+
key = key.replace('__dict_key__', '')
|
409
467
|
self._dict[key] = val
|
410
468
|
|
411
469
|
return self._dict.get(key, None)
|
@@ -454,27 +512,32 @@ class ComponentDictionary(SimultanObject):
|
|
454
512
|
return
|
455
513
|
|
456
514
|
from .type_setter_lookup import type_setter_fcn_lookup_dict
|
457
|
-
setter_fcn = type_setter_fcn_lookup_dict.get(
|
515
|
+
setter_fcn = type_setter_fcn_lookup_dict.get(value, set_property_to_unknown_type)
|
458
516
|
|
459
517
|
setter_fcn(*fcn_arg_list)
|
460
518
|
item = self.__getitem__(key, check_dict=False)
|
461
519
|
|
462
|
-
|
520
|
+
if key.startswith('__dict_key__'):
|
521
|
+
self._dict[key.replace('__dict_key__', '')] = item
|
522
|
+
else:
|
523
|
+
self._dict[key] = item
|
463
524
|
|
464
525
|
def __delitem__(self, key):
|
465
526
|
self[key] = None
|
466
527
|
del self._dict[key]
|
467
528
|
|
468
529
|
def items(self):
|
530
|
+
if self._dict is None or not self._dict:
|
531
|
+
self._generate_internal_dict()
|
469
532
|
return self._dict.items()
|
470
533
|
|
471
534
|
def keys(self):
|
472
|
-
if not self._dict:
|
535
|
+
if not self._dict or not self._dict:
|
473
536
|
self._generate_internal_dict()
|
474
537
|
return self._dict.keys()
|
475
538
|
|
476
539
|
def values(self):
|
477
|
-
if not self._dict:
|
540
|
+
if not self._dict or not self._dict:
|
478
541
|
self._generate_internal_dict()
|
479
542
|
return self._dict.values()
|
480
543
|
|
@@ -482,22 +545,26 @@ class ComponentDictionary(SimultanObject):
|
|
482
545
|
comp_dict = {}
|
483
546
|
|
484
547
|
for parameter in self._wrapped_obj.Parameters.Items:
|
485
|
-
|
486
|
-
|
487
|
-
|
548
|
+
key = parameter.NameTaxonomyEntry.TextOrKey.replace('__dict_key__', '')
|
549
|
+
comp_dict[key] = get_obj_value(parameter,
|
550
|
+
data_model=self._data_model,
|
551
|
+
object_mapper=self._object_mapper)
|
488
552
|
for component in self._wrapped_obj.Components.Items:
|
489
|
-
|
490
|
-
|
491
|
-
|
553
|
+
key = component.Slot.SlotBase.Target.Key.replace('__dict_key__', '')
|
554
|
+
comp_dict[key] = get_obj_value(component.Component,
|
555
|
+
data_model=self._data_model,
|
556
|
+
object_mapper=self._object_mapper)
|
492
557
|
for ref_component in self._wrapped_obj.ReferencedComponents.Items:
|
493
|
-
|
494
|
-
|
495
|
-
|
558
|
+
key = ref_component.Slot.SlotBase.Target.Key.replace('__dict_key__', '')
|
559
|
+
comp_dict[key] = get_obj_value(ref_component.Target,
|
560
|
+
data_model=self._data_model,
|
561
|
+
object_mapper=self._object_mapper)
|
496
562
|
for ref_asset in self._wrapped_obj.ReferencedAssets.Items:
|
497
563
|
for tag in ref_asset.Resource.Tags:
|
498
|
-
|
499
|
-
|
500
|
-
|
564
|
+
key = tag.Target.Key.replace('__dict_key__', '')
|
565
|
+
comp_dict[key] = get_obj_value(ref_asset.Target,
|
566
|
+
data_model=self._data_model,
|
567
|
+
object_mapper=self._object_mapper)
|
501
568
|
|
502
569
|
object.__setattr__(self, '_dict', comp_dict)
|
503
570
|
|
@@ -529,5 +596,40 @@ class ComponentDictionary(SimultanObject):
|
|
529
596
|
for key, value in other.items():
|
530
597
|
self[key] = value
|
531
598
|
|
599
|
+
def to_json(self) -> dict:
|
600
|
+
|
601
|
+
return_value = {}
|
602
|
+
|
603
|
+
for key, value in self.items():
|
604
|
+
if isinstance(value, SimultanObject):
|
605
|
+
return_value[key] = value.to_json()
|
606
|
+
elif isinstance(value, list):
|
607
|
+
return_value[key] = [v.json_ref() if hasattr(v, 'json_ref') else v for v in value]
|
608
|
+
elif isinstance(value, dict):
|
609
|
+
return_value[key] = {k: v.json_ref() if hasattr(v, 'json_ref') else v for k, v in value.items()}
|
610
|
+
elif isinstance(value, np.ndarray):
|
611
|
+
return_value[key] = value.tolist()
|
612
|
+
else:
|
613
|
+
return_value[key] = value
|
614
|
+
|
615
|
+
return {
|
616
|
+
str(self.id): {
|
617
|
+
'name': self.name,
|
618
|
+
'taxonomies': self.taxonomy_keys,
|
619
|
+
'items': return_value
|
620
|
+
}
|
621
|
+
}
|
622
|
+
|
623
|
+
def json_ref(self):
|
624
|
+
return {"$ref": {
|
625
|
+
"$type": 'ComponentDictionary',
|
626
|
+
"$taxonomies": self.taxonomy_keys,
|
627
|
+
"$id": {'local_id': self.id.LocalId,
|
628
|
+
'global_id': str(self.id.GlobalId)
|
629
|
+
},
|
630
|
+
"length": len(self)
|
631
|
+
}
|
632
|
+
}
|
633
|
+
|
532
634
|
|
533
635
|
component_dict_map = ComponentDictionary._taxonomy_map
|
PySimultan2/files.py
CHANGED
@@ -81,9 +81,17 @@ def add_asset_to_component(comp: [SimComponent, SimultanObject],
|
|
81
81
|
wrapped_obj = comp if isinstance(comp, SimComponent) else comp._wrapped_obj
|
82
82
|
|
83
83
|
if tag is not None:
|
84
|
-
|
84
|
+
try:
|
85
|
+
add_tag_to_resource(asset, tag)
|
86
|
+
except Exception as e:
|
87
|
+
logger.error(f'Error adding tag to asset {asset}: {e} ')
|
88
|
+
raise e
|
85
89
|
|
86
|
-
|
90
|
+
try:
|
91
|
+
return ComponentMapping.AddAsset(wrapped_obj, asset, content_id)
|
92
|
+
except Exception as e:
|
93
|
+
logger.error(f'Error adding asset {asset} to component: {e}')
|
94
|
+
raise e
|
87
95
|
|
88
96
|
|
89
97
|
def remove_asset_from_component(comp: Union[SimComponent, SimultanObject],
|
@@ -187,7 +195,9 @@ class FileInfo(object, metaclass=MetaMock):
|
|
187
195
|
_cls_instances = {}
|
188
196
|
|
189
197
|
@classmethod
|
190
|
-
def from_string(cls,
|
198
|
+
def from_string(cls,
|
199
|
+
filename: str,
|
200
|
+
content: str, *args, **kwargs) -> FileInfo:
|
191
201
|
"""
|
192
202
|
Create a file info object from a string.
|
193
203
|
:param filename: Name of the file to be created. E.g. 'new_file.txt'
|
@@ -237,6 +247,13 @@ class FileInfo(object, metaclass=MetaMock):
|
|
237
247
|
self.args = args
|
238
248
|
self.kwargs = kwargs
|
239
249
|
|
250
|
+
@property
|
251
|
+
def key(self) -> int:
|
252
|
+
try:
|
253
|
+
return self.resource_entry.Key
|
254
|
+
except Exception as e:
|
255
|
+
return None
|
256
|
+
|
240
257
|
@property
|
241
258
|
def resource_entry(self) -> Union[ResourceFileEntry, ContainedResourceFileEntry, None]:
|
242
259
|
if self._resource_entry is None:
|
@@ -258,8 +275,13 @@ class FileInfo(object, metaclass=MetaMock):
|
|
258
275
|
self._resource_entry = value
|
259
276
|
|
260
277
|
@property
|
261
|
-
def file_size(self) -> int:
|
262
|
-
|
278
|
+
def file_size(self) -> Optional[int]:
|
279
|
+
try:
|
280
|
+
return os.path.getsize(self.file_path)
|
281
|
+
except FileNotFoundError:
|
282
|
+
raise FileNotFoundError(f'File not found: {self.file_path}')
|
283
|
+
except Exception as e:
|
284
|
+
raise e
|
263
285
|
|
264
286
|
@property
|
265
287
|
def last_modified(self) -> datetime:
|
@@ -269,6 +291,10 @@ class FileInfo(object, metaclass=MetaMock):
|
|
269
291
|
def resource_entry(self, value):
|
270
292
|
self._resource_entry = value
|
271
293
|
|
294
|
+
@property
|
295
|
+
def filename(self) -> str:
|
296
|
+
return self.resource_entry.File.Name
|
297
|
+
|
272
298
|
@property
|
273
299
|
def name(self) -> str:
|
274
300
|
return os.path.basename(self.file_path)
|
@@ -317,6 +343,9 @@ class FileInfo(object, metaclass=MetaMock):
|
|
317
343
|
def __exit__(self, *args):
|
318
344
|
self.file_obj.close()
|
319
345
|
|
346
|
+
def __repr__(self):
|
347
|
+
return f'FileInfo({self.file_path})'
|
348
|
+
|
320
349
|
def get_content(self, encoding='utf-8') -> Optional[Union[str, dict[str, str]]]:
|
321
350
|
"""
|
322
351
|
Get the content of the file.
|
@@ -373,3 +402,24 @@ class FileInfo(object, metaclass=MetaMock):
|
|
373
402
|
if self.resource_entry is not None:
|
374
403
|
self.data_model.delete_resource(self.resource_entry)
|
375
404
|
os.remove(self.file_path)
|
405
|
+
|
406
|
+
def to_json(self) -> dict:
|
407
|
+
|
408
|
+
obj_dict = {
|
409
|
+
'key': self.key,
|
410
|
+
'name': self.name,
|
411
|
+
'file_path': self.file_path,
|
412
|
+
'file_size': self.file_size,
|
413
|
+
'last_modified': self.last_modified,
|
414
|
+
'encoding': self.encoding,
|
415
|
+
'is_zip': self.is_zip,
|
416
|
+
}
|
417
|
+
|
418
|
+
return obj_dict
|
419
|
+
|
420
|
+
def json_ref(self):
|
421
|
+
return {"$ref": {
|
422
|
+
"$type": 'FileInfo',
|
423
|
+
"$key": str(self.key)
|
424
|
+
}
|
425
|
+
}
|
PySimultan2/object_mapper.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import Optional, Type, TYPE_CHECKING, Union
|
1
|
+
from typing import Optional, Type, TYPE_CHECKING, Union, Any
|
2
2
|
from copy import copy
|
3
3
|
from collections import UserList
|
4
4
|
from colorlog import getLogger
|
@@ -32,9 +32,21 @@ default_taxonomy_maps = {'ComponentList': component_list_map,
|
|
32
32
|
|
33
33
|
class PythonMapper(object):
|
34
34
|
|
35
|
+
mappers = {}
|
36
|
+
|
35
37
|
def __new__(cls, *args, **kwargs):
|
36
38
|
instance = super(PythonMapper, cls).__new__(cls)
|
37
39
|
config.set_default_mapper(instance)
|
40
|
+
|
41
|
+
if kwargs.get('add_to_mappers', True):
|
42
|
+
initial_module_name = kwargs.get('module', 'unknown_module')
|
43
|
+
module_name = initial_module_name
|
44
|
+
i = 0
|
45
|
+
while module_name in cls.mappers.keys():
|
46
|
+
module_name = f'{initial_module_name}_{i}'
|
47
|
+
i+=1
|
48
|
+
cls.mappers[module_name] = instance
|
49
|
+
|
38
50
|
return instance
|
39
51
|
|
40
52
|
def __init__(self, *args, **kwargs):
|
@@ -42,6 +54,9 @@ class PythonMapper(object):
|
|
42
54
|
self._mapped_classes = {}
|
43
55
|
|
44
56
|
self.name = kwargs.get('name', 'PythonMapper')
|
57
|
+
self._module = kwargs.get('module', 'unknown_module')
|
58
|
+
self.submodules = kwargs.get('submodules', {})
|
59
|
+
|
45
60
|
self.registered_classes: dict[str: SimultanObject] = copy(default_registered_classes) # dict with all registered classes: {taxonomy: class}
|
46
61
|
|
47
62
|
self.undefined_registered_classes: dict[str: SimultanObject] = {} # dict with all registered classes: {taxonomy: class}
|
@@ -59,6 +74,18 @@ class PythonMapper(object):
|
|
59
74
|
self.re_register = False
|
60
75
|
self.load_undefined = False
|
61
76
|
|
77
|
+
@property
|
78
|
+
def module(self):
|
79
|
+
return self._module
|
80
|
+
|
81
|
+
@module.setter
|
82
|
+
def module(self, value):
|
83
|
+
if self._module != value:
|
84
|
+
del self.mappers[self._module]
|
85
|
+
|
86
|
+
self._module = value
|
87
|
+
self.mappers[value] = self
|
88
|
+
|
62
89
|
@property
|
63
90
|
def mapped_classes(self):
|
64
91
|
if len(self.registered_classes) > len(self._mapped_classes):
|
@@ -72,10 +99,24 @@ class PythonMapper(object):
|
|
72
99
|
def mapped_classes(self, value):
|
73
100
|
self._mapped_classes = value
|
74
101
|
|
75
|
-
def register(self,
|
76
|
-
|
102
|
+
def register(self,
|
103
|
+
taxonomy: str,
|
104
|
+
cls: Type[Any],
|
105
|
+
re_register=True,
|
106
|
+
update_in_other_mappers=False,
|
107
|
+
taxonomy_map=None):
|
108
|
+
|
109
|
+
# print(f'Registering {taxonomy} with {cls} {hash(cls)}')
|
110
|
+
|
111
|
+
if not (self.re_register or re_register) and taxonomy in self.registered_classes.keys():
|
77
112
|
return
|
78
113
|
|
114
|
+
if taxonomy in self.mapped_classes.keys():
|
115
|
+
try:
|
116
|
+
del self.mapped_classes[taxonomy]
|
117
|
+
except KeyError:
|
118
|
+
pass
|
119
|
+
|
79
120
|
if taxonomy_map is None:
|
80
121
|
taxonomy_map = TaxonomyMap(taxonomy_name='PySimultan',
|
81
122
|
taxonomy_key='PySimultan',
|
@@ -85,8 +126,28 @@ class PythonMapper(object):
|
|
85
126
|
self.registered_classes[taxonomy] = cls
|
86
127
|
self.taxonomy_maps[taxonomy] = taxonomy_map
|
87
128
|
|
129
|
+
if update_in_other_mappers:
|
130
|
+
self.update_from_other_mappers()
|
131
|
+
|
88
132
|
return self.get_mapped_class(taxonomy)
|
89
133
|
|
134
|
+
def update_from_other_mappers(self):
|
135
|
+
for mapper in self.mappers.values():
|
136
|
+
if mapper is not self:
|
137
|
+
for cls, taxonomy in mapper.registered_classes.items():
|
138
|
+
if cls in self.registered_classes.values():
|
139
|
+
key = list(filter(lambda x: mapper.registered_classes[x] == cls,
|
140
|
+
mapper.registered_classes)
|
141
|
+
)[0]
|
142
|
+
mapper.registered_classes[key] = cls
|
143
|
+
print(f'Updated {cls} in {mapper.module} with {taxonomy}')
|
144
|
+
|
145
|
+
def update_from_submodules(self):
|
146
|
+
for submodule in self.submodules.values():
|
147
|
+
self.registered_classes.update(submodule.registered_classes)
|
148
|
+
self.taxonomy_maps.update(submodule.taxonomy_maps)
|
149
|
+
self.registered_geometry_classes.update(submodule.registered_geometry_classes)
|
150
|
+
|
90
151
|
def create_mapped_class(self, taxonomy, cls):
|
91
152
|
|
92
153
|
if any([issubclass(cls, x) for x in (SimultanObject, UserList)]):
|
@@ -171,7 +232,11 @@ class PythonMapper(object):
|
|
171
232
|
typed_data.append(typed_object)
|
172
233
|
return typed_data
|
173
234
|
|
174
|
-
def create_python_geometry_object(self,
|
235
|
+
def create_python_geometry_object(self,
|
236
|
+
component: Union[Layer, Vertex, Edge, PEdge, Face, Volume, EdgeLoop],
|
237
|
+
data_model: 'DataModel' = None,
|
238
|
+
*args,
|
239
|
+
**kwargs):
|
175
240
|
|
176
241
|
if component is None:
|
177
242
|
return None
|
@@ -191,7 +256,7 @@ class PythonMapper(object):
|
|
191
256
|
self.create_python_object(component, data_model, *args, **kwargs)
|
192
257
|
|
193
258
|
def get_mapped_class_from_component(self,
|
194
|
-
component,
|
259
|
+
component: Union[SimComponent, Layer, Vertex, Edge, PEdge, Face, Volume, EdgeLoop],
|
195
260
|
data_model: Optional['DataModel'] = None,
|
196
261
|
*args,
|
197
262
|
**kwargs) -> Optional[Type[SimultanObject]]:
|
@@ -205,7 +270,10 @@ class PythonMapper(object):
|
|
205
270
|
if isinstance(component,
|
206
271
|
(Layer, Vertex, Edge, PEdge, Face, Volume, EdgeLoop)
|
207
272
|
):
|
208
|
-
self.create_python_geometry_object(component,
|
273
|
+
self.create_python_geometry_object(component,
|
274
|
+
data_model,
|
275
|
+
*args,
|
276
|
+
**kwargs)
|
209
277
|
|
210
278
|
c_slots = [x.Target.Key for x in component.Slots.Items]
|
211
279
|
c_slot = list(set(c_slots) & set(self.registered_classes.keys()))
|
@@ -266,6 +334,21 @@ class PythonMapper(object):
|
|
266
334
|
*args,
|
267
335
|
**kwargs)
|
268
336
|
|
337
|
+
def create_mapped_python_object(self,
|
338
|
+
obj: Any,
|
339
|
+
data_model=None,
|
340
|
+
add_to_data_model=True,
|
341
|
+
*args,
|
342
|
+
**kwargs) -> Optional[SimultanObject]:
|
343
|
+
|
344
|
+
from .utils import create_mapped_python_object
|
345
|
+
return create_mapped_python_object(obj,
|
346
|
+
object_mapper=self,
|
347
|
+
data_model=data_model,
|
348
|
+
add_to_data_model=add_to_data_model,
|
349
|
+
*args,
|
350
|
+
**kwargs)
|
351
|
+
|
269
352
|
def get_typed_data_with_taxonomy(self, taxonomy: str, data_model=None, first=False):
|
270
353
|
|
271
354
|
tax_components = data_model.find_components_with_taxonomy(taxonomy=taxonomy, first=first)
|
@@ -307,14 +390,68 @@ class PythonMapper(object):
|
|
307
390
|
new_val = create_mapped_python_object(obj, self, data_model)
|
308
391
|
return new_val
|
309
392
|
|
310
|
-
def copy(self
|
311
|
-
|
393
|
+
def copy(self,
|
394
|
+
*args,
|
395
|
+
**kwargs) -> 'PythonMapper':
|
396
|
+
|
397
|
+
orig_new_module_name = kwargs.get('module', self.module)
|
398
|
+
new_module_name = orig_new_module_name
|
399
|
+
i = 0
|
400
|
+
while new_module_name in self.mappers.keys():
|
401
|
+
new_module_name = f'copy_{i}_of_{new_module_name}'
|
402
|
+
i+=1
|
403
|
+
|
404
|
+
new_mapper = PythonMapper(add_to_mappers=kwargs.get('add_to_mappers', True),
|
405
|
+
module=new_module_name)
|
312
406
|
new_mapper.registered_classes = self.registered_classes
|
313
407
|
new_mapper.taxonomy_maps = self.taxonomy_maps
|
314
408
|
new_mapper.registered_geometry_classes = self.registered_geometry_classes
|
315
409
|
new_mapper.load_undefined = self.load_undefined
|
410
|
+
|
316
411
|
return new_mapper
|
317
412
|
|
413
|
+
def __add__(self, other: 'PythonMapper') -> 'PythonMapper':
|
414
|
+
# new_mapper = self.copy(add_to_mappers=True)
|
415
|
+
self.submodules[other.module] = other
|
416
|
+
self.submodules.update(other.submodules)
|
417
|
+
self.registered_classes.update(other.registered_classes)
|
418
|
+
self.taxonomy_maps.update(other.taxonomy_maps)
|
419
|
+
self.registered_geometry_classes.update(other.registered_geometry_classes)
|
420
|
+
return self
|
421
|
+
|
422
|
+
def get_mapped_class_for_python_type(self, python_type: type) -> Optional[Type[SimultanObject]]:
|
423
|
+
try:
|
424
|
+
key = list(filter(lambda x: self.registered_classes[x] == python_type,
|
425
|
+
self.registered_classes)
|
426
|
+
)[0]
|
427
|
+
mapped_cls = self.get_mapped_class(key)
|
428
|
+
return mapped_cls
|
429
|
+
except IndexError:
|
430
|
+
return None
|
431
|
+
|
432
|
+
def __repr__(self):
|
433
|
+
return f'PythonMapper(module={self.module}, {len(self.registered_classes)} registered classes)'
|
434
|
+
|
318
435
|
|
319
436
|
if config.get_default_mapper() is None:
|
320
|
-
config.set_default_mapper(PythonMapper())
|
437
|
+
config.set_default_mapper(PythonMapper(module='default'))
|
438
|
+
|
439
|
+
|
440
|
+
def register(taxonomy: str,
|
441
|
+
taxonomy_map: TaxonomyMap,
|
442
|
+
re_register=True,
|
443
|
+
module: str = 'unknown_module') -> Any:
|
444
|
+
|
445
|
+
if module not in PythonMapper.mappers.keys():
|
446
|
+
PythonMapper(module=module)
|
447
|
+
|
448
|
+
mapper = PythonMapper.mappers[module]
|
449
|
+
|
450
|
+
def decorator(cls):
|
451
|
+
mapper.register(taxonomy,
|
452
|
+
cls,
|
453
|
+
re_register=re_register,
|
454
|
+
taxonomy_map=taxonomy_map)
|
455
|
+
return cls
|
456
|
+
|
457
|
+
return decorator
|
Binary file
|
@@ -12,7 +12,8 @@
|
|
12
12
|
}
|
13
13
|
],
|
14
14
|
"configProperties": {
|
15
|
-
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false
|
15
|
+
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
|
16
|
+
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": true
|
16
17
|
}
|
17
18
|
}
|
18
19
|
}
|