fameio 3.2.0__py3-none-any.whl → 3.4.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.
Files changed (53) hide show
  1. fameio/cli/convert_results.py +4 -6
  2. fameio/cli/make_config.py +3 -5
  3. fameio/cli/options.py +6 -4
  4. fameio/cli/parser.py +53 -29
  5. fameio/cli/reformat.py +58 -0
  6. fameio/input/__init__.py +4 -4
  7. fameio/input/loader/__init__.py +4 -6
  8. fameio/input/loader/controller.py +11 -16
  9. fameio/input/loader/loader.py +11 -9
  10. fameio/input/metadata.py +26 -29
  11. fameio/input/resolver.py +4 -6
  12. fameio/input/scenario/agent.py +18 -16
  13. fameio/input/scenario/attribute.py +85 -31
  14. fameio/input/scenario/contract.py +78 -38
  15. fameio/input/scenario/exception.py +3 -6
  16. fameio/input/scenario/fameiofactory.py +7 -12
  17. fameio/input/scenario/generalproperties.py +7 -8
  18. fameio/input/scenario/scenario.py +14 -18
  19. fameio/input/scenario/stringset.py +5 -6
  20. fameio/input/schema/agenttype.py +8 -10
  21. fameio/input/schema/attribute.py +30 -36
  22. fameio/input/schema/java_packages.py +6 -7
  23. fameio/input/schema/schema.py +9 -11
  24. fameio/input/validator.py +178 -41
  25. fameio/input/writer.py +20 -29
  26. fameio/logs.py +28 -19
  27. fameio/output/agent_type.py +14 -16
  28. fameio/output/conversion.py +9 -12
  29. fameio/output/csv_writer.py +33 -23
  30. fameio/output/data_transformer.py +11 -11
  31. fameio/output/execution_dao.py +170 -0
  32. fameio/output/input_dao.py +16 -19
  33. fameio/output/output_dao.py +7 -7
  34. fameio/output/reader.py +8 -10
  35. fameio/output/yaml_writer.py +2 -3
  36. fameio/scripts/__init__.py +15 -4
  37. fameio/scripts/convert_results.py +18 -17
  38. fameio/scripts/exception.py +1 -1
  39. fameio/scripts/make_config.py +3 -4
  40. fameio/scripts/reformat.py +71 -0
  41. fameio/scripts/reformat.py.license +3 -0
  42. fameio/series.py +78 -47
  43. fameio/time.py +56 -18
  44. fameio/tools.py +42 -4
  45. {fameio-3.2.0.dist-info → fameio-3.4.0.dist-info}/METADATA +64 -40
  46. fameio-3.4.0.dist-info/RECORD +60 -0
  47. {fameio-3.2.0.dist-info → fameio-3.4.0.dist-info}/entry_points.txt +1 -0
  48. fameio-3.2.0.dist-info/RECORD +0 -56
  49. {fameio-3.2.0.dist-info → fameio-3.4.0.dist-info}/LICENSE.txt +0 -0
  50. {fameio-3.2.0.dist-info → fameio-3.4.0.dist-info}/LICENSES/Apache-2.0.txt +0 -0
  51. {fameio-3.2.0.dist-info → fameio-3.4.0.dist-info}/LICENSES/CC-BY-4.0.txt +0 -0
  52. {fameio-3.2.0.dist-info → fameio-3.4.0.dist-info}/LICENSES/CC0-1.0.txt +0 -0
  53. {fameio-3.2.0.dist-info → fameio-3.4.0.dist-info}/WHEEL +0 -0
@@ -16,7 +16,7 @@ from fameio.tools import keys_to_lower
16
16
 
17
17
 
18
18
  class AttributeType(Enum):
19
- """Data types that Attributes can take"""
19
+ """Data types that Attributes can take."""
20
20
 
21
21
  INTEGER = auto()
22
22
  DOUBLE = auto()
@@ -57,7 +57,7 @@ class AttributeType(Enum):
57
57
 
58
58
 
