pyibis-ami 7.2.3__py3-none-any.whl → 7.2.5__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.
@@ -1,324 +1,325 @@
1
- """``AMIParameter`` class definition, plus some helpers.
2
-
3
- Original author: David Banas <capn.freako@gmail.com>
4
-
5
- Original date: December 24, 2016
6
-
7
- Copyright (c) 2019 David Banas; all rights reserved World wide.
8
- """
9
-
10
- #####
11
- # AMI parameter
12
- #####
13
-
14
-
15
- class AMIParamError(Exception):
16
- """Base Exception for all AMI Parameter Errors."""
17
-
18
-
19
- class AMIParameter: # pylint: disable=too-many-instance-attributes,too-few-public-methods
20
- """IBIS-AMI model parameter.
21
-
22
- This class encapsulates the attributes and behavior of a AMI
23
- parameter.
24
- """
25
-
26
- # Properties.
27
-
28
- # Note: They are read-only, despite the presence of apparent setters.
29
- # (The idea is that, once initialized, parameter definitions
30
- # are immutable.)
31
- # The only exception to this is pvalue, which has been made
32
- # writable, for scripted non-GUI use cases.
33
- # Be very careful w/ this; there is NO CHECKING!
34
-
35
- # Note that the setters, below, are only intended for use by
36
- # __init__(). They may raise an *AMIParamError* exception. This is
37
- # to ensure that a malformed instance never be created.
38
-
39
- def _get_name(self):
40
- """pname."""
41
- return self._name
42
-
43
- pname = property(_get_name, doc="Name of AMI parameter.")
44
-
45
- # pusage
46
- def _set_usage(self, values):
47
- "Process *Usage* tag."
48
-
49
- val = values[0]
50
- if val in ("In", "Out", "InOut", "Info"):
51
- self._usage = val
52
- else:
53
- raise AMIParamError(f"Unrecognized usage value: '{val}'.")
54
-
55
- def _get_usage(self):
56
- return self._usage
57
-
58
- pusage = property(_get_usage, doc="Value of AMI parameter 'Usage' tag.")
59
-
60
- # ptype
61
- def _set_type(self, values):
62
- "Process *Type* tag."
63
-
64
- val = values[0]
65
- if val in ("Float", "Integer", "String", "Boolean", "UI", "Tap"):
66
- self._type = val
67
- else:
68
- raise AMIParamError(f"Unrecognized type value: '{val}'.")
69
-
70
- def _get_type(self):
71
- return self._type
72
-
73
- ptype = property(_get_type, doc="Value of AMI parameter 'Type' tag.")
74
-
75
- # pformat
76
- def _set_format(self, values):
77
- "Process *Format* tag."
78
-
79
- form = values[0]
80
- if len(values) < 2:
81
- raise AMIParamError(f"No values provided for: '{form}'.")
82
- self._format = form
83
- self._format_rem = values[1:]
84
-
85
- def _get_format(self):
86
- return self._format
87
-
88
- pformat = property(_get_format, doc="Value of AMI parameter 'Format' tag.")
89
-
90
- # pvalue
91
- def _get_value(self):
92
- return self._value
93
-
94
- def _set_val(self, new_val):
95
- self._value = new_val
96
-
97
- pvalue = property(_get_value, _set_val, doc="Value of AMI parameter.")
98
-
99
- # pmin
100
- def _get_min(self):
101
- return self._min
102
-
103
- pmin = property(_get_min, doc="Minimum value of AMI parameter.")
104
-
105
- # pmax
106
- def _get_max(self):
107
- return self._max
108
-
109
- pmax = property(_get_max, doc="Maximum value of AMI parameter.")
110
-
111
- # default
112
- def _set_default(self, values):
113
- """Process *Default* tag."""
114
- self._default = values[0]
115
-
116
- def _get_default(self):
117
- return self._default
118
-
119
- pdefault = property(_get_default, doc="Default value of AMI parameter.")
120
-
121
- # pdescription
122
- def _set_description(self, values):
123
- """Process *Description* tag."""
124
- self._description = values[0]
125
-
126
- def _get_description(self):
127
- return self._description
128
-
129
- pdescription = property(_get_description, doc="Description of AMI parameter.")
130
-
131
- # plist_tip
132
- def _set_list_tip(self, values):
133
- """Process *List_Tip* tag."""
134
- self._list_tip = [x.strip('"') for x in values]
135
-
136
- def _get_list_tip(self):
137
- return self._list_tip
138
-
139
- plist_tip = property(_get_list_tip, doc="List tips of AMI parameter.")
140
-
141
- # Helpers.
142
- # These 3 just accomodate the awkwardness caused by the optional
143
- # nature of the 'Format' keyword, in *.AMI files. Since, a properly
144
- # formed instance of *AMIParameter* will always have a *format*
145
- # property, we don't need to make these properties of that class.
146
-
147
- # value
148
- def _set_value(self, values):
149
- """Process *Value* tag."""
150
-
151
- return self._set_format(["Value"] + values)
152
-
153
- # range
154
- def _set_range(self, values):
155
- """Process *Range* tag."""
156
-
157
- return self._set_format(["Range"] + values)
158
-
159
- # usage
160
- def _set_list(self, values):
161
- """Process *List* tag."""
162
-
163
- return self._set_format(["List"] + values)
164
-
165
- # Holds any warnings encountered, during initialization.
166
- # (Any errors encountered will prevent initialization from completing.)
167
- _msg = ""
168
-
169
- def _get_msg(self):
170
- return self._msg
171
-
172
- msg = property(_get_msg, doc="Any warning messages encountered, during parameter initialization.")
173
-
174
- # This dictionary defines both:
175
- #
176
- # - the allowed parameter definition tag names, and
177
- # - their processing functions.
178
- #
179
- # The idea is to allow this class to grow along with the IBIS
180
- # standard, without having to change any of its boilerplate.
181
-
182
- _param_def_tag_procs = {
183
- "Usage": _set_usage,
184
- "Type": _set_type,
185
- "Format": _set_format,
186
- "Value": _set_value,
187
- "Range": _set_range,
188
- "List": _set_list,
189
- "Corner": _set_list,
190
- "Default": _set_default,
191
- "Description": _set_description,
192
- "List_Tip": _set_list_tip,
193
- "Label": _set_list_tip,
194
- "Labels": _set_list_tip,
195
- }
196
-
197
- def __init__(self, name, tags): # pylint: disable=too-many-branches,too-many-statements
198
- """
199
- Args:
200
- name (str): The name of the AMI parameter being created.
201
- tags ([(str, [a])]): A list of pairs, each containing
202
-
203
- - a parameter definition tag name
204
- (Must be one of the keys from the '_param_def_tag_procs' dictionary.)
205
-
206
- - a list of values to be associated with that tag.
207
- """
208
- # Initialization
209
- self._usage = None
210
- self._type = None
211
- self._format = None
212
- self._value = None
213
- self._min = None
214
- self._max = None
215
- self._default = None
216
- self._description = ""
217
- self._list_tip = None
218
-
219
- # Holds any warnings encountered, during initialization.
220
- # (Any errors encountered will prevent initialization from completing.)
221
- self._msg = ""
222
-
223
- # Process all parameter definition tags.
224
- for tag in tags:
225
- tag_name = tag[0]
226
- if tag_name in self._param_def_tag_procs:
227
- try:
228
- self._param_def_tag_procs[tag_name](self, tag[1])
229
- except AMIParamError as err:
230
- raise AMIParamError(f"Problem initializing parameter, '{name}': {err}\n") from err
231
-
232
- # Validate and complete the instance.
233
- # Check for required tags.
234
- param_usage = self._usage
235
- param_type = self._type
236
- param_format = self._format
237
- param_default = self._default
238
- if param_usage is None:
239
- raise AMIParamError("Missing 'Usage' tag!\n")
240
- if param_type is None:
241
- raise AMIParamError("Missing 'Type' tag!\n")
242
- if param_format is None:
243
- if param_default is None:
244
- raise AMIParamError("Missing both 'Format' and 'Default' tags!\n")
245
- self._value = param_default
246
- param_format = "Value"
247
- self._format_rem = [param_default]
248
- # Check for mutual exclusivity of 'Format Value' and 'Default'.
249
- elif (param_format == "Value") and (param_default is not None):
250
- self._msg += "'Format Value' and 'Default' both found! (They are mutually exclusive.)\n"
251
- # Canonicalize Boolean if necessary.
252
- elif (param_format == "List") and (param_type == "Boolean"):
253
- if param_default:
254
- self._value = param_default
255
- else:
256
- self._value = "False"
257
- param_format = "Value"
258
- self._format_rem = [self._value]
259
-
260
- # Check for 'Default' used with parameter type 'Out'.
261
- if (param_usage == "Out") and (param_default is not None):
262
- raise AMIParamError("'Default' may not be used with parameter type 'Out'!\n")
263
-
264
- # Complete the instance.
265
- vals = self._format_rem
266
- if param_format == "Value":
267
- value_str = vals[0].strip()
268
- if param_type in ("Float", "UI"):
269
- try:
270
- self._value = float(value_str)
271
- except (ValueError, TypeError) as exc:
272
- raise AMIParamError(f"Couldn't read float from '{value_str}'.\n") from exc
273
- elif param_type == "Integer":
274
- try:
275
- self._value = int(float(value_str)) # Hack to accommodate: "1e5", for instance.
276
- except (ValueError, TypeError) as exc:
277
- raise AMIParamError(f"Couldn't read integer from '{value_str}'.\n") from exc
278
- elif param_type == "Boolean":
279
- if value_str == "True":
280
- self._value = True
281
- elif value_str == "False":
282
- self._value = False
283
- else:
284
- raise AMIParamError(f"Couldn't read Boolean from '{value_str}'.\n")
285
- else:
286
- self._value = value_str.strip('"')
287
- elif param_format == "Range":
288
- if param_type not in ("Float", "Integer", "UI", "Tap"):
289
- raise AMIParamError(f"Illegal type, '{param_type}', for use with Range.\n")
290
- if len(vals) < 3:
291
- raise AMIParamError(f"Insufficient number of values, {len(vals)}, provided for Range.\n")
292
- if param_type in ("Float", "UI", "Tap"):
293
- try:
294
- temp_vals = list(map(float, vals[:3]))
295
- except (ValueError, TypeError) as exc:
296
- raise AMIParamError(f"Couldn't read floats from '{vals[:3]}'.\n") from exc
297
- else:
298
- try:
299
- temp_vals = list(map(int, vals[:3]))
300
- except (ValueError, TypeError) as exc:
301
- raise AMIParamError(f"Couldn't read integers from '{vals[:3]}'.\n") from exc
302
- self._value = temp_vals[0]
303
- self._min = temp_vals[1]
304
- self._max = temp_vals[2]
305
- else: # param_format == 'List'
306
- if param_type in ("Float", "UI"):
307
- try:
308
- temp_vals = list(map(float, vals))
309
- except (ValueError, TypeError) as exc:
310
- raise AMIParamError(f"Couldn't read floats from '{vals}'.\n") from exc
311
- elif param_type in ("Integer", "Tap"):
312
- try:
313
- temp_vals = list(map(int, vals))
314
- except (ValueError, TypeError) as exc:
315
- raise AMIParamError(f"Couldn't read integers from '{vals}'.\n") from exc
316
- else: # 'param_type' == 'String'
317
- try:
318
- temp_vals = list(map(str, vals))
319
- temp_vals = [x.strip('"') for x in temp_vals]
320
- except (ValueError, TypeError) as exc:
321
- raise AMIParamError(f"Couldn't read strings from '{vals}'.\n") from exc
322
- self._value = temp_vals
323
-
324
- self._name = name
1
+ """``AMIParameter`` class definition, plus some helpers.
2
+
3
+ Original author: David Banas <capn.freako@gmail.com>
4
+
5
+ Original date: December 24, 2016
6
+
7
+ Copyright (c) 2019 David Banas; all rights reserved World wide.
8
+ """
9
+
10
+ #####
11
+ # AMI parameter
12
+ #####
13
+
14
+
15
+ class AMIParamError(Exception):
16
+ """Base Exception for all AMI Parameter Errors."""
17
+
18
+
19
+ class AMIParameter: # pylint: disable=too-many-instance-attributes,too-few-public-methods
20
+ """IBIS-AMI model parameter.
21
+
22
+ This class encapsulates the attributes and behavior of a AMI
23
+ parameter.
24
+ """
25
+
26
+ # Properties.
27
+
28
+ # Note: They are read-only, despite the presence of apparent setters.
29
+ # (The idea is that, once initialized, parameter definitions
30
+ # are immutable.)
31
+ # The only exception to this is pvalue, which has been made
32
+ # writable, for scripted non-GUI use cases.
33
+ # Be very careful w/ this; there is NO CHECKING!
34
+
35
+ # Note that the setters, below, are only intended for use by
36
+ # __init__(). They may raise an *AMIParamError* exception. This is
37
+ # to ensure that a malformed instance never be created.
38
+
39
+ def _get_name(self):
40
+ """pname."""
41
+ return self._name
42
+
43
+ pname = property(_get_name, doc="Name of AMI parameter.")
44
+
45
+ # pusage
46
+ def _set_usage(self, values):
47
+ "Process *Usage* tag."
48
+
49
+ val = values[0]
50
+ if val in ("In", "Out", "InOut", "Info"):
51
+ self._usage = val
52
+ else:
53
+ raise AMIParamError(f"Unrecognized usage value: '{val}'.")
54
+
55
+ def _get_usage(self):
56
+ return self._usage
57
+
58
+ pusage = property(_get_usage, doc="Value of AMI parameter 'Usage' tag.")
59
+
60
+ # ptype
61
+ def _set_type(self, values):
62
+ "Process *Type* tag."
63
+
64
+ val = values[0]
65
+ if val in ("Float", "Integer", "String", "Boolean", "UI", "Tap"):
66
+ self._type = val
67
+ else:
68
+ raise AMIParamError(f"Unrecognized type value: '{val}'.")
69
+
70
+ def _get_type(self):
71
+ return self._type
72
+
73
+ ptype = property(_get_type, doc="Value of AMI parameter 'Type' tag.")
74
+
75
+ # pformat
76
+ def _set_format(self, values):
77
+ "Process *Format* tag."
78
+
79
+ form = values[0]
80
+ if len(values) < 2:
81
+ raise AMIParamError(f"No values provided for: '{form}'.")
82
+ self._format = form
83
+ self._format_rem = values[1:]
84
+
85
+ def _get_format(self):
86
+ return self._format
87
+
88
+ pformat = property(_get_format, doc="Value of AMI parameter 'Format' tag.")
89
+
90
+ # pvalue
91
+ def _get_value(self):
92
+ return self._value
93
+
94
+ def _set_val(self, new_val):
95
+ self._value = new_val
96
+
97
+ pvalue = property(_get_value, _set_val, doc="Value of AMI parameter.")
98
+
99
+ # pmin
100
+ def _get_min(self):
101
+ return self._min
102
+
103
+ pmin = property(_get_min, doc="Minimum value of AMI parameter.")
104
+
105
+ # pmax
106
+ def _get_max(self):
107
+ return self._max
108
+
109
+ pmax = property(_get_max, doc="Maximum value of AMI parameter.")
110
+
111
+ # default
112
+ def _set_default(self, values):
113
+ """Process *Default* tag."""
114
+ self._default = values[0]
115
+
116
+ def _get_default(self):
117
+ return self._default
118
+
119
+ pdefault = property(_get_default, doc="Default value of AMI parameter.")
120
+
121
+ # pdescription
122
+ def _set_description(self, values):
123
+ """Process *Description* tag."""
124
+ self._description = values[0]
125
+
126
+ def _get_description(self):
127
+ return self._description
128
+
129
+ pdescription = property(_get_description, doc="Description of AMI parameter.")
130
+
131
+ # plist_tip
132
+ def _set_list_tip(self, values):
133
+ """Process *List_Tip* tag."""
134
+ self._list_tip = [x.strip('"') for x in values]
135
+
136
+ def _get_list_tip(self):
137
+ return self._list_tip
138
+
139
+ plist_tip = property(_get_list_tip, doc="List tips of AMI parameter.")
140
+
141
+ # Helpers.
142
+ # These 3 just accomodate the awkwardness caused by the optional
143
+ # nature of the 'Format' keyword, in *.AMI files. Since, a properly
144
+ # formed instance of *AMIParameter* will always have a *format*
145
+ # property, we don't need to make these properties of that class.
146
+
147
+ # value
148
+ def _set_value(self, values):
149
+ """Process *Value* tag."""
150
+
151
+ return self._set_format(["Value"] + values)
152
+
153
+ # range
154
+ def _set_range(self, values):
155
+ """Process *Range* tag."""
156
+
157
+ return self._set_format(["Range"] + values)
158
+
159
+ # usage
160
+ def _set_list(self, values):
161
+ """Process *List* tag."""
162
+
163
+ return self._set_format(["List"] + values)
164
+
165
+ # Holds any warnings encountered, during initialization.
166
+ # (Any errors encountered will prevent initialization from completing.)
167
+ _msg = ""
168
+
169
+ def _get_msg(self):
170
+ return self._msg
171
+
172
+ msg = property(_get_msg, doc="Any warning messages encountered, during parameter initialization.")
173
+
174
+ # This dictionary defines both:
175
+ #
176
+ # - the allowed parameter definition tag names, and
177
+ # - their processing functions.
178
+ #
179
+ # The idea is to allow this class to grow along with the IBIS
180
+ # standard, without having to change any of its boilerplate.
181
+
182
+ _param_def_tag_procs = {
183
+ "Usage": _set_usage,
184
+ "Type": _set_type,
185
+ "Format": _set_format,
186
+ "Value": _set_value,
187
+ "Range": _set_range,
188
+ "List": _set_list,
189
+ "Corner": _set_list,
190
+ "Default": _set_default,
191
+ "Description": _set_description,
192
+ "List_Tip": _set_list_tip,
193
+ "Label": _set_list_tip,
194
+ "Labels": _set_list_tip,
195
+ }
196
+
197
+ def __init__(self, name, tags): # pylint: disable=too-many-branches,too-many-statements
198
+ """
199
+ Args:
200
+ name (str): The name of the AMI parameter being created.
201
+ tags ([(str, [a])]): A list of pairs, each containing
202
+
203
+ - a parameter definition tag name
204
+ (Must be one of the keys from the '_param_def_tag_procs' dictionary.)
205
+
206
+ - a list of values to be associated with that tag.
207
+ """
208
+ # Initialization
209
+ self._usage = None
210
+ self._type = None
211
+ self._format = None
212
+ self._value = None
213
+ self._min = None
214
+ self._max = None
215
+ self._default = None
216
+ self._description = ""
217
+ self._list_tip = None
218
+
219
+ # Holds any warnings encountered, during initialization.
220
+ # (Any errors encountered will prevent initialization from completing.)
221
+ self._msg = ""
222
+
223
+ # Process all parameter definition tags.
224
+ for tag in tags:
225
+ tag_name = tag[0]
226
+ if tag_name in self._param_def_tag_procs:
227
+ try:
228
+ self._param_def_tag_procs[tag_name](self, tag[1])
229
+ except AMIParamError as err:
230
+ raise AMIParamError(f"Problem initializing parameter, '{name}': {err}\n") from err
231
+
232
+ # Validate and complete the instance.
233
+ # Check for required tags.
234
+ param_usage = self._usage
235
+ param_type = self._type
236
+ param_format = self._format
237
+ param_default = self._default
238
+ if param_usage is None:
239
+ raise AMIParamError("Missing 'Usage' tag!\n")
240
+ if param_type is None:
241
+ raise AMIParamError("Missing 'Type' tag!\n")
242
+ if param_format is None:
243
+ if param_default is None:
244
+ raise AMIParamError("Missing both 'Format' and 'Default' tags!\n")
245
+ self._value = param_default
246
+ param_format = "Value"
247
+ self._format_rem = [param_default]
248
+ # Check for mutual exclusivity of 'Format Value' and 'Default'.
249
+ elif (param_format == "Value") and (param_default is not None):
250
+ self._msg += "'Format Value' and 'Default' both found! (They are mutually exclusive.)\n"
251
+ # Canonicalize Boolean if necessary.
252
+ elif (param_format == "List") and (param_type == "Boolean"):
253
+ if param_default:
254
+ self._value = param_default
255
+ else:
256
+ self._value = "False"
257
+ param_format = "Value"
258
+ self._format_rem = [self._value]
259
+ self._format = param_format
260
+
261
+ # Check for 'Default' used with parameter type 'Out'.
262
+ if (param_usage == "Out") and (param_default is not None):
263
+ raise AMIParamError("'Default' may not be used with parameter type 'Out'!\n")
264
+
265
+ # Complete the instance.
266
+ vals = self._format_rem
267
+ if param_format == "Value":
268
+ value_str = vals[0].strip()
269
+ if param_type in ("Float", "UI"):
270
+ try:
271
+ self._value = float(value_str)
272
+ except (ValueError, TypeError) as exc:
273
+ raise AMIParamError(f"Couldn't read float from '{value_str}'.\n") from exc
274
+ elif param_type == "Integer":
275
+ try:
276
+ self._value = int(float(value_str)) # Hack to accommodate: "1e5", for instance.
277
+ except (ValueError, TypeError) as exc:
278
+ raise AMIParamError(f"Couldn't read integer from '{value_str}'.\n") from exc
279
+ elif param_type == "Boolean":
280
+ if value_str == "True":
281
+ self._value = True
282
+ elif value_str == "False":
283
+ self._value = False
284
+ else:
285
+ raise AMIParamError(f"Couldn't read Boolean from '{value_str}'.\n")
286
+ else: # `String`
287
+ self._value = value_str.strip('"')
288
+ elif param_format == "Range":
289
+ if param_type not in ("Float", "Integer", "UI", "Tap"):
290
+ raise AMIParamError(f"Illegal type, '{param_type}', for use with Range.\n")
291
+ if len(vals) < 3:
292
+ raise AMIParamError(f"Insufficient number of values, {len(vals)}, provided for Range.\n")
293
+ if param_type in ("Float", "UI", "Tap"):
294
+ try:
295
+ temp_vals = list(map(float, vals[:3]))
296
+ except (ValueError, TypeError) as exc:
297
+ raise AMIParamError(f"Couldn't read floats from '{vals[:3]}'.\n") from exc
298
+ else:
299
+ try:
300
+ temp_vals = list(map(int, vals[:3]))
301
+ except (ValueError, TypeError) as exc:
302
+ raise AMIParamError(f"Couldn't read integers from '{vals[:3]}'.\n") from exc
303
+ self._value = temp_vals[0]
304
+ self._min = temp_vals[1]
305
+ self._max = temp_vals[2]
306
+ else: # param_format == 'List'
307
+ if param_type in ("Float", "UI"):
308
+ try:
309
+ temp_vals = list(map(float, vals))
310
+ except (ValueError, TypeError) as exc:
311
+ raise AMIParamError(f"Couldn't read floats from '{vals}'.\n") from exc
312
+ elif param_type in ("Integer", "Tap"):
313
+ try:
314
+ temp_vals = list(map(int, vals))
315
+ except (ValueError, TypeError) as exc:
316
+ raise AMIParamError(f"Couldn't read integers from '{vals}'.\n") from exc
317
+ else: # 'param_type' == 'String'
318
+ try:
319
+ temp_vals = list(map(str, vals))
320
+ temp_vals = [x.strip('"') for x in temp_vals]
321
+ except (ValueError, TypeError) as exc:
322
+ raise AMIParamError(f"Couldn't read strings from '{vals}'.\n") from exc
323
+ self._value = temp_vals
324
+
325
+ self._name = name