idmtools 0.0.0.dev0__py3-none-any.whl → 0.0.2__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.
Files changed (118) hide show
  1. idmtools/__init__.py +27 -8
  2. idmtools/analysis/__init__.py +5 -0
  3. idmtools/analysis/add_analyzer.py +89 -0
  4. idmtools/analysis/analyze_manager.py +490 -0
  5. idmtools/analysis/csv_analyzer.py +103 -0
  6. idmtools/analysis/download_analyzer.py +96 -0
  7. idmtools/analysis/map_worker_entry.py +100 -0
  8. idmtools/analysis/platform_analysis_bootstrap.py +94 -0
  9. idmtools/analysis/platform_anaylsis.py +291 -0
  10. idmtools/analysis/tags_analyzer.py +93 -0
  11. idmtools/assets/__init__.py +9 -0
  12. idmtools/assets/asset.py +453 -0
  13. idmtools/assets/asset_collection.py +514 -0
  14. idmtools/assets/content_handlers.py +19 -0
  15. idmtools/assets/errors.py +23 -0
  16. idmtools/assets/file_list.py +191 -0
  17. idmtools/builders/__init__.py +11 -0
  18. idmtools/builders/arm_simulation_builder.py +152 -0
  19. idmtools/builders/csv_simulation_builder.py +76 -0
  20. idmtools/builders/simulation_builder.py +348 -0
  21. idmtools/builders/sweep_arm.py +109 -0
  22. idmtools/builders/yaml_simulation_builder.py +82 -0
  23. idmtools/config/__init__.py +7 -0
  24. idmtools/config/idm_config_parser.py +486 -0
  25. idmtools/core/__init__.py +10 -0
  26. idmtools/core/cache_enabled.py +114 -0
  27. idmtools/core/context.py +68 -0
  28. idmtools/core/docker_task.py +207 -0
  29. idmtools/core/enums.py +51 -0
  30. idmtools/core/exceptions.py +91 -0
  31. idmtools/core/experiment_factory.py +71 -0
  32. idmtools/core/id_file.py +70 -0
  33. idmtools/core/interfaces/__init__.py +5 -0
  34. idmtools/core/interfaces/entity_container.py +64 -0
  35. idmtools/core/interfaces/iassets_enabled.py +58 -0
  36. idmtools/core/interfaces/ientity.py +331 -0
  37. idmtools/core/interfaces/iitem.py +206 -0
  38. idmtools/core/interfaces/imetadata_operations.py +89 -0
  39. idmtools/core/interfaces/inamed_entity.py +17 -0
  40. idmtools/core/interfaces/irunnable_entity.py +159 -0
  41. idmtools/core/logging.py +387 -0
  42. idmtools/core/platform_factory.py +316 -0
  43. idmtools/core/system_information.py +104 -0
  44. idmtools/core/task_factory.py +145 -0
  45. idmtools/entities/__init__.py +10 -0
  46. idmtools/entities/command_line.py +229 -0
  47. idmtools/entities/command_task.py +155 -0
  48. idmtools/entities/experiment.py +787 -0
  49. idmtools/entities/generic_workitem.py +43 -0
  50. idmtools/entities/ianalyzer.py +163 -0
  51. idmtools/entities/iplatform.py +1106 -0
  52. idmtools/entities/iplatform_default.py +39 -0
  53. idmtools/entities/iplatform_ops/__init__.py +5 -0
  54. idmtools/entities/iplatform_ops/iplatform_asset_collection_operations.py +148 -0
  55. idmtools/entities/iplatform_ops/iplatform_experiment_operations.py +415 -0
  56. idmtools/entities/iplatform_ops/iplatform_simulation_operations.py +315 -0
  57. idmtools/entities/iplatform_ops/iplatform_suite_operations.py +322 -0
  58. idmtools/entities/iplatform_ops/iplatform_workflowitem_operations.py +301 -0
  59. idmtools/entities/iplatform_ops/utils.py +185 -0
  60. idmtools/entities/itask.py +316 -0
  61. idmtools/entities/iworkflow_item.py +167 -0
  62. idmtools/entities/platform_requirements.py +20 -0
  63. idmtools/entities/relation_type.py +14 -0
  64. idmtools/entities/simulation.py +255 -0
  65. idmtools/entities/suite.py +188 -0
  66. idmtools/entities/task_proxy.py +37 -0
  67. idmtools/entities/templated_simulation.py +325 -0
  68. idmtools/frozen/frozen_dict.py +71 -0
  69. idmtools/frozen/frozen_list.py +66 -0
  70. idmtools/frozen/frozen_set.py +86 -0
  71. idmtools/frozen/frozen_tuple.py +18 -0
  72. idmtools/frozen/frozen_utils.py +179 -0
  73. idmtools/frozen/ifrozen.py +66 -0
  74. idmtools/plugins/__init__.py +5 -0
  75. idmtools/plugins/git_commit.py +117 -0
  76. idmtools/registry/__init__.py +4 -0
  77. idmtools/registry/experiment_specification.py +105 -0
  78. idmtools/registry/functions.py +28 -0
  79. idmtools/registry/hook_specs.py +132 -0
  80. idmtools/registry/master_plugin_registry.py +51 -0
  81. idmtools/registry/platform_specification.py +138 -0
  82. idmtools/registry/plugin_specification.py +129 -0
  83. idmtools/registry/task_specification.py +104 -0
  84. idmtools/registry/utils.py +119 -0
  85. idmtools/services/__init__.py +5 -0
  86. idmtools/services/ipersistance_service.py +135 -0
  87. idmtools/services/platforms.py +13 -0
  88. idmtools/utils/__init__.py +5 -0
  89. idmtools/utils/caller.py +24 -0
  90. idmtools/utils/collections.py +246 -0
  91. idmtools/utils/command_line.py +45 -0
  92. idmtools/utils/decorators.py +300 -0
  93. idmtools/utils/display/__init__.py +22 -0
  94. idmtools/utils/display/displays.py +181 -0
  95. idmtools/utils/display/settings.py +25 -0
  96. idmtools/utils/dropbox_location.py +30 -0
  97. idmtools/utils/entities.py +127 -0
  98. idmtools/utils/file.py +72 -0
  99. idmtools/utils/file_parser.py +151 -0
  100. idmtools/utils/filter_simulations.py +182 -0
  101. idmtools/utils/filters/__init__.py +5 -0
  102. idmtools/utils/filters/asset_filters.py +88 -0
  103. idmtools/utils/general.py +286 -0
  104. idmtools/utils/gitrepo.py +336 -0
  105. idmtools/utils/hashing.py +239 -0
  106. idmtools/utils/info.py +124 -0
  107. idmtools/utils/json.py +82 -0
  108. idmtools/utils/language.py +107 -0
  109. idmtools/utils/local_os.py +40 -0
  110. idmtools/utils/time.py +22 -0
  111. idmtools-0.0.2.dist-info/METADATA +120 -0
  112. idmtools-0.0.2.dist-info/RECORD +116 -0
  113. idmtools-0.0.2.dist-info/entry_points.txt +9 -0
  114. idmtools-0.0.2.dist-info/licenses/LICENSE.TXT +3 -0
  115. idmtools-0.0.0.dev0.dist-info/METADATA +0 -41
  116. idmtools-0.0.0.dev0.dist-info/RECORD +0 -5
  117. {idmtools-0.0.0.dev0.dist-info → idmtools-0.0.2.dist-info}/WHEEL +0 -0
  118. {idmtools-0.0.0.dev0.dist-info → idmtools-0.0.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,325 @@
1
+ """
2
+ TemplatedSimulations provides a utility to build sets of simulations from a base simulation.
3
+
4
+ This is meant to be combined with builders.
5
+
6
+ Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
7
+ """
8
+ import copy
9
+ from dataclasses import dataclass, field, fields, InitVar
10
+ from functools import partial
11
+ from itertools import chain
12
+ from typing import Set, Generator, Dict, Any, List, TYPE_CHECKING, Union
13
+ from more_itertools import grouper
14
+ from idmtools.entities.itask import ITask
15
+ from idmtools.entities.simulation import Simulation
16
+ from idmtools.utils.collections import ResetGenerator
17
+ from idmtools.utils.hashing import ignore_fields_in_dataclass_on_pickle
18
+ from idmtools.builders import SimulationBuilder, ArmSimulationBuilder
19
+
20
+ if TYPE_CHECKING: # pragma: no cover
21
+ from idmtools.entities.experiment import Experiment
22
+
23
+
24
+ def simulation_generator(builders, new_sim_func, additional_sims=None, batch_size=10):
25
+ """
26
+ Generates batches of simulations from the templated simulations.
27
+
28
+ Args:
29
+ builders: List of builders to build
30
+ new_sim_func: Build new simulation callback
31
+ additional_sims: Additional simulations
32
+ batch_size: Batch size
33
+
34
+ Returns:
35
+ Generator for simulations in batches
36
+ """
37
+ if additional_sims is None:
38
+ additional_sims = []
39
+ # Then the builders
40
+ for groups in grouper(chain(*builders), batch_size):
41
+ for simulation_functions in filter(None, groups):
42
+ simulation = new_sim_func()
43
+ tags = {}
44
+
45
+ for func in simulation_functions:
46
+ new_tags = func(simulation=simulation)
47
+ if new_tags:
48
+ tags.update(new_tags)
49
+
50
+ simulation.tags.update(tags)
51
+ yield simulation
52
+
53
+ yield from additional_sims
54
+
55
+
56
+ @dataclass(repr=False)
57
+ class TemplatedSimulations:
58
+ """
59
+ Class for building templated simulations and commonly used with SimulationBuilder class.
60
+
61
+ Examples:
62
+ Add tags to all simulations via base task::
63
+
64
+ ts = TemplatedSimulations(base_task=task)
65
+ ts.tags = {'a': 'test', 'b': 9}
66
+ ts.add_builder(builder)
67
+
68
+ Add tags to a specific simulation::
69
+
70
+ experiment = Experiment.from_builder(builder, task, name=expname)
71
+ experiment.simulations = list(experiment.simulations)
72
+ experiment.simulations[2].tags['test']=123
73
+ """
74
+ builders: Set[Union[SimulationBuilder, ArmSimulationBuilder]] = field(default_factory=set, compare=False)
75
+ base_simulation: Simulation = field(default=None, compare=False, metadata={"pickle_ignore": True})
76
+ base_task: ITask = field(default=None)
77
+ parent: 'Experiment' = field(default=None)
78
+ tags: InitVar[Dict] = None
79
+ __extra_simulations: List[Simulation] = field(default_factory=list)
80
+
81
+ def __post_init__(self, tags):
82
+ """
83
+ Constructor.
84
+
85
+ Args:
86
+ tags: Tags to set on the base simulation
87
+
88
+ Returns:
89
+ None
90
+
91
+ Raises:
92
+ ValueError - If base task is not set, and base simulations is not set or bas_simulation_task is not set.
93
+ """
94
+ if self.base_task is None and (self.base_simulation is None or self.base_simulation.task is None):
95
+ raise ValueError("Either a base simulation or a base_task are required")
96
+
97
+ if self.base_simulation is None:
98
+ self.base_simulation = Simulation(task=self.base_task)
99
+ else:
100
+ self.base_task = self.base_simulation.task
101
+
102
+ if tags and not isinstance(tags, property):
103
+ self.base_simulation.tags.update(tags)
104
+
105
+ @property
106
+ def builder(self) -> Union[SimulationBuilder, ArmSimulationBuilder]:
107
+ """
108
+ For backward-compatibility purposes.
109
+
110
+ Returns:
111
+ The last ``TExperimentBuilder``.
112
+ """
113
+ return list(self.builders)[-1] if self.builders and len(self.builders) > 0 else None
114
+
115
+ @builder.setter
116
+ def builder(self, builder: Union[SimulationBuilder, ArmSimulationBuilder]) -> None:
117
+ """
118
+ For backward-compatibility purposes.
119
+
120
+ Args:
121
+ builder: The new builder to be used.
122
+
123
+ Returns:
124
+ None
125
+ """
126
+ # Make sure we only take the last builder assignment
127
+ if self.builders:
128
+ self.builders.clear()
129
+
130
+ self.add_builder(builder)
131
+
132
+ def add_builder(self, builder: Union[SimulationBuilder, ArmSimulationBuilder]) -> None:
133
+ """
134
+ Add builder to builder collection.
135
+
136
+ Args:
137
+ builder: A builder to be added.
138
+
139
+ Returns:
140
+ None
141
+
142
+ Raises:
143
+ ValueError - Builder must be type of SimulationBuilder
144
+ """
145
+ # Add builder validation
146
+ if not isinstance(builder, (SimulationBuilder, ArmSimulationBuilder)):
147
+ raise ValueError("Builder ({}) must have type of ExperimentBuilder!".format(builder))
148
+
149
+ # Initialize builders the first time
150
+ if self.builders is None:
151
+ self.builders = set()
152
+
153
+ # Add new builder to the collection
154
+ self.builders.add(builder)
155
+
156
+ @property
157
+ def pickle_ignore_fields(self):
158
+ """
159
+ Fields that we should ignore on the object.
160
+
161
+ Returns:
162
+ Fields to ignore
163
+ """
164
+ return set(f.name for f in fields(self) if "pickle_ignore" in f.metadata and f.metadata["pickle_ignore"])
165
+
166
+ def display(self):
167
+ """
168
+ Display the templated simulation.
169
+
170
+ Returns:
171
+ None
172
+ """
173
+ from idmtools.utils.display import display, experiment_table_display
174
+ display(self, experiment_table_display)
175
+
176
+ def simulations(self) -> Generator[Simulation, None, None]:
177
+ """
178
+ Simulations iterator.
179
+
180
+ Returns:
181
+ Simulation iterator
182
+ """
183
+ p = partial(simulation_generator, self.builders, self.new_simulation, self.__extra_simulations)
184
+ return ResetGenerator(p)
185
+
186
+ def extra_simulations(self) -> List[Simulation]:
187
+ """
188
+ Returns the extra simulations defined on template.
189
+
190
+ Returns:
191
+ Returns the extra simulations defined
192
+ """
193
+ return self.__extra_simulations
194
+
195
+ def add_simulation(self, simulation: Simulation):
196
+ """
197
+ Add a simulation that was built outside template engine to template generator.
198
+
199
+ This is useful we you can build most simulations through a template but need a some that cannot. This is especially true
200
+ for large simulation sets.
201
+
202
+ Args:
203
+ simulation: Simulation to add
204
+
205
+ Returns:
206
+ None
207
+ """
208
+ self.__extra_simulations.append(simulation)
209
+
210
+ def add_simulations(self, simulations: List[Simulation]):
211
+ """
212
+ Add multiple simulations without templating. See add_simulation.
213
+
214
+ Args:
215
+ simulations: Simulation to add
216
+
217
+ Returns:
218
+ None
219
+ """
220
+ self.__extra_simulations.extend(simulations)
221
+
222
+ def new_simulation(self):
223
+ """
224
+ Return a new simulation object.
225
+
226
+ The simulation will be copied from the base simulation of the experiment.
227
+
228
+ Returns:
229
+ The created simulation.
230
+ """
231
+ # TODO: the experiment should be frozen when the first simulation is created
232
+ sim = copy.deepcopy(self.base_simulation)
233
+ # Set UID=none to ensure it is regenerated
234
+ sim._uid = None
235
+ sim.assets = copy.deepcopy(self.base_simulation.assets)
236
+ sim.parent = self.parent
237
+ return sim
238
+
239
+ @property
240
+ def tags(self): # noqa: F811
241
+ """
242
+ Get tags for the base simulation.
243
+
244
+ Returns:
245
+ Tags for base simulation
246
+ """
247
+ return self.base_simulation.tags
248
+
249
+ @tags.setter
250
+ def tags(self, tags):
251
+ """
252
+ Set tags on the base simulation.
253
+
254
+ Args:
255
+ tags: Tags to set
256
+
257
+ Returns:
258
+ None
259
+ """
260
+ self.base_simulation.tags = tags
261
+
262
+ def __iter__(self):
263
+ """
264
+ Iterator over the simulations.
265
+
266
+ Returns:
267
+ Simulations itero
268
+ """
269
+ return self.simulations()
270
+
271
+ def __getstate__(self):
272
+ """
273
+ Ignore the fields in pickle_ignore_fields during pickling.
274
+ """
275
+ return ignore_fields_in_dataclass_on_pickle(self)
276
+
277
+ def __setstate__(self, state):
278
+ """
279
+ Add ignored fields back since they don't exist in the pickle.
280
+ """
281
+ self.__dict__.update(state)
282
+
283
+ def __len__(self):
284
+ """
285
+ Length of the templated simulations.
286
+
287
+ Returns:
288
+ Total number of simulations
289
+ """
290
+ return sum([len(b) for b in self.builders]) + len(self.__extra_simulations)
291
+
292
+ @classmethod
293
+ def from_task(cls, task: ITask, tags: Dict[str, Any] = None) -> 'TemplatedSimulations':
294
+ """
295
+ Creates a templated simulation from a task.
296
+
297
+ We use the task to set as base_task, and the tags are applied to the base simulation we need internally.
298
+
299
+ Args:
300
+ task: Task to use as base task
301
+ tags: Tags to add to base simulation
302
+
303
+ Returns:
304
+ TemplatedSimulations from the task
305
+ """
306
+ return TemplatedSimulations(base_task=task, tags=tags)
307
+
308
+ def check_duplicate(self, simulation_id: str) -> bool:
309
+ """
310
+ Check if a simulation id is already in the templated simulations.
311
+ Args:
312
+ simulation_id:
313
+
314
+ Returns:
315
+ True if the simulation id is already in the templated simulations, False otherwise.
316
+ """
317
+ ids = [sim.id for sim in self.__extra_simulations]
318
+ return simulation_id in ids
319
+
320
+ def clear_extra_simulation_directory_cache(self):
321
+ """
322
+ Clear templated extra simulations directory cache.
323
+ """
324
+ for sim in self.__extra_simulations:
325
+ sim._platform_directory = None
@@ -0,0 +1,71 @@
1
+ """
2
+ Frozen_dict provided utilities for a read-only dict.
3
+
4
+ Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
5
+ """
6
+ from collections import UserDict
7
+ from idmtools.frozen.ifrozen import IFrozen
8
+
9
+
10
+ class ImDict(UserDict, IFrozen):
11
+ """
12
+ ImDict is a frozen wrapper for dict.
13
+ """
14
+
15
+ def __setitem__(self, *args, **kwargs): # real signature unknown
16
+ """Set self[key] to value."""
17
+ if self._frozen:
18
+ raise Exception('Frozen')
19
+ super().__setitem__(*args, **kwargs)
20
+
21
+ def __delitem__(self, *args, **kwargs): # real signature unknown
22
+ """Delete self[key]."""
23
+ if self._frozen:
24
+ raise Exception('Frozen')
25
+ super().__delitem__(*args, **kwargs)
26
+
27
+ def setdefault(self, *args, **kwargs): # real signature unknown
28
+ """
29
+ Insert key with a value of default if key is not in the dictionary.
30
+
31
+ Return the value for key if key is in the dictionary, else default.
32
+ """
33
+ if self._frozen:
34
+ raise Exception('Frozen')
35
+ super().setdefault(*args, **kwargs)
36
+
37
+ def update(self, E=None, **F): # known special case of dict.update
38
+ """
39
+ Update the dict.
40
+
41
+ D.update([E, ]**F) -> None. Update D from dict/iterable E and F.
42
+
43
+ If E is present and has a .keys() method, then does: for k in E: D[k] = E[k]
44
+ If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v
45
+ In either case, this is followed by: for k in F: D[k] = F[k]
46
+ """
47
+ if self._frozen:
48
+ raise Exception('Frozen')
49
+ super().update(E, **F)
50
+
51
+ def pop(self, k, d=None): # real signature unknown; restored from __doc__
52
+ """
53
+ Pop from dictionary.
54
+
55
+ D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
56
+
57
+ If key is not found, d is returned if given, otherwise KeyError is raised
58
+ """
59
+ if self._frozen:
60
+ raise Exception('Frozen')
61
+ super().pop(k, d)
62
+
63
+ def popitem(self): # real signature unknown; restored from __doc__
64
+ """
65
+ Pop item from dictionary.
66
+
67
+ Popitem - D.popitem() -> (k, v), remove and return some (key, value) pair as a 2-tuple; but raise KeyError if D is empty.
68
+ """
69
+ if self._frozen:
70
+ raise Exception('Frozen')
71
+ super().popitem()
@@ -0,0 +1,66 @@
1
+ """
2
+ Frozen_list provided utilities for a read-only list.
3
+
4
+ Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
5
+ """
6
+ from collections import UserList
7
+ from idmtools.frozen.ifrozen import IFrozen
8
+
9
+
10
+ class ImList(UserList, IFrozen):
11
+ """FrozenList wrapper."""
12
+ def append(self, *args, **kwargs): # real signature unknown
13
+ """Append object to the end of the list."""
14
+ if self._frozen:
15
+ raise Exception('Frozen')
16
+ super().append(*args, **kwargs)
17
+
18
+ def clear(self, *args, **kwargs): # real signature unknown
19
+ """Remove all items from list."""
20
+ if self._frozen:
21
+ raise Exception('Frozen')
22
+ super().clear(*args, **kwargs)
23
+
24
+ def extend(self, *args, **kwargs): # real signature unknown
25
+ """Extend list by appending elements from the iterable."""
26
+ if self._frozen:
27
+ raise Exception('Frozen')
28
+ super().extend(*args, **kwargs)
29
+
30
+ def insert(self, *args, **kwargs): # real signature unknown
31
+ """Insert object before index."""
32
+ if self._frozen:
33
+ raise Exception('Frozen')
34
+ super().insert(*args, **kwargs)
35
+
36
+ def pop(self, *args, **kwargs): # real signature unknown
37
+ """
38
+ Remove and return item at index (default last).
39
+
40
+ Raises IndexError if list is empty or index is out of range.
41
+ """
42
+ if self._frozen:
43
+ raise Exception('Frozen')
44
+ super().pop(*args, **kwargs)
45
+
46
+ def remove(self, *args, **kwargs): # real signature unknown
47
+ """
48
+ Remove first occurrence of value.
49
+
50
+ Raises ValueError if the value is not present.
51
+ """
52
+ if self._frozen:
53
+ raise Exception('Frozen')
54
+ super().remove(*args, **kwargs)
55
+
56
+ def __setitem__(self, key, item):
57
+ """Set item. Raises exception if frozen."""
58
+ if self._frozen:
59
+ raise Exception('Frozen')
60
+ super().__setitem__(key, item)
61
+
62
+ def __delitem__(self, key):
63
+ """Delete item. Raises exception if frozen."""
64
+ if self._frozen:
65
+ raise Exception('Frozen')
66
+ super().__delitem__(key)
@@ -0,0 +1,86 @@
1
+ """
2
+ Frozen_set provided utilities for a read-only set.
3
+
4
+ Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
5
+ """
6
+ from idmtools.frozen.ifrozen import IFrozen
7
+
8
+
9
+ class ImSet(set, IFrozen):
10
+ """
11
+ ImSet is a frozen wrapper for Sets.
12
+ """
13
+
14
+ def add(self, *args, **kwargs): # real signature unknown
15
+ """
16
+ Add an element to a set.
17
+
18
+ This has no effect if the element is already present.
19
+ """
20
+ if self._frozen:
21
+ raise Exception('Frozen')
22
+ super().add(*args, **kwargs)
23
+
24
+ def clear(self, *args, **kwargs): # real signature unknown
25
+ """Remove all elements from this set."""
26
+ if self._frozen:
27
+ raise Exception('Frozen')
28
+ super().clear(*args, **kwargs)
29
+
30
+ def difference_update(self, *args, **kwargs): # real signature unknown
31
+ """Remove all elements of another set from this set."""
32
+ if self._frozen:
33
+ raise Exception('Frozen')
34
+ super().difference_update(*args, **kwargs)
35
+
36
+ def discard(self, *args, **kwargs): # real signature unknown
37
+ """
38
+ Remove an element from a set if it is a member.
39
+
40
+ If the element is not a member, do nothing.
41
+ """
42
+ if self._frozen:
43
+ raise Exception('Frozen')
44
+ super().discard(*args, **kwargs)
45
+
46
+ def intersection_update(self, *args, **kwargs): # real signature unknown
47
+ """Update a set with the intersection of itself and another."""
48
+ if self._frozen:
49
+ raise Exception('Frozen')
50
+ super().intersection_update(*args, **kwargs)
51
+
52
+ def pop(self, *args, **kwargs): # real signature unknown
53
+ """
54
+ Remove and return an arbitrary set element.
55
+
56
+ Raises KeyError if the set is empty.
57
+ """
58
+ if self._frozen:
59
+ raise Exception('Frozen')
60
+ super().pop(*args, **kwargs)
61
+
62
+ def remove(self, *args, **kwargs): # real signature unknown
63
+ """
64
+ Remove an element from a set; it must be a member.
65
+
66
+ If the element is not a member, raise a KeyError.
67
+ """
68
+ if self._frozen:
69
+ raise Exception('Frozen')
70
+ super().remove(*args, **kwargs)
71
+
72
+ def union(self, *args, **kwargs): # real signature unknown
73
+ """
74
+ Return the union of sets as a new set.
75
+
76
+ (i.e. all elements that are in either set.)
77
+ """
78
+ if self._frozen:
79
+ raise Exception('Frozen')
80
+ super().union(*args, **kwargs)
81
+
82
+ def update(self, *args, **kwargs): # real signature unknown
83
+ """Update a set with the union of itself and others."""
84
+ if self._frozen:
85
+ raise Exception('Frozen')
86
+ super().update(*args, **kwargs)
@@ -0,0 +1,18 @@
1
+ """
2
+ Frozen_tuple provided utilities for a read-only tuple.
3
+
4
+ Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
5
+ """
6
+ from idmtools.frozen.ifrozen import IFrozen
7
+
8
+
9
+ class ImTuple(tuple, IFrozen):
10
+ """
11
+ Doc: Once a tuple is created, you cannot add items to it. Tuples are unchangeable.
12
+ """
13
+
14
+ def __add__(self, *args, **kwargs): # real signature unknown
15
+ """Return self+value."""
16
+ if self._frozen:
17
+ raise Exception('Frozen')
18
+ super().__add__(*args, **kwargs)