genie-python 15.1.0rc1__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 (43) hide show
  1. genie_python/.pylintrc +539 -0
  2. genie_python/__init__.py +1 -0
  3. genie_python/block_names.py +123 -0
  4. genie_python/channel_access_exceptions.py +45 -0
  5. genie_python/genie.py +2462 -0
  6. genie_python/genie_advanced.py +418 -0
  7. genie_python/genie_alerts.py +195 -0
  8. genie_python/genie_api_setup.py +451 -0
  9. genie_python/genie_blockserver.py +64 -0
  10. genie_python/genie_cachannel_wrapper.py +545 -0
  11. genie_python/genie_change_cache.py +151 -0
  12. genie_python/genie_dae.py +2218 -0
  13. genie_python/genie_epics_api.py +906 -0
  14. genie_python/genie_experimental_data.py +186 -0
  15. genie_python/genie_logging.py +200 -0
  16. genie_python/genie_p4p_wrapper.py +203 -0
  17. genie_python/genie_plot.py +77 -0
  18. genie_python/genie_pre_post_cmd_manager.py +21 -0
  19. genie_python/genie_pv_connection_protocol.py +36 -0
  20. genie_python/genie_script_checker.py +507 -0
  21. genie_python/genie_script_generator.py +212 -0
  22. genie_python/genie_simulate.py +69 -0
  23. genie_python/genie_simulate_impl.py +1265 -0
  24. genie_python/genie_startup.py +29 -0
  25. genie_python/genie_toggle_settings.py +58 -0
  26. genie_python/genie_wait_for_move.py +154 -0
  27. genie_python/genie_waitfor.py +576 -0
  28. genie_python/matplotlib_backend/__init__.py +0 -0
  29. genie_python/matplotlib_backend/ibex_websocket_backend.py +366 -0
  30. genie_python/mysql_abstraction_layer.py +272 -0
  31. genie_python/run_tests.py +56 -0
  32. genie_python/scanning_instrument_pylint_plugin.py +31 -0
  33. genie_python/typings/CaChannel/CaChannel.pyi +893 -0
  34. genie_python/typings/CaChannel/__init__.pyi +9 -0
  35. genie_python/typings/CaChannel/_version.pyi +6 -0
  36. genie_python/typings/CaChannel/ca.pyi +31 -0
  37. genie_python/utilities.py +406 -0
  38. genie_python/version.py +1 -0
  39. genie_python-15.1.0rc1.dist-info/LICENSE +28 -0
  40. genie_python-15.1.0rc1.dist-info/METADATA +95 -0
  41. genie_python-15.1.0rc1.dist-info/RECORD +43 -0
  42. genie_python-15.1.0rc1.dist-info/WHEEL +5 -0
  43. genie_python-15.1.0rc1.dist-info/top_level.txt +1 -0