59
59
  class AttributeSpecs(Metadata):
60
- """Schema Definition of a single Attribute (with possible inner Attributes) of an agent"""
60
+ """Schema Definition of a single Attribute (with possible inner Attributes) of an agent."""
61
61
 
62
62
  _DISALLOWED_NAMES = ["value", "values", "metadata"]
63
63
  _SEPARATOR = "."
@@ -83,8 +83,7 @@ class AttributeSpecs(Metadata):
83
83
  _NAME_DISALLOWED = f"Attribute name must not be empty and none of: {_DISALLOWED_NAMES}"
84
84
 
85
85
  def __init__(self, name: str, definition: dict):
86
- """
87
- Loads Attribute from given `definition`
86
+ """Loads Attribute from given `definition`.
88
87
 
89
88
  Args:
90
89
  name: of attribute type
@@ -115,8 +114,7 @@ class AttributeSpecs(Metadata):
115
114
 
116
115
  @staticmethod
117
116
  def _assert_is_allowed_name(full_name: str) -> None:
118
- """
119
- Raises SchemaError if provided name is not allowed for Attributes
117
+ """Raises SchemaError if provided name is not allowed for Attributes.
120
118
 
121
119
  Args:
122
120
  full_name: to be checked if it can serve as name for an attribute
@@ -134,7 +132,7 @@ class AttributeSpecs(Metadata):
134
132
 
135
133
  @staticmethod
136
134
  def _get_is_mandatory(definition: dict, name: str) -> bool:
137
- """Returns True if `Mandatory` is set to True or if specification is missing; False otherwise"""
135
+ """Returns True if `Mandatory` is set to True or if specification is missing; False otherwise."""
138
136
  if AttributeSpecs.KEY_MANDATORY in definition:
139
137
  return definition[AttributeSpecs.KEY_MANDATORY]
140
138
  log().warning(AttributeSpecs._MISSING_SPEC_DEFAULT.format(AttributeSpecs.KEY_MANDATORY, name, True))
@@ -142,7 +140,7 @@ class AttributeSpecs(Metadata):
142
140
 
143
141
  @staticmethod
144
142
  def _get_is_list(definition: dict, name: str) -> bool:
145
- """Returns True if `List` is set to True; Returns False otherwise or if specification is missing"""
143
+ """Returns True if `List` is set to True; Returns False otherwise or if specification is missing."""
146
144
  if AttributeSpecs.KEY_LIST in definition:
147
145
  return definition[AttributeSpecs.KEY_LIST]
148
146
  log().warning(AttributeSpecs._MISSING_SPEC_DEFAULT.format(AttributeSpecs.KEY_LIST, name, False))
@@ -150,8 +148,7 @@ class AttributeSpecs(Metadata):
150
148
 
151
149
  @staticmethod
152
150
  def _get_type(definition: dict, name: str) -> AttributeType:
153
- """
154
- Returns `AttributeType` from given definition
151
+ """Returns `AttributeType` from given definition.
155
152
 
156
153
  Args:
157
154
  definition: of the attribute
@@ -172,7 +169,7 @@ class AttributeSpecs(Metadata):
172
169
  raise log_error(SchemaError(AttributeSpecs._MISSING_TYPE.format(name)))
173
170
 
174
171
  def _get_allowed_values(self, definition: dict) -> ValueContainer:
175
- """Returns ValueContainer with allowed values if defined; otherwise an empty ValueContainer"""
172
+ """Returns ValueContainer with allowed values if defined; otherwise an empty ValueContainer."""
176
173
  allowed_values: ValueContainer = ValueContainer()
177
174
  if AttributeSpecs.KEY_VALUES in definition:
178
175
  value_definition = definition[AttributeSpecs.KEY_VALUES]
@@ -181,9 +178,9 @@ class AttributeSpecs(Metadata):
181
178
  return allowed_values
182
179
 
183
180
  def _read_values(self, definition: dict | list) -> ValueContainer:
