Skip to content

Commit 37166d9

Browse files
authored
Merge pull request #83 from ISISComputingGroup/Ticket_8527_Fix_Ruff_Pyright
Ticket 8527 fix ruff pyright
2 parents b11b666 + 51dbaa2 commit 37166d9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+531
-265
lines changed

check_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import upgrade
44

55

6-
def compare_version_number(version_to_check):
6+
def compare_version_number(version_to_check: str) -> int:
77
latest_version, _ = upgrade.UPGRADE_STEPS[-1]
88

99
if latest_version == version_to_check:

requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
gitpython
22
mysql-connector-python
3+
PyHamcrest
4+

src/common_upgrades/add_to_base_iocs.py

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
from xml.dom import minidom
22
from xml.parsers.expat import ExpatError
33

4-
IOC_FILENAME = "configurations\components\_base\iocs.xml"
4+
from src.file_access import FileAccess
5+
from src.local_logger import LocalLogger
6+
7+
IOC_FILENAME = r"configurations\components\_base\iocs.xml"
58

69
FILE_TO_CHECK_STR = "IOC default component file"
710
ALREADY_CONTAINS = "{} already contains {} ioc."
@@ -12,12 +15,14 @@
1215
class AddToBaseIOCs:
1316
"""Add the ioc autostart to _base ioc so that it autostarts"""
1417

15-
def __init__(self, ioc_to_add, add_after_ioc, xml_to_add):
18+
def __init__(
19+
self, ioc_to_add: str | None, add_after_ioc: str | None, xml_to_add: str | None
20+
) -> None:
1621
self._ioc_to_add = ioc_to_add
1722
self._add_after_ioc = add_after_ioc
1823
self._xml_to_add = xml_to_add
1924

20-
def perform(self, file_access, logger):
25+
def perform(self, file_access: FileAccess, logger: LocalLogger) -> int:
2126
"""Add the autostart of the given.
2227
2328
Args:
@@ -54,7 +59,7 @@ def perform(self, file_access, logger):
5459
return 0
5560

5661
@staticmethod
57-
def _get_ioc_names(xml):
62+
def _get_ioc_names(xml: minidom.Document) -> list[str]:
5863
"""Gets the names of all the iocs in the xml.
5964
6065
Args:
@@ -65,7 +70,9 @@ def _get_ioc_names(xml):
6570
"""
6671
return [ioc.getAttribute("name") for ioc in xml.getElementsByTagName("ioc")]
6772

68-
def _check_final_file_contains_one_of_added_ioc(self, logger, xml):
73+
def _check_final_file_contains_one_of_added_ioc(
74+
self, logger: LocalLogger, xml: minidom.Document
75+
) -> bool:
6976
"""Check the file to make sure it now contains one and only one ioc added entry.
7077
7178
Args:
@@ -77,14 +84,15 @@ def _check_final_file_contains_one_of_added_ioc(self, logger, xml):
7784
"""
7885
ioc_names = AddToBaseIOCs._get_ioc_names(xml)
7986

87+
assert self._ioc_to_add is not None
8088
node_count = ioc_names.count(self._ioc_to_add)
8189
if node_count != 1:
8290
# I can not see how to generate this error but it is here because it is important
8391
logger.error(INCORRECT_ADDING.format(FILE_TO_CHECK_STR, node_count, self._ioc_to_add))
8492
return False
8593
return True
8694

87-
def _check_prerequistes_for_file(self, xml, logger):
95+
def _check_prerequistes_for_file(self, xml: minidom.Document, logger: LocalLogger) -> bool:
8896
"""Check the file can be modified.
8997
9098
Args:
@@ -95,11 +103,11 @@ def _check_prerequistes_for_file(self, xml, logger):
95103
True if everything is ok, else False.
96104
"""
97105
ioc_names = AddToBaseIOCs._get_ioc_names(xml)
98-
106+
assert self._ioc_to_add is not None
99107
if ioc_names.count(self._ioc_to_add) != 0:
100108
logger.error(ALREADY_CONTAINS.format(FILE_TO_CHECK_STR, self._ioc_to_add))
101109
return False
102-
110+
assert self._add_after_ioc is not None
103111
node_count = ioc_names.count(self._add_after_ioc)
104112
if node_count != 1:
105113
logger.error(
@@ -108,7 +116,7 @@ def _check_prerequistes_for_file(self, xml, logger):
108116
return False
109117
return True
110118

111-
def _add_ioc(self, ioc_xml, logger):
119+
def _add_ioc(self, ioc_xml: minidom.Document, logger: LocalLogger) -> minidom.Document:
112120
"""Add IOC entry after add after ioc specified if it exists.
113121
114122
Args:
@@ -119,7 +127,9 @@ def _add_ioc(self, ioc_xml, logger):
119127
"""
120128
for ioc in ioc_xml.getElementsByTagName("ioc"):
121129
if ioc.getAttribute("name") == self._add_after_ioc:
130+
assert self._xml_to_add is not None
122131
new_ioc_node = minidom.parseString(self._xml_to_add).firstChild
132+
assert ioc_xml.firstChild is not None
123133
ioc_xml.firstChild.insertBefore(new_ioc_node, ioc.nextSibling)
124134
# add some formatting to make it look nice
125135
ioc_xml.firstChild.insertBefore(ioc_xml.createTextNode("\n "), new_ioc_node)

src/common_upgrades/change_macro_in_globals.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
import re
2+
from typing import Generator
23

34
from src.common_upgrades.utils.constants import GLOBALS_FILENAME
5+
from src.common_upgrades.utils.macro import Macro
6+
from src.file_access import FileAccess
7+
from src.local_logger import LocalLogger
48

59

610
class ChangeMacroInGlobals(object):
711
"""An interface to replace arbitrary macros in a globals.txt file"""
812

9-
def __init__(self, file_access, logger):
13+
def __init__(self, file_access: FileAccess, logger: LocalLogger) -> None:
1014
"""Initialise.
1115
1216
Args:
@@ -17,7 +21,7 @@ def __init__(self, file_access, logger):
1721
self._logger = logger
1822
self._loaded_file = self.load_globals_file()
1923