genie_python/.pylintrc ADDED
@@ -0,0 +1,539 @@
1
+ [MASTER]
2
+
3
+ # A comma-separated list of package or module names from where C extensions may
4
+ # be loaded. Extensions are loading into the active Python interpreter and may
5
+ # run arbitrary code
6
+ extension-pkg-whitelist=
7
+
8
+ # Add files or directories to the blacklist. They should be base names, not
9
+ # paths.
10
+ ignore=CVS
11
+
12
+ # Add files or directories matching the regex patterns to the blacklist. The
13
+ # regex matches against base names, not paths.
14
+ ignore-patterns=
15
+
16
+ # Python code to execute, usually for sys.path manipulation such as
17
+ # pygtk.require().
18
+ init-hook=
19
+
20
+ # Use multiple processes to speed up Pylint.
21
+ #jobs=1
22
+
23
+ # List of plugins (as comma separated values of python modules names) to load,
24
+ # usually to register additional checkers.
25
+ load-plugins=genie_python.scanning_instrument_pylint_plugin
26
+
27
+ # Pickle collected data for later comparisons.
28
+ persistent=yes
29
+
30
+ # Specify a configuration file.
31
+ #rcfile=
32
+
33
+ # When enabled, pylint would attempt to guess common misconfiguration and emit
34
+ # user-friendly hints instead of false-positive error messages
35
+ suggestion-mode=yes
36
+
37
+ # Allow loading of arbitrary C extensions. Extensions are imported into the
38
+ # active Python interpreter and may run arbitrary code.
39
+ unsafe-load-any-extension=yes
40
+
41
+ [MESSAGES CONTROL]
42
+
43
+ # Only show warnings with the listed confidence levels. Leave empty to show
44
+ # all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
45
+ confidence=
46
+
47
+ # Disable the message, report, category or checker with the given id(s). You
48
+ # can either give multiple identifiers separated by comma (,) or put this
49
+ # option multiple times (only on the command line, not in the configuration
50
+ # file where it should appear only once).You can also use "--disable=all" to
51
+ # disable everything first and then reenable specific checks. For example, if
52
+ # you want to run only the similarities checker, you can use "--disable=all
53
+ # --enable=similarities". If you want to run only the classes checker, but have
54
+ # no Warning level messages displayed, use"--disable=all --enable=classes
55
+ # --disable=W"
56
+ # Consider removing some of these to show scientists when there script is not py 2/3 compatible
57
+ disable=C,
58
+ print-statement,
59
+ unused-import,
60
+ unused-variable,
61
+ bad-indentation,
62
+ parameter-unpacking,
63
+ unpacking-in-except,
64
+ old-raise-syntax,
65
+ backtick,
66
+ import-star-module-level,
67
+ raw-checker-failed,
68
+ bad-inline-option,
69
+ locally-disabled,
70
+ file-ignored,
71
+ suppressed-message,
72
+ useless-suppression,
73
+ deprecated-pragma,
74
+ apply-builtin,
75
+ basestring-builtin,
76
+ buffer-builtin,
77
+ cmp-builtin,
78
+ coerce-builtin,
79
+ execfile-builtin,
80
+ file-builtin,
81
+ long-builtin,
82
+ raw_input-builtin,
83
+ reduce-builtin,
84
+ standarderror-builtin,
85
+ unicode-builtin,
86
+ xrange-builtin,
87
+ coerce-method,
88
+ delslice-method,
89
+ getslice-method,
90
+ setslice-method,
91
+ no-absolute-import,
92
+ old-division,
93
+ dict-iter-method,
94
+ dict-view-method,
95
+ next-method-called,
96
+ metaclass-assignment,
97
+ indexing-exception,
98
+ raising-string,
99
+ reload-builtin,
100
+ oct-method,
101
+ hex-method,
102
+ nonzero-method,
103
+ cmp-method,
104
+ input-builtin,
105
+ round-builtin,
106
+ intern-builtin,
107
+ unichr-builtin,
108
+ map-builtin-not-iterating,
109
+ zip-builtin-not-iterating,
110
+ range-builtin-not-iterating,
111
+ filter-builtin-not-iterating,
112
+ using-cmp-argument,
113
+ div-method,
114
+ idiv-method,
115
+ rdiv-method,
116
+ exception-message-attribute,
117
+ invalid-str-codec,
118
+ sys-max-int,
119
+ bad-python3-import,
120
+ deprecated-string-function,
121
+ deprecated-str-translate-call,
122
+ deprecated-itertools-function,
123
+ deprecated-types-field,
124
+ next-method-defined,
125
+ dict-items-not-iterating,
126
+ dict-keys-not-iterating,
127
+ dict-values-not-iterating,
128
+ deprecated-operator-function,
129
+ deprecated-urllib-function,
130
+ xreadlines-attribute,
131
+ deprecated-sys-function,
132
+ exception-escape,
133
+ comprehension-escape
134
+
135
+ # Enable the message, report, category or checker with the given id(s). You can
136
+ # either give multiple identifier separated by comma (,) or put this option
137
+ # multiple time (only on the command line, not in the configuration file where
138
+ # it should appear only once). See also the "--disable" option for examples.
139
+ enable=c-extension-no-member
140
+
141
+
142
+ [REPORTS]
143
+
144
+ # Python expression which should return a note less than 10 (10 is the highest
145
+ # note). You have access to the variables errors warning, statement which
146
+ # respectively contain the number of errors / warnings messages and the total
147
+ # number of statements analyzed. This is used by the global evaluation report
148
+ # (RP0004).
149
+ evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
150
+
151
+ # Template used to display messages. This is a python new-style format string
152
+ # used to format the message information. See doc for all details
153
+ #msg-template=
154
+
155
+ # Set the output format. Available formats are text, parseable, colorized, json
156
+ # and msvs (visual studio).You can also give a reporter class, eg
157
+ # mypackage.mymodule.MyReporterClass.
158
+ output-format=text
159
+
160
+ # Tells whether to display a full report or only the messages
161
+ reports=no
162
+
163
+ # Activate the evaluation score.
164
+ score=yes
165
+
166
+
167
+ [REFACTORING]
168
+
169
+ # Maximum number of nested blocks for function / method body
170
+ max-nested-blocks=5
171
+
172
+ # Complete name of functions that never returns. When checking for
173
+ # inconsistent-return-statements if a never returning function is called then
174
+ # it will be considered as an explicit return statement and no message will be
175
+ # printed.
176
+ never-returning-functions=optparse.Values,sys.exit
177
+
178
+
179
+ [BASIC]
180
+
181
+ # Naming style matching correct argument names
182
+ argument-naming-style=snake_case
183
+
184
+ # Regular expression matching correct argument names. Overrides argument-
185
+ # naming-style
186
+ #argument-rgx=
187
+
188
+ # Naming style matching correct attribute names
189
+ attr-naming-style=snake_case
190
+
191
+ # Regular expression matching correct attribute names. Overrides attr-naming-
192
+ # style
193
+ #attr-rgx=
194
+
195
+ # Bad variable names which should always be refused, separated by a comma
196
+ bad-names=foo,
197
+ bar,
198
+ baz,
199
+ toto,
200
+ tutu,
201
+ tata
202
+
203
+ # Naming style matching correct class attribute names
204
+ class-attribute-naming-style=any
205
+
206
+ # Regular expression matching correct class attribute names. Overrides class-
207
+ # attribute-naming-style
208
+ #class-attribute-rgx=
209
+
210
+ # Naming style matching correct class names
211
+ class-naming-style=PascalCase
212
+
213
+ # Regular expression matching correct class names. Overrides class-naming-style
214
+ #class-rgx=
215
+
216
+ # Naming style matching correct constant names
217
+ const-naming-style=UPPER_CASE
218
+
219
+ # Regular expression matching correct constant names. Overrides const-naming-
220
+ # style
221
+ #const-rgx=
222
+
223
+ # Minimum line length for functions/classes that require docstrings, shorter
224
+ # ones are exempt.
225
+ docstring-min-length=-1
226
+
227
+ # Naming style matching correct function names
228
+ function-naming-style=snake_case
229
+
230
+ # Regular expression matching correct function names. Overrides function-
231
+ # naming-style
232
+ #function-rgx=
233
+
234
+ # Good variable names which should always be accepted, separated by a comma
235
+ good-names=i,
236
+ j,
237
+ k,
238
+ ex,
239
+ Run,
240
+ _
241
+
242
+ # Include a hint for the correct naming format with invalid-name
243
+ include-naming-hint=no
244
+
245
+ # Naming style matching correct inline iteration names
246
+ inlinevar-naming-style=any
247
+
248
+ # Regular expression matching correct inline iteration names. Overrides
249
+ # inlinevar-naming-style
250
+ #inlinevar-rgx=
251
+
252
+ # Naming style matching correct method names
253
+ method-naming-style=snake_case
254
+
255
+ # Regular expression matching correct method names. Overrides method-naming-
256
+ # style
257
+ #method-rgx=
258
+
259
+ # Naming style matching correct module names
260
+ module-naming-style=snake_case
261
+
262
+ # Regular expression matching correct module names. Overrides module-naming-
263
+ # style
264
+ #module-rgx=
265
+
266
+ # Colon-delimited sets of names that determine each other's naming style when
267
+ # the name regexes allow several styles.
268
+ name-group=
269
+
270
+ # Regular expression which should only match function or class names that do
271
+ # not require a docstring.
272
+ no-docstring-rgx=^_
273
+
274
+ # List of decorators that produce properties, such as abc.abstractproperty. Add
275
+ # to this list to register other decorators that produce valid properties.
276
+ property-classes=abc.abstractproperty
277
+
278
+ # Naming style matching correct variable names
279
+ variable-naming-style=snake_case
280
+
281
+ # Regular expression matching correct variable names. Overrides variable-
282
+ # naming-style
283
+ #variable-rgx=
284
+
285
+
286
+ [FORMAT]
287
+
288
+ # Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
289
+ expected-line-ending-format=
290
+
291
+ # Regexp for a line that is allowed to be longer than the limit.
292
+ ignore-long-lines=^\s*(# )?<?https?://\S+>?$
293
+
294
+ # Number of spaces of indent required inside a hanging or continued line.
295
+ indent-after-paren=4
296
+
297
+ # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
298
+ # tab).
299
+ indent-string=' '
300
+
301
+ # Maximum number of characters on a single line.
302
+ max-line-length=100
303
+
304
+ # Maximum number of lines in a module
305
+ max-module-lines=1000
306
+
307
+ # Allow the body of a class to be on the same line as the declaration if body
308
+ # contains single statement.
309
+ single-line-class-stmt=no
310
+
311
+ # Allow the body of an if to be on the same line as the test if there is no
312
+ # else.
313
+ single-line-if-stmt=no
314
+
315
+
316
+ [LOGGING]
317
+
318
+ # Logging modules to check that the string format arguments are in logging
319
+ # function parameter format
320
+ logging-modules=logging
321
+
322
+
323
+ [MISCELLANEOUS]
324
+
325
+ # List of note tags to take in consideration, separated by a comma.
326
+ notes=FIXME,
327
+ XXX,
328
+ TODO
329
+
330
+
331
+ [SIMILARITIES]
332
+
333
+ # Ignore comments when computing similarities.
334
+ ignore-comments=yes
335
+
336
+ # Ignore docstrings when computing similarities.
337
+ ignore-docstrings=yes
338
+
339
+ # Ignore imports when computing similarities.
340
+ ignore-imports=no
341
+
342
+ # Minimum lines number of a similarity.
343
+ min-similarity-lines=4
344
+
345
+
346
+ [SPELLING]
347
+
348
+ # Limits count of emitted suggestions for spelling mistakes
349
+ max-spelling-suggestions=4
350
+
351
+ # Spelling dictionary name. Available dictionaries: none. To make it working
352
+ # install python-enchant package.
353
+ spelling-dict=
354
+
355
+ # List of comma separated words that should not be checked.
356
+ spelling-ignore-words=
357
+
358
+ # A path to a file that contains private dictionary; one word per line.
359
+ spelling-private-dict-file=
360
+
361
+ # Tells whether to store unknown words to indicated private dictionary in
362
+ # --spelling-private-dict-file option instead of raising a message.
363
+ spelling-store-unknown-words=no
364
+
365
+
366
+ [TYPECHECK]
367
+
368
+ # List of decorators that produce context managers, such as
369
+ # contextlib.contextmanager. Add to this list to register other decorators that
370
+ # produce valid context managers.
371
+ contextmanager-decorators=contextlib.contextmanager
372
+
373
+ # List of members which are set dynamically and missed by pylint inference
374
+ # system, and so shouldn't trigger E1101 when accessed. Python regular
375
+ # expressions are accepted.
376
+ generated-members=
377
+
378
+ # Tells whether missing members accessed in mixin class should be ignored. A
379
+ # mixin class is detected if its name ends with "mixin" (case insensitive).
380
+ ignore-mixin-members=yes
381
+
382
+ # This flag controls whether pylint should warn about no-member and similar
383
+ # checks whenever an opaque object is returned when inferring. The inference
384
+ # can return multiple potential results while evaluating a Python object, but
385
+ # some branches might not be evaluated, which results in partial inference. In
386
+ # that case, it might be useful to still emit no-member and other checks for
387
+ # the rest of the inferred objects.
388
+ ignore-on-opaque-inference=yes
389
+
390
+ # List of class names for which member attributes should not be checked (useful
391
+ # for classes with dynamically set attributes). This supports the use of
392
+ # qualified names.
393
+ ignored-classes=optparse.Values,thread._local,_thread._local
394
+
395
+ # List of module names for which member attributes should not be checked
396
+ # (useful for modules/projects where namespaces are manipulated during runtime
397
+ # and thus existing member attributes cannot be deduced by static analysis. It
398
+ # supports qualified module names, as well as Unix pattern matching.
399
+ ignored-modules=
400
+
401
+ # Show a hint with possible names when a member name was not found. The aspect
402
+ # of finding the hint is based on edit distance.
403
+ missing-member-hint=yes
404
+
405
+ # The minimum edit distance a name should have in order to be considered a
406
+ # similar match for a missing member name.
407
+ missing-member-hint-distance=1
408
+
409
+ # The total number of similar names that should be taken in consideration when
410
+ # showing a hint for a missing member.
411
+ missing-member-max-choices=1
412
+
413
+
414
+ [VARIABLES]
415
+
416
+ # List of additional names supposed to be defined in builtins. Remember that
417
+ # you should avoid to define new builtins when possible.
418
+ additional-builtins=
419
+
420
+ # Tells whether unused global variables should be treated as a violation.
421
+ allow-global-unused-variables=yes
422
+
423
+ # List of strings which can identify a callback function by name. A callback
424
+ # name must start or end with one of those strings.
425
+ callbacks=cb_,
426
+ _cb
427
+
428
+ # A regular expression matching the name of dummy variables (i.e. expectedly
429
+ # not used).
430
+ dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
431
+
432
+ # Argument names that match this expression will be ignored. Default to name
433
+ # with leading underscore
434
+ ignored-argument-names=_.*|^ignored_|^unused_
435
+
436
+ # Tells whether we should check for unused import in __init__ files.
437
+ init-import=no
438
+
439
+ # List of qualified module names which can have objects that can redefine
440
+ # builtins.
441
+ redefining-builtins-modules=past.builtins,future.builtins,io,builtins
442
+
443
+
444
+ [CLASSES]
445
+
446
+ # List of method names used to declare (i.e. assign) instance attributes.
447
+ defining-attr-methods=__init__,
448
+ __new__,
449
+ setUp
450
+
451
+ # List of member names, which should be excluded from the protected access
452
+ # warning.
453
+ exclude-protected=_asdict,
454
+ _fields,
455
+ _replace,
456
+ _source,
457
+ _make
458
+
459
+ # List of valid names for the first argument in a class method.
460
+ valid-classmethod-first-arg=cls
461
+
462
+ # List of valid names for the first argument in a metaclass class method.
463
+ valid-metaclass-classmethod-first-arg=mcs
464
+
465
+
466
+ [DESIGN]
467
+
468
+ # Maximum number of arguments for function / method
469
+ max-args=5
470
+
471
+ # Maximum number of attributes for a class (see R0902).
472
+ max-attributes=7
473
+
474
+ # Maximum number of boolean expressions in a if statement
475
+ max-bool-expr=5
476
+
477
+ # Maximum number of branch for function / method body
478
+ max-branches=12
479
+
480
+ # Maximum number of locals for function / method body
481
+ max-locals=15
482
+
483
+ # Maximum number of parents for a class (see R0901).
484
+ max-parents=7
485
+
486
+ # Maximum number of public methods for a class (see R0904).
487
+ max-public-methods=20
488
+
489
+ # Maximum number of return / yield for function / method body
490
+ max-returns=6
491
+
492
+ # Maximum number of statements in function / method body
493
+ max-statements=50
494
+
495
+ # Minimum number of public methods for a class (see R0903).
496
+ min-public-methods=2
497
+
498
+
499
+ [IMPORTS]
500
+
501
+ # Allow wildcard imports from modules that define __all__.
502
+ allow-wildcard-with-all=yes
503
+
504
+ # Analyse import fallback blocks. This can be used to support both Python 2 and
505
+ # 3 compatible code, which means that the block might have code that exists
506
+ # only in one or another interpreter, leading to false positives when analysed.
507
+ analyse-fallback-blocks=no
508
+
509
+ # Deprecated modules which should not be used, separated by a comma
510
+ deprecated-modules=regsub,
511
+ TERMIOS,
512
+ Bastion,
513
+ rexec
514
+
515
+ # Create a graph of external dependencies in the given file (report RP0402 must
516
+ # not be disabled)
517
+ ext-import-graph=
518
+
519
+ # Create a graph of every (i.e. internal and external) dependencies in the
520
+ # given file (report RP0402 must not be disabled)
521
+ import-graph=
522
+
523
+ # Create a graph of internal dependencies in the given file (report RP0402 must
524
+ # not be disabled)
525
+ int-import-graph=
526
+
527
+ # Force import order to recognize a module as part of the standard
528
+ # compatibility libraries.
529
+ known-standard-library=
530
+
531
+ # Force import order to recognize a module as part of a third party library.
532
+ known-third-party=enchant
533
+
534
+
535
+ [EXCEPTIONS]
536
+
537
+ # Exceptions that will emit a warning when being caught. Defaults to
538
+ # "Exception"
539
+ overgeneral-exceptions=builtins.Exception
@@ -0,0 +1 @@
1
+ from .genie_epics_api import BLOCK_NAMES
@@ -0,0 +1,123 @@
1
+ import zlib
2
+ from keyword import iskeyword
3
+ from threading import RLock, Timer
4
+
5
+ from .channel_access_exceptions import UnableToConnectToPVException
6
+ from .genie_blockserver import BLOCK_SERVER_PREFIX, PV_BLOCK_NAMES
7
+ from .genie_cachannel_wrapper import CaChannelWrapper
8
+ from .utilities import dehex_decompress_and_dejson
9
+
10
+ DELAY_BEFORE_RETRYING_BLOCK_NAMES_PV_ON_FAIL = 30.0
11
+
12
+
13
+ class BlockNamesManager:
14
+ """
15
+ Manager for a blocks name object. It makes sure that the blocks it contains are updated
16
+ """
17
+
18
+ def __init__(
19
+ self,
20
+ block_names,
21
+ delay_before_retry_add_monitor=DELAY_BEFORE_RETRYING_BLOCK_NAMES_PV_ON_FAIL,
22
+ ):
23
+ """
24
+ Constructor.
25
+ :param block_names: the block name instance that this manger is managing
26
+ :param delay_before_retry_add_monitor: if the block names pv doesn't exist on start the delay before retrying
27
+ """
28
+ self._block_names = block_names
29
+ self._cancel_monitor_fn = None
30
+ self._delay_before_retry_add_monitor = delay_before_retry_add_monitor
31
+ self._timer = None
32
+ self._pv_name = None
33
+ # lock used to access _timer or _pv_name
34
+ self.pv_name_lock = RLock()
35
+
36
+ def update_prefix(self, pv_prefix):
37
+ """
38
+ Update the instrument prefix that the manager is using if it has changed
39
+ :param pv_prefix: new pv prefix
40
+ """
41
+
42
+ with self.pv_name_lock:
43
+ new_name = "{}{}{}".format(pv_prefix, BLOCK_SERVER_PREFIX, PV_BLOCK_NAMES)
44
+ if new_name != self._pv_name:
45
+ self._pv_name = new_name
46
+ if self._timer is None:
47
+ self._timer = Timer(0, self._add_monitor)
48
+ self._timer.setDaemon(True)
49
+ self._timer.start()
50
+
51
+ def _add_monitor(self):
52
+ """
53
+ Add a monitor to the block names pv if it is not already monitored, then reschedule task to add monitor. If the
54
+ pv is monitored don't run.
55
+ """
56
+
57
+ # Get PV we should monitor and check whether we need to add new monitor if so cancel old monitor
58
+ with self.pv_name_lock:
59
+ self._timer = None
60
+ # not monitoring the correct pv
61
+ if self._cancel_monitor_fn is not None:
62
+ self._cancel_monitor_fn()
63
+
64
+ # Add new monitor if successful then record monitored pv and pull first value, otherwise do nothing
65
+ try:
66
+ self._cancel_monitor_fn = CaChannelWrapper.add_monitor(
67
+ self._pv_name, self._update_block_names, to_string=True
68
+ )
69
+ self._update_block_names(
70
+ CaChannelWrapper.get_pv_value(self._pv_name, to_string=True), None, None
71
+ )
72
+ except UnableToConnectToPVException:
73
+ # Schedule next add monitor if needed; i.e. a old pv-prefix change was slower the the last pv-prefix
74
+ # and so we are monitoring the wrong pv.
75
+ self._timer = Timer(self._delay_before_retry_add_monitor, self._add_monitor)
76
+ self._timer.setDaemon(True)
77
+ self._timer.start()
78
+
79
+ def _update_block_names(self, value, _, _1):
80
+ """
81
+ Update the block names from a pv
82
+ Args:
83
+ :param value: new value of block names pv
84
+ :param _(CaChannel._ca.AlarmSeverity): severity of any alarm (not used but passed in by monitor)
85
+ :param _1(CaChannel._ca.AlarmCondition): status of the alarm (not used but passed in by monitor)
86
+ """
87
+ # remove old blocks
88
+ for block_name in list(self._block_names.__dict__.keys()):
89
+ delattr(self._block_names, block_name)
90
+
91
+ # add new block as attributes to class
92
+ try:
93
+ block_names = dehex_decompress_and_dejson(value)
94
+ for name in block_names:
95
+ attribute_name = name
96
+ if iskeyword(attribute_name):
97
+ attribute_name = "{}__".format(attribute_name)
98
+ setattr(self._block_names, attribute_name, name)
99
+ except (zlib.error, ValueError, TypeError):
100
+ # if we can not decode the blocks then just pass
101
+ pass
102
+
103
+
104
+ class BlockNames:
105
+ """
106
+ Hold names of the current blocks in config. If block is requested which does not appear in the current config
107
+ block name returned but message printed about it.
108
+ """
109
+
110
+ def __getattr__(self, attr):
111
+ """
112
+ If an attribute is not set then return name requested
113
+ :param attr: attribute name
114
+ :return: block name, which is the same as the attribute
115
+ """
116
+ # don't mask not having methods starting with underscore all blocks start with a
117
+ # letter, e.g. ipython console calls __wrapper__ to check it is not a wrapper
118
+ if attr.startswith("_"):
119
+ raise AttributeError()
120
+ print("WARNING: Block name {} not found, it may not exist".format(attr))
121
+ if attr.endswith("__") and iskeyword(attr[:-2]):
122
+ return str(attr[:-2])
123
+ return attr
@@ -0,0 +1,45 @@
1
+ """
2
+ Useful and slightly more explit exceptions that can be thrown. In general catch the super class of these.
3
+ """
4
+
5
+
6
+ class UnableToConnectToPVException(IOError):
7
+ """
8
+ The system is unable to connect to a PV for some reason.
9
+ """
10
+
11
+ def __init__(self, pv_name, err):
12
+ super(UnableToConnectToPVException, self).__init__(
13
+ "Unable to connect to PV {0}: {1}".format(pv_name, err)
14
+ )
15
+
16
+
17
+ class InvalidEnumStringException(KeyError):
18
+ """
19
+ The enum string that is trying to be set is not listed in the pv.
20
+ """
21
+
22
+ def __init__(self, pv_name, valid_states):
23
+ super(InvalidEnumStringException, self).__init__(
24
+ "Invalid string value entered for {}. Valid strings are {}".format(
25
+ pv_name, valid_states
26
+ )
27
+ )
28
+
29
+
30
+ class ReadAccessException(IOError):
31
+ """
32
+ PV exists but its value is unavailable to read.
33
+ """
34
+
35
+ def __init__(self, pv_name):
36
+ super(ReadAccessException, self).__init__("Read access denied for PV {}".format(pv_name))
37
+
38
+
39
+ class WriteAccessException(IOError):
40
+ """
41
+ PV was written to but does not allow writes.
42
+ """
43
+
44
+ def __init__(self, pv_name):
45
+ super(WriteAccessException, self).__init__("Write access denied for PV {}".format(pv_name))