184
- """
185
- Returns accepted values mapped to their additional metadata specifications extracted from given `definition`
186
- Accepts lists of accepted values or dictionaries with (optional) metadata assigned to each value
181
+ """Returns acceptable values mapped to their optional metadata specifications extracted from given `definition`.
182
+
183
+ Accepts lists of values or dictionaries with (optional) metadata assigned to each value
187
184
 
188
185
  Args:
189
186
  definition: list of acceptable values or dict with acceptable values as keys and (optional) metadata content
@@ -192,7 +189,7 @@ class AttributeSpecs(Metadata):
192
189
  Mapping of acceptable values to their associated Metadata
193
190
 
194
191
  Raises:
195
- SchemaError: if values could not be parsed, logged with level "ERROR"
192
+ SchemaError: if values could not be parsed or do not match the attribute type, logged with level "ERROR"
196
193
  """
197
194
  try:
198
195
  value_container = ValueContainer(definition)
@@ -203,8 +200,7 @@ class AttributeSpecs(Metadata):
203
200
  raise log_error(SchemaError(AttributeSpecs._VALUES_ILL_FORMAT.format(definition))) from e
204
201
 
205
202
  def _convert_to_data_type(self, value: str, section: str) -> int | float | str:
206
- """
207
- Returns a given single `value` in `section` converted to this Attribute's data type
203
+ """Returns a given single `value` in `section` converted to this Attribute's data type.
208
204
 
209
205
  Args:
210
206
  value: to be converted
@@ -222,7 +218,7 @@ class AttributeSpecs(Metadata):
222
218
  raise log_error(SchemaError(AttributeSpecs._INCOMPATIBLE.format(value, section, self._attr_type))) from e
223
219
 
224
220
  def _get_default_value(self, definition: dict) -> int | float | str | list | None:
225
- """Returns default value(s) from given definitions, or None if no default is specified"""
221
+ """Returns default value(s) from given definitions, or None if no default is specified."""
226
222
  if AttributeSpecs.KEY_DEFAULT in definition:
227
223
  provided_value = definition[AttributeSpecs.KEY_DEFAULT]
228
224
  if self._is_list:
@@ -231,8 +227,7 @@ class AttributeSpecs(Metadata):
231
227
  return None
232
228
 
233
229
  def _convert_list(self, values) -> list:
234
- """
235
- Converts all entries in given `values` list to this attribute data type and returns this new list
230
+ """Converts all entries in given `values` list to this attribute data type and returns this new list.
236
231
 
237
232
  Args:
238
233
  values: to be converted to a list of default values
@@ -248,8 +243,7 @@ class AttributeSpecs(Metadata):
248
243
  raise log_error(SchemaError(AttributeSpecs._DEFAULT_NOT_LIST.format(values)))
249
244
 
250
245
  def _convert_and_test(self, value: str):
251
- """
252
- Converts a given single `value` to this Attribute's data type and tests if the value is allowed
246
+ """Converts a given single `value` to this Attribute's data type and tests if the value is allowed.
253
247
 
254
248
  Args:
255
249
  value: to be converted and tested
@@ -268,7 +262,7 @@ class AttributeSpecs(Metadata):
268
262
 
269
263
  @staticmethod
270
264
  def _get_nested_attributes(definition: dict, name: str) -> dict[str, AttributeSpecs]:
271
- """Returns dict of nested attributes read from given definition; empty dict if no nested attributes exist"""
265
+ """Returns dict of nested attributes read from given definition; empty dict if no nested attributes exist."""
272
266
  nested_attributes = {}
273
267
  if AttributeSpecs.KEY_NESTED in definition:
274
268
  for nested_name, nested_details in definition[AttributeSpecs.KEY_NESTED].items():
@@ -278,67 +272,67 @@ class AttributeSpecs(Metadata):
278
272
 
279
273
  @staticmethod
280
274
  def _get_help(definition) -> str:
281
- """Returns (possible empty) help text if provided in definition; None otherwise"""
275
+ """Returns (possible empty) help text if provided in definition; None otherwise."""
282
276
  return definition.get(AttributeSpecs.KEY_HELP, "").strip()
283
277
 
284
278
  @property
285
279
  def attr_type(self) -> AttributeType:
286
- """Returns AttributeType of this attribute"""
280
+ """Returns AttributeType of this attribute."""
287
281
  return self._attr_type
288
282
 
289
283
  @property
290
284
  def values(self) -> list:
291
- """Returns the list of allowed values for this attribute"""
285
+ """Returns the list of allowed values for this attribute."""
292
286
  return self._allowed_values.as_list()
293
287
 
294
288
  @property
295
289
  def has_value_restrictions(self) -> bool:
296
- """Returns True if the attribute can only take a set of certain values"""
290
+ """Returns True if the attribute can only take a set of certain values."""
297
291
  return not self._allowed_values.is_empty()
298
292
 
299
293
  @property
300
294
  def is_list(self) -> bool:
301
- """Return True if this attribute type is a list"""
295
+ """Return True if this attribute type is a list."""
302
296
  return self._is_list
303
297
 
304
298
  @property
305
299
  def has_nested_attributes(self) -> bool:
306
- """Returns True if nested attributes are defined"""
300
+ """Returns True if nested attributes are defined."""
307
301
  return bool(self._nested_attributes)
308
302
 
309
303
  @property
310
304
  def nested_attributes(self) -> dict[str, AttributeSpecs]:
311
- """Returns list of nested Attributes of this Attribute or an empty dict if no nested attributes are defined"""
305
+ """Returns list of nested Attributes of this Attribute or an empty dict if no nested attributes are defined."""
312
306
  return self._nested_attributes
313
307
 
314
308
  @property
315
309
  def has_default_value(self) -> bool:
316
- """Return True if a default value is available"""
310
+ """Return True if a default value is available."""
317
311
  return self._default_value is not None
318
312
 
319
313
  @property
320
314
  def default_value(self) -> Any | None:
321
- """Return the default value of this attribute, or None if no default is specified"""
315
+ """Return the default value of this attribute, or None if no default is specified."""
322
316
  return self._default_value
323
317
 
324
318
  @property
325
319
  def is_mandatory(self) -> bool:
326
- """Return True if this attribute is mandatory"""
320
+ """Return True if this attribute is mandatory."""
327
321
  return self._is_mandatory
328
322
 
329
323
  @property
330
324
  def full_name(self) -> str:
331
- """Returns name including name of enclosing parent attributes"""
325
+ """Returns name including name of enclosing parent attributes."""
332
326
  return self._full_name
333
327
 
334
328
  @property
335
329
  def has_help_text(self) -> bool:
336
- """Return True if a help_text is available"""
330
+ """Return True if a help_text is available."""
337
331
  return bool(self._help)
338
332
 
339
333
  @property
340
334
  def help_text(self) -> str:
341
- """Return the help_text of this attribute, if any"""
335
+ """Return the help_text of this attribute, if any."""
342
336
  return self._help
343
337
 
344
338
  def _to_dict(self) -> dict[str, Any]:
@@ -11,7 +11,7 @@ from fameio.tools import keys_to_lower
11
11
 
12
12
 
13
13
  class JavaPackages:
14
- """Schema definitions for Java package names in which model classes reside"""
14
+ """Schema definitions for Java package names in which model classes reside."""
15
15
 
16
16
  KEY_AGENT: Final[str] = "Agents".lower()
17
17
  KEY_DATA_ITEM: Final[str] = "DataItems".lower()
@@ -28,8 +28,7 @@ class JavaPackages:
28
28
 
29
29
  @classmethod
30
30
  def from_dict(cls, definitions: dict[str, list[str]]) -> JavaPackages:
31
- """
32
- Creates JavaPackages from a dictionary representation
31
+ """Creates JavaPackages from a dictionary representation.
33
32
 
34
33
  Args:
35
34
  definitions: dictionary representation of JavaPackages
@@ -58,19 +57,19 @@ class JavaPackages:
58
57
 
59
58
  @property
60
59
  def agents(self) -> list[str]:
61
- """Return list of java package names that contain the model's Agents"""
60
+ """Return list of java package names that contain the model's Agents."""
62
61
  return self._agents
