Skip to content

Commit 9fcdf4a

Browse files
Ruff
1 parent 8f95fa3 commit 9fcdf4a

File tree

1 file changed

+54
-39
lines changed

1 file changed

+54
-39
lines changed

utilities/utilities.py

Lines changed: 54 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import timeit
88
import unittest
99
from time import sleep, time
10-
from typing import Callable
10+
from typing import Callable, ParamSpec, TypeVar
1111

1212
import six
1313

@@ -27,9 +27,12 @@
2727
except ImportError:
2828
from genie_python.utilities import compress_and_hex, dehex_and_decompress
2929

30+
P = ParamSpec("P")
31+
T = TypeVar("T")
32+
3033
WAIT_FOR_SERVER_TIMEOUT = 90
31-
"""Number of seconds to wait for a pv to become available in the config server e.g. when it starts or
32-
when it changed config"""
34+
"""Number of seconds to wait for a pv to become available in the
35+
config server e.g. when it starts or when it changed config"""
3336

3437
# Number of seconds to wait for the DAE settings to update
3538
DAE_MODE_TIMEOUT = 120
@@ -41,7 +44,7 @@
4144
BASE_MEMORY_USAGE = "BASE_MEMORY_USAGE"
4245

4346

44-
def parameterized_list(cases):
47+
def parameterized_list(cases: list[str]) -> list[str]:
4548
"""
4649
Creates a list of cases for parameterized to use to run tests.
4750
@@ -68,7 +71,9 @@ def parameterized_list(cases):
6871
return return_list
6972

7073

71-
def load_config_if_not_already_loaded(config_name, timeout=WAIT_FOR_SERVER_TIMEOUT):
74+
def load_config_if_not_already_loaded(
75+
config_name: str, timeout: int = WAIT_FOR_SERVER_TIMEOUT
76+
) -> None:
7277
"""
7378
Load a config by name if it has not already been loaded.
7479
@@ -103,19 +108,21 @@ def load_config_if_not_already_loaded(config_name, timeout=WAIT_FOR_SERVER_TIMEO
103108
)
104109

105110

106-
def _get_config_name():
111+
def _get_config_name() -> str:
107112
"""
108-
Returns the current config name after waiting for up to WAIT_FOR_SERVER_TIMEOUT seconds for it to be readable
113+
Returns the current config name after waiting for up to WAIT_FOR_SERVER_TIMEOUT seconds
114+
for it to be readable
109115
Returns: the current configs name
110116
Raises: AssertionError if the cv can not be read
111117
112118
"""
113119
return get_config_details()["name"]
114120

115121

116-
def get_config_details():
122+
def get_config_details() -> dict():
117123
"""
118-
Returns the current config name after waiting for up to WAIT_FOR_SERVER_TIMEOUT seconds for it to be readable
124+
Returns the current config name after waiting for up to WAIT_FOR_SERVER_TIMEOUT seconds
125+
for it to be readable
119126
Returns: the current configs name
120127
Raises: AssertionError if the cv can not be read
121128
@@ -136,7 +143,7 @@ def get_config_details():
136143
raise final_exception
137144

138145

139-
def get_server_status():
146+
def get_server_status() -> str | None:
140147
"""
141148
Get the servers current status
142149
@@ -155,7 +162,7 @@ def get_server_status():
155162
return None
156163

157164

158-
def set_genie_python_raises_exceptions(does_throw):
165+
def set_genie_python_raises_exceptions(does_throw: bool) -> None:
159166
"""
160167
Set that genie python api raises exceptions instead of just logging a message
161168
Args:
@@ -167,7 +174,7 @@ def set_genie_python_raises_exceptions(does_throw):
167174
genie_api_setup._exceptions_raised = does_throw
168175

169176

170-
def setup_simulated_wiring_tables(event_data=False):
177+
def setup_simulated_wiring_tables(event_data: bool = False) -> None:
171178
"""
172179
Configures the DAE's wiring tables and sets the DAE to simulation mode
173180
@@ -206,7 +213,7 @@ def setup_simulated_wiring_tables(event_data=False):
206213
set_genie_python_raises_exceptions(False)
207214

208215

209-
def _wait_for_and_assert_dae_simulation_mode(mode):
216+
def _wait_for_and_assert_dae_simulation_mode(mode: bool) -> None:
210217
"""
211218
Waits for specified DAE simulation mode in the DAE
212219
@@ -232,7 +239,7 @@ def _wait_for_and_assert_dae_simulation_mode(mode):
232239
)
233240

234241

235-
def set_wait_for_complete_callback_dae_settings(wait):
242+
def set_wait_for_complete_callback_dae_settings(wait: bool) -> None:
236243
"""Sets the wait for completion callback attribute of the DAE
237244
238245
@param wait: Boolean value, True if you want the DAE to wait for the operation
@@ -241,13 +248,13 @@ def set_wait_for_complete_callback_dae_settings(wait):
241248
genie_api_setup.__api.dae.wait_for_completion_callback_dae_settings = wait
242249