20-
def load_globals_file(self):
24+
def load_globals_file(self) -> list:
2125
"""Loads in a globals file as a list of strings.
2226
2327
Returns:
@@ -29,7 +33,7 @@ def load_globals_file(self):
2933
else:
3034
return []
3135

32-
def change_macros(self, ioc_name, macros_to_change):
36+
def change_macros(self, ioc_name: str, macros_to_change: list[tuple[Macro, Macro]]) -> None:
3337
"""Changes a list of macros in the globals.txt file for a specific IOC.
3438
3539
Args:
@@ -46,7 +50,7 @@ def change_macros(self, ioc_name, macros_to_change):
4650

4751
self.write_modified_globals_file()
4852

49-
def change_ioc_name(self, old_ioc_name, new_ioc_name):
53+
def change_ioc_name(self, old_ioc_name: str, new_ioc_name: str) -> None:
5054
"""Changes the name of an IOC in a globals.txt file.
5155
5256
Args:
@@ -62,7 +66,7 @@ def change_ioc_name(self, old_ioc_name, new_ioc_name):
6266

6367
self.write_modified_globals_file()
6468

65-
def _globals_filter_generator(self, ioc_to_change):
69+
def _globals_filter_generator(self, ioc_to_change: str) -> Generator[int, None, None]:
6670
"""Returns lines containing specified IOCs from globals.txt
6771
6872
Generator that gives all the lines for a given IOC in globals.txt.
@@ -80,7 +84,7 @@ def _globals_filter_generator(self, ioc_to_change):
8084
self._logger.info("Found line '{}' in {}".format(line, GLOBALS_FILENAME))
8185
yield index
8286

83-
def _determine_replacement_values(self, old_macro, new_macro):
87+
def _determine_replacement_values(self, old_macro: Macro, new_macro: Macro) -> dict[str, str]:
8488
"""Determines the strings to search for and replace.
8589
8690
Args:
@@ -110,7 +114,9 @@ def _determine_replacement_values(self, old_macro, new_macro):
110114

111115
return regex_changes
112116

113-
def _apply_regex_macro_change(self, ioc_name, old_macro, new_macro, line_number):
117+
def _apply_regex_macro_change(
118+
self, ioc_name: str, old_macro: Macro, new_macro: Macro, line_number: int
119+
) -> None:
114120
"""Applies a regular expression to modify a macro.
115121
116122
Args:
@@ -135,7 +141,7 @@ def _apply_regex_macro_change(self, ioc_name, old_macro, new_macro, line_number)
135141
self._loaded_file[line_number],
136142
)
137143

138-
def _change_ioc_name(self, ioc_name, new_ioc_name, line_number):
144+
def _change_ioc_name(self, ioc_name: str, new_ioc_name: str, line_number: int) -> None:
139145
"""If a new name is supplied, changes the name of the IOC
140146
141147
Args:
@@ -150,7 +156,7 @@ def _change_ioc_name(self, ioc_name, new_ioc_name, line_number):
150156
ioc_name, new_ioc_name.upper()
151157
)
152158

153-
def write_modified_globals_file(self):
159+
def write_modified_globals_file(self) -> None:
154160
"""Writes the modified globals file if it has been loaded.
155161
156162
Returns:

src/common_upgrades/change_macros_in_xml.py

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
import re
2+
from typing import Generator
3+
from xml.dom.minidom import Document, Element, Text
24
from xml.parsers.expat import ExpatError
35

46
from src.common_upgrades.utils.constants import FILTER_REGEX, IOC_FILE, SYNOPTIC_FOLDER
7+
from src.common_upgrades.utils.macro import Macro
8+
from src.file_access import FileAccess
9+
from src.local_logger import LocalLogger
510

611

7-
def change_macro_name(macro, old_macro_name, new_macro_name):
12+
def change_macro_name(macro: Element, old_macro_name: str, new_macro_name: str) -> None:
813
"""Changes the macro name of a macro xml node.
914
1015
Args:
@@ -17,7 +22,9 @@ def change_macro_name(macro, old_macro_name, new_macro_name):
1722
macro.setAttribute("name", new_macro_name)
1823

1924

20-
def change_macro_value(macro, old_macro_value, new_macro_value):
25+
def change_macro_value(
26+
macro: Element, old_macro_value: str | None, new_macro_value: str | None
27+
) -> None:
2128
"""Changes the macros in the given xml if a new macro value is given.
2229
2330
Args:
@@ -33,7 +40,7 @@ def change_macro_value(macro, old_macro_value, new_macro_value):
3340
macro.setAttribute("value", new_macro_value)
3441

3542

36-
def find_macro_with_name(macros, name_to_find):
43+
def find_macro_with_name(macros: Element, name_to_find: str) -> bool:
3744
"""Find whether macro with name attribute equal to argument name_to_find exists
3845
3946
Args:
@@ -51,7 +58,9 @@ def find_macro_with_name(macros, name_to_find):
5158
class ChangeMacrosInXML(object):
5259
"""Changes macros in XML files."""
5360

54-
def __init__(self, file_access, logger):
61+
_ioc_file_generator: object
62+
63+
def __init__(self, file_access: FileAccess, logger: LocalLogger) -> None:
5564
"""Initialise.
5665
5766
Args:
@@ -62,20 +71,27 @@ def __init__(self, file_access, logger):
6271
self._logger = logger
6372