63
62
 
64
63
  @property
65
64
  def data_items(self) -> list[str]:
66
- """Return list of java package names that contain the model's DataItems"""
65
+ """Return list of java package names that contain the model's DataItems."""
67
66
  return self._data_items
68
67
 
69
68
  @property
70
69
  def portables(self) -> list[str]:
71
- """Return list of java package names that contain the model's Portables"""
70
+ """Return list of java package names that contain the model's Portables."""
72
71
  return self._portables
73
72
 
74
73
  def to_dict(self) -> dict[str, list[str]]:
75
- """Return dictionary representation of this JavaPackages object"""
74
+ """Return dictionary representation of this JavaPackages object."""
76
75
  return {self.KEY_AGENT: self.agents, self.KEY_DATA_ITEM: self.data_items, self.KEY_PORTABLE: self.portables}
@@ -14,7 +14,7 @@ from .java_packages import JavaPackages
14
14
 
15
15
 
16
16
  class Schema:
17
- """Definition of a schema"""
17
+ """Definition of a schema."""
18
18
 
19
19
  KEY_AGENT_TYPE: Final[str] = "AgentTypes".lower()
20
20
  KEY_PACKAGES: Final[str] = "JavaPackages".lower()
@@ -30,14 +30,13 @@ class Schema:
30
30
 