243250

244-
def temporarily_kill_icp():
251+
def temporarily_kill_icp() -> None:
245252
# Temporarily kills the ISIS ICP (ISIS DAE)
246253

247254
return genie_api_setup.__api.dae.temporarily_kill_icp()
248255

249256

250-
def as_seconds(time):
257+
def as_seconds(time: str) -> int:
251258
"""
252259
Convert a up time to seconds
253260
Args:
@@ -265,7 +272,7 @@ def as_seconds(time):
265272
return seconds
266273

267274

268-
def _start_stop_ioc_is_a_start(is_a_start, ioc_name):
275+
def _start_stop_ioc_is_a_start(is_a_start: bool, ioc_name: str) -> None:
269276
"""
270277
Start or stop and ioc dependent on whether it "is_a_start"
271278
Args:
@@ -285,12 +292,13 @@ def _start_stop_ioc_is_a_start(is_a_start, ioc_name):
285292
wait_for_ioc_start_stop(timeout=IOCS_START_STOP_TIMEOUT, is_start=is_a_start, ioc_name=ioc_name)
286293

287294

288-
def bulk_start_ioc(ioc_list):
295+
def bulk_start_ioc(ioc_list: list[str]) -> tuple[bool, bool]:
289296
"""
290297
start a list of IOCs in bulk
291298
:param ioc_list: a list of the names of the IOCs to start
292299
:return: a list of IOCs that failed to start after IOCS_START_STOP_TIMEOUT seconds
293-
and a list of any IOCs that were not present in proc serv (this should be a very rare case)
300+
and a list of any IOCs that were not present in proc serv
301+
(this should be a very rare case)
294302
"""
295303
failed_to_start = []
296304
not_in_proc_serv = []
@@ -301,7 +309,8 @@ def bulk_start_ioc(ioc_list):
301309
except UnableToConnectToPVException:
302310
not_in_proc_serv.append(ioc_name)
303311
print(
304-
f"{ioc_name} not found in proc serv, should this be added to the list of iocs to skip?"
312+
f"{ioc_name} not found in proc serv, should this be added "
313+
"to the list of iocs to skip?"
305314
)
306315
ioc_list = [ioc for ioc in ioc_list if ioc not in not_in_proc_serv]
307316
for ioc_name in ioc_list:
@@ -314,7 +323,7 @@ def bulk_start_ioc(ioc_list):
314323
return failed_to_start, not_in_proc_serv
315324

316325

317-
def bulk_stop_ioc(ioc_list):
326+
def bulk_stop_ioc(ioc_list: list[str]) -> bool:
318327
"""
319328
Stops a list of IOCs in bulk
320329
:param ioc_list: a list of the names of the IOCs to stop
@@ -334,7 +343,7 @@ def bulk_stop_ioc(ioc_list):
334343
return failed_to_stop
335344

336345

337-
def start_ioc(ioc_name):
346+
def start_ioc(ioc_name: str) -> None:
338347
"""
339348
Start the ioc
340349
Args:
@@ -346,7 +355,7 @@ def start_ioc(ioc_name):
346355
_start_stop_ioc_is_a_start(True, ioc_name)
347356

348357

349-
def stop_ioc(ioc_name):
358+
def stop_ioc(ioc_name: str) -> None:
350359
"""
351360
Stop the ioc
352361
Args:
@@ -358,7 +367,7 @@ def stop_ioc(ioc_name):
358367
_start_stop_ioc_is_a_start(False, ioc_name)
359368

360369

361-
def wait_for_ioc_start_stop(timeout, is_start, ioc_name):
370+
def wait_for_ioc_start_stop(timeout: int, is_start: bool, ioc_name: str) -> None:
362371
"""
363372
Wait for an ioc to start or stop, if timeout raise a timeout error
364373
Args:
@@ -382,9 +391,10 @@ def wait_for_ioc_start_stop(timeout, is_start, ioc_name):
382391
raise IOError(f"IOC {ioc_name} is not {'started' if is_start else 'stopped'}")
383392

384393

385-
def quick_is_ioc_down(ioc_name):
394+
def quick_is_ioc_down(ioc_name: str) -> bool:
386395
"""
387-
Determine if IOC is up by checking proc serv, cannot be used to make sure a PV has been started, but is
396+
Determine if IOC is up by checking proc serv, cannot be used to make sure a PV
397+
has been started, but is
388398
good enough for checks before attempting to start/stop
389399
:param ioc_name: The IOC to check
390400
:return: True if IOC is up; False otherwise
@@ -393,7 +403,7 @@ def quick_is_ioc_down(ioc_name):
393403
return running == "Shutdown"
394404

395405

396-
def is_ioc_up(ioc_name):
406+
def is_ioc_up(ioc_name: str) -> bool:
397407
"""
398408
Determine if IOC is up by checking for the existence of its heartbeat PV
399409
Args:
@@ -411,7 +421,7 @@ def is_ioc_up(ioc_name):
411421
return heartbeat is not None
412422

413423

414-
def wait_for_iocs_to_be_up(ioc_names, seconds_to_wait):
424+
def wait_for_iocs_to_be_up(ioc_names: list[str], seconds_to_wait: int) -> None:
415425
"""
416426
Wait for a number of iocs to be up by checking for existence of heartbeat PVs for each ioc.
417427
@@ -432,11 +442,14 @@ def wait_for_iocs_to_be_up(ioc_names, seconds_to_wait):
432442
sleep(1)
433443
else:
434444
raise AssertionError(
435-
f"IOCs: {[ioc_name for ioc_name in ioc_names if not is_ioc_up(ioc_name)]} could not be started."
445+
f"IOCs: {[ioc_name for ioc_name in ioc_names if not is_ioc_up(ioc_name)]} "
446+
"could not be started."
436447
)
437448

438449

439-
def wait_for_string_pvs_to_not_be_empty(pvs, seconds_to_wait, is_local=True):
450+
def wait_for_string_pvs_to_not_be_empty(
451+
pvs: list[str], seconds_to_wait: int, is_local: bool = True
452+
) -> dict():
440453
"""
441454
Wait for a number of string pvs to be non-empty and return their values.
442455
Raises an assertion error if at least one is not found.
@@ -469,16 +482,16 @@ def wait_for_string_pvs_to_not_be_empty(pvs, seconds_to_wait, is_local=True):
469482
return pv_values
470483

471484

472-
def retry_on_failure(max_times):
485+
def retry_on_failure(max_times: int) -> Callable[[], None]:
473486
"""
474487
Decorator that will retry running a test if it failed.
475488
:param max_times: Maximum number of times to retry running the test
476489
:return: the decorator
477490
"""
478491

479-
def decorator(func):
492+
def decorator(func: Callable[P, T]) -> Callable[P, T]:
480493
@six.wraps(func)
481-
def wrapper(*args, **kwargs):
494+
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
482495
err = None
483496
for attempt in range(max_times):
484497
try:
@@ -497,7 +510,7 @@ def wrapper(*args, **kwargs):
497510
return decorator
498511

499512

500-
def check_block_exists(block_name):
513+
def check_block_exists(block_name: str) -> bool:
501514
"""
502515
Check that the given block name is in the current blocks.
503516
@@ -511,10 +524,12 @@ def check_block_exists(block_name):
511524
return block_name in blocks
512525

513526

514-
def retry_assert(retry_limit: int, func: Callable[[], None], retry_time: float = 1.0):
527+
def retry_assert(retry_limit: int, func: Callable[[], None], retry_time: float = 1.0) -> None:
515528
"""
516-
Take a function (func) that makes assertions. Try to call the function and catch any AssertionErrors if raised.
517-
Repeat this until either the function does not raise an AssertionError or the retry_limit is reached.
529+
Take a function (func) that makes assertions. Try to call the function and
530+
catch any AssertionErrors if raised.
531+
Repeat this until either the function does not raise an AssertionError
532+
or the retry_limit is reached.
518533
If the retry limit is reach reraise the last error.
519534
520535
Args:
@@ -537,7 +552,7 @@ def retry_assert(retry_limit: int, func: Callable[[], None], retry_time: float =
537552
raise error
538553

539554

540-
def get_execution_time(method):
555+
def get_execution_time(method: Callable[[], None]) -> float:
541556
"""
542557
Takes a method and calculates its execution time.
543558
Useful for tests that are time sensitive
@@ -556,7 +571,7 @@ def get_execution_time(method):
556571
return execution_time
557572

558573

559-
def assert_with_timeout(assertion: Callable, timeout: int):
574+
def assert_with_timeout(assertion: Callable[[], None], timeout: int) -> None:
560575
err = None
561576
for _ in range(timeout):
562577
try:

0 commit comments

Comments
 (0)