diff --git a/src/fastcs/transports/epics/ca/ioc.py b/src/fastcs/transports/epics/ca/ioc.py index b141a7ebe..733fdf62b 100644 --- a/src/fastcs/transports/epics/ca/ioc.py +++ b/src/fastcs/transports/epics/ca/ioc.py @@ -20,7 +20,8 @@ record_metadata_from_attribute, record_metadata_from_datatype, ) -from fastcs.transports.epics.util import controller_pv_prefix, snake_to_pascal +from fastcs.transports.epics.util import controller_pv_prefix +from fastcs.util import snake_to_pascal EPICS_MAX_NAME_LENGTH = 60 diff --git a/src/fastcs/transports/epics/gui.py b/src/fastcs/transports/epics/gui.py index 4cfa5f31f..b1a2ab686 100644 --- a/src/fastcs/transports/epics/gui.py +++ b/src/fastcs/transports/epics/gui.py @@ -36,7 +36,7 @@ from fastcs.methods import Command from fastcs.transports.controller_api import ControllerAPI from fastcs.transports.epics.options import EpicsGUIFormat, EpicsGUIOptions -from fastcs.transports.epics.util import snake_to_pascal +from fastcs.util import snake_to_pascal logger = bind_logger(logger_name=__name__) diff --git a/src/fastcs/transports/epics/pva/ioc.py b/src/fastcs/transports/epics/pva/ioc.py index 5b2dc29dc..df4f64570 100644 --- a/src/fastcs/transports/epics/pva/ioc.py +++ b/src/fastcs/transports/epics/pva/ioc.py @@ -4,13 +4,10 @@ from fastcs.attributes import AttrR, AttrRW, AttrW from fastcs.transports.controller_api import ControllerAPI -from fastcs.transports.epics.util import controller_pv_prefix, snake_to_pascal +from fastcs.transports.epics.util import controller_pv_prefix +from fastcs.util import snake_to_pascal -from ._pv_handlers import ( - make_command_pv, - make_shared_read_pv, - make_shared_write_pv, -) +from ._pv_handlers import make_command_pv, make_shared_read_pv, make_shared_write_pv from .pvi import add_pvi_info diff --git a/src/fastcs/transports/epics/pva/pvi.py b/src/fastcs/transports/epics/pva/pvi.py index a0266cb2b..2823fe38c 100644 --- a/src/fastcs/transports/epics/pva/pvi.py +++ b/src/fastcs/transports/epics/pva/pvi.py @@ -8,7 +8,7 @@ from fastcs.attributes import Attribute, AttrR, AttrRW, AttrW from fastcs.transports.controller_api import ControllerAPI -from fastcs.transports.epics.util import snake_to_pascal +from fastcs.util import snake_to_pascal from .types import p4p_alarm_states, p4p_timestamp_now diff --git a/src/fastcs/transports/epics/util.py b/src/fastcs/transports/epics/util.py index 9f8359001..013cfaff4 100644 --- a/src/fastcs/transports/epics/util.py +++ b/src/fastcs/transports/epics/util.py @@ -1,15 +1,5 @@ -import re - from fastcs.transports.controller_api import ControllerAPI - - -def snake_to_pascal(name: str) -> str: - """Converts string from snake case to Pascal case. - If string is not a valid snake case it will be returned unchanged - """ - if re.fullmatch(r"[a-z][a-z0-9]*(?:_[a-z0-9]+)*", name): - name = re.sub(r"(?:^|_)([a-z0-9])", lambda match: match.group(1).upper(), name) - return name +from fastcs.util import snake_to_pascal def controller_pv_prefix(prefix: str, controller_api: ControllerAPI) -> str: diff --git a/src/fastcs/util.py b/src/fastcs/util.py index 1ef11621a..bb475d641 100644 --- a/src/fastcs/util.py +++ b/src/fastcs/util.py @@ -1,2 +1,13 @@ +import re + ONCE = float("inf") """Sentinel value to call a ``scan`` or io ``update`` method once on start up""" + + +def snake_to_pascal(name: str) -> str: + """Converts string from snake case to Pascal case. + If string is not a valid snake case it will be returned unchanged + """ + if re.fullmatch(r"[a-z][a-z0-9]*(?:_[a-z0-9]+)*", name): + name = re.sub(r"(?:^|_)([a-z0-9])", lambda match: match.group(1).upper(), name) + return name diff --git a/tests/test_util.py b/tests/test_util.py new file mode 100644 index 000000000..5475af74a --- /dev/null +++ b/tests/test_util.py @@ -0,0 +1,28 @@ +from fastcs.util import snake_to_pascal + + +def test_snake_to_pascal(): + name1 = "name_in_snake_case" + name2 = "name-not-in-snake-case" + name3 = "name_with-different_separators" + name4 = "name_with_numbers_1_2_3" + name5 = "numbers_1_2_3_in_the_middle" + name6 = "1_2_3_starting_with_numbers" + name7 = "name1_with2_a3_number4" + name8 = "name_in_lower_case" + name9 = "NameAlreadyInPascalCase" + name10 = "Name_With_%_Invalid_&_Symbols_£_" + name11 = "a_b_c_d" + name12 = "test" + assert snake_to_pascal(name1) == "NameInSnakeCase" + assert snake_to_pascal(name2) == "name-not-in-snake-case" + assert snake_to_pascal(name3) == "name_with-different_separators" + assert snake_to_pascal(name4) == "NameWithNumbers123" + assert snake_to_pascal(name5) == "Numbers123InTheMiddle" + assert snake_to_pascal(name6) == "1_2_3_starting_with_numbers" + assert snake_to_pascal(name7) == "Name1With2A3Number4" + assert snake_to_pascal(name8) == "NameInLowerCase" + assert snake_to_pascal(name9) == "NameAlreadyInPascalCase" + assert snake_to_pascal(name10) == "Name_With_%_Invalid_&_Symbols_£_" + assert snake_to_pascal(name11) == "ABCD" + assert snake_to_pascal(name12) == "Test" diff --git a/tests/transports/epics/test_epics_util.py b/tests/transports/epics/test_epics_util.py index 1701d6b31..e240b0e31 100644 --- a/tests/transports/epics/test_epics_util.py +++ b/tests/transports/epics/test_epics_util.py @@ -2,34 +2,7 @@ from pvi.device import SignalR from pydantic import ValidationError -from fastcs.transports.epics.util import snake_to_pascal - - -def test_snake_to_pascal(): - name1 = "name_in_snake_case" - name2 = "name-not-in-snake-case" - name3 = "name_with-different_separators" - name4 = "name_with_numbers_1_2_3" - name5 = "numbers_1_2_3_in_the_middle" - name6 = "1_2_3_starting_with_numbers" - name7 = "name1_with2_a3_number4" - name8 = "name_in_lower_case" - name9 = "NameAlreadyInPascalCase" - name10 = "Name_With_%_Invalid_&_Symbols_£_" - name11 = "a_b_c_d" - name12 = "test" - assert snake_to_pascal(name1) == "NameInSnakeCase" - assert snake_to_pascal(name2) == "name-not-in-snake-case" - assert snake_to_pascal(name3) == "name_with-different_separators" - assert snake_to_pascal(name4) == "NameWithNumbers123" - assert snake_to_pascal(name5) == "Numbers123InTheMiddle" - assert snake_to_pascal(name6) == "1_2_3_starting_with_numbers" - assert snake_to_pascal(name7) == "Name1With2A3Number4" - assert snake_to_pascal(name8) == "NameInLowerCase" - assert snake_to_pascal(name9) == "NameAlreadyInPascalCase" - assert snake_to_pascal(name10) == "Name_With_%_Invalid_&_Symbols_£_" - assert snake_to_pascal(name11) == "ABCD" - assert snake_to_pascal(name12) == "Test" +from fastcs.util import snake_to_pascal def test_pvi_validation_error():