6473
def add_macro(
65-
self, ioc_name, macro_to_add, pattern, description="No description", default_value=None
66-
):
67-
"""Add a macro with a specified name and value to all IOCs whose name begins with ioc_name, unless a macro
68-
with that name already exists
74+
self,
75+
ioc_name: str,
76+
macro_to_add: Macro,
77+
pattern: str,
78+
description: str = "No description",
79+
default_value: str | None = None,
80+
) -> None:
81+
"""Add a macro with a specified name and value to all IOCs whose name begins with ioc_name,
82+
unless a macro with that name already exists
6983
7084
Args:
71-
ioc_name: Name of the IOC to add the macro to (e.g. DFKPS would add macros to DFKPS_01 and DFKPS_02)
72-
macro_to_add: Macro class with desired name and value
73-
pattern: Regex pattern describing what values the macro accepts e.g. "^(0|1)$" for 0 or 1
85+
ioc_name: Name of the IOC to add the macro to (e.g. DFKPS would add macros to DFKPS_01
86+
and DFKPS_02) macro_to_add: Macro class with desired name and value
87+
pattern: Regex pattern describing what values the macro accepts e.g. "^(0|1)$" for 0/1
7488
description: Description of macro purpose
7589
default_value: An optional default value for the macro
7690
Returns:
7791
None
7892
"""
93+
assert macro_to_add.name is not None
94+
assert macro_to_add.value is not None
7995
for path, ioc_xml in self._file_access.get_config_files(IOC_FILE):
8096
for ioc in self.ioc_tag_generator(path, ioc_xml, ioc_name):
8197
macros = ioc.getElementsByTagName("macros")[0]
@@ -88,7 +104,7 @@ def add_macro(
88104

89105
self._file_access.write_xml_file(path, ioc_xml)
90106

91-
def change_macros(self, ioc_name, macros_to_change):
107+
def change_macros(self, ioc_name: str, macros_to_change: list[tuple[Macro, Macro]]) -> None:
92108
"""Changes macros in all xml files that contain the correct macros for a specified ioc.
93109
94110
Args:
@@ -103,15 +119,16 @@ def change_macros(self, ioc_name, macros_to_change):
103119
macros = ioc.getElementsByTagName("macros")[0]
104120
for macro in macros.getElementsByTagName("macro"):
105121
name = macro.getAttribute("name")
106-
for old_macro, new_macro in macros_to_change:
107-
# Check if current macro name starts with name of macro to be changed
108-
if re.match(old_macro.name, name) is not None:
109-
change_macro_name(macro, old_macro.name, new_macro.name)
110-
change_macro_value(macro, old_macro.value, new_macro.value)
122+
if name is not None:
123+
for old_macro, new_macro in macros_to_change:
124+
# Check if current macro name starts with name of macro to be changed
125+
if re.match(old_macro.name, name) is not None:
126+
change_macro_name(macro, old_macro.name, new_macro.name)
127+
change_macro_value(macro, old_macro.value, new_macro.value)
111128

112129
self._file_access.write_xml_file(path, ioc_xml)
113130

114-
def change_ioc_name(self, old_ioc_name, new_ioc_name):
131+
def change_ioc_name(self, old_ioc_name: str, new_ioc_name: str) -> None:
115132
"""Replaces all instances of old_ioc_name with new_ioc_name in an XML tree
116133
Args:
117134
old_ioc_name: String, the old ioc prefix (without _XX number suffix)
@@ -131,7 +148,7 @@ def change_ioc_name(self, old_ioc_name, new_ioc_name):
131148

132149
self._file_access.write_xml_file(path, ioc_xml)
133150

134-
def change_ioc_name_in_synoptics(self, old_ioc_name, new_ioc_name):
151+
def change_ioc_name_in_synoptics(self, old_ioc_name: str, new_ioc_name: str) -> None:
135152
"""Replaces instances of old_ioc_name with new_ioc_name
136153
137154
Args:
@@ -155,7 +172,10 @@ def change_ioc_name_in_synoptics(self, old_ioc_name, new_ioc_name):
155172
for element in synoptic_xml.getElementsByTagName("value"):
156173
# Obtain text between the <value> tags (https://stackoverflow.com/a/317494 and https://stackoverflow.com/a/13591742)
157174
if element.firstChild is not None:
158-
if element.firstChild.nodeType == element.TEXT_NODE:
175+
if (
176+
isinstance(element.firstChild, Text)
177+
and element.firstChild.nodeType == element.TEXT_NODE
178+
):
159179
ioc_name_with_suffix = element.firstChild.nodeValue
160180

161181
if old_ioc_name in ioc_name_with_suffix:
@@ -166,7 +186,9 @@ def change_ioc_name_in_synoptics(self, old_ioc_name, new_ioc_name):
166186

167187
self._file_access.write_xml_file(xml_path, synoptic_xml)
168188

169-
def ioc_tag_generator(self, path, ioc_xml, ioc_to_change):
189+
def ioc_tag_generator(
190+
self, path: str, ioc_xml: Document, ioc_to_change: str
191+
) -> Generator[Element, None, None]:
170192
"""Generator giving all the IOC tags in all configurations.
171193
172194
Args:

0 commit comments

Comments
 (0)