31
31
  @classmethod
32
32
  def from_dict(cls, definitions: dict) -> Schema:
33
- """
34
- Load given dictionary `definitions` into a new schema
33
+ """Convert given `definitions` into a new schema.
35
34
 
36
35
  Args:
37
36
  definitions: dictionary representation of schema
38
37
 
39
38
  Returns:
40
- new Schema
39
+ schema created from given definitions
41
40
 
42
41
  Raises:
43
42
  SchemaError: if definitions are incomplete or erroneous, logged on level "ERROR"
@@ -59,8 +58,7 @@ class Schema:
59
58
 
60
59
  @staticmethod
61
60
  def _get_or_raise(definitions: dict[str, Any], key: str, error_message: str) -> Any:
62
- """
63
- Get given `key` from given `definitions` - raise error with given `error_message` if not present
61
+ """Get given `key` from given `definitions` - raise error with given `error_message` if not present.
64
62
 
65
63
  Args:
66
64
  definitions: to search the key in
@@ -79,25 +77,25 @@ class Schema:
79
77
 
80
78
  @classmethod
81
79
  def from_string(cls, definitions: str) -> Schema:
82
- """Load given string `definitions` into a new Schema"""
80
+ """Load given string `definitions` into a new Schema."""
83
81
  return cls.from_dict(ast.literal_eval(definitions))
84
82
 
85
83
  def to_dict(self) -> dict:
86
- """Serializes the schema content to a dict"""
84
+ """Serializes the schema content to a dict."""
87
85
  return self._original_input_dict
88
86
 
89
87
  def to_string(self) -> str:
90
- """Returns a string representation of the Schema of which the class can be rebuilt"""
88
+ """Returns a string representation of the Schema of which the class can be rebuilt."""
91
89
  return repr(self.to_dict())
92
90
 
93
91
  @property
94
92
  def agent_types(self) -> dict[str, AgentType]:
95
- """Returns all the agent types by their name"""
93
+ """Returns all the agent types by their name."""
96
94
  return self._agent_types
97
95
 
98
96
  @property
99
97
  def packages(self) -> JavaPackages:
100
- """Returns JavaPackages, i.e. names where model classes are defined in"""
98
+ """Returns JavaPackages, i.e. names where model classes are defined in."""
101
99
  if self._packages is None:
102
100
  raise log_error(SchemaError(self._ERR_MISSING_PACKAGES))
103
101
  return self._packages