1
1
import re
2
+ from typing import Generator
3
+ from xml .dom .minidom import Document , Element , Text
2
4
from xml .parsers .expat import ExpatError
3
5
4
6
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
5
10
6
11
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 :
8
13
"""Changes the macro name of a macro xml node.
9
14
10
15
Args:
@@ -17,7 +22,9 @@ def change_macro_name(macro, old_macro_name, new_macro_name):
17
22
macro .setAttribute ("name" , new_macro_name )
18
23
19
24
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 :
21
28
"""Changes the macros in the given xml if a new macro value is given.
22
29
23
30
Args:
@@ -33,7 +40,7 @@ def change_macro_value(macro, old_macro_value, new_macro_value):
33
40
macro .setAttribute ("value" , new_macro_value )
34
41
35
42
36
- def find_macro_with_name (macros , name_to_find ) :
43
+ def find_macro_with_name (macros : Element , name_to_find : str ) -> bool :
37
44
"""Find whether macro with name attribute equal to argument name_to_find exists
38
45
39
46
Args:
@@ -51,7 +58,9 @@ def find_macro_with_name(macros, name_to_find):
51
58
class ChangeMacrosInXML (object ):
52
59
"""Changes macros in XML files."""
53
60
54
- def __init__ (self , file_access , logger ):
61
+ _ioc_file_generator : object
62
+
63
+ def __init__ (self , file_access : FileAccess , logger : LocalLogger ) -> None :
55
64
"""Initialise.
56
65
57
66
Args:
@@ -62,20 +71,27 @@ def __init__(self, file_access, logger):
62
71
self ._logger = logger
63
72
64
73
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
69
83
70
84
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
74
88
description: Description of macro purpose
75
89
default_value: An optional default value for the macro
76
90
Returns:
77
91
None
78
92
"""
93
+ assert macro_to_add .name is not None
94
+ assert macro_to_add .value is not None
79
95
for path , ioc_xml in self ._file_access .get_config_files (IOC_FILE ):
80
96
for ioc in self .ioc_tag_generator (path , ioc_xml , ioc_name ):
81
97
macros = ioc .getElementsByTagName ("macros" )[0 ]
@@ -88,7 +104,7 @@ def add_macro(
88
104
89
105
self ._file_access .write_xml_file (path , ioc_xml )
90
106
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 :
92
108
"""Changes macros in all xml files that contain the correct macros for a specified ioc.
93
109
94
110
Args:
@@ -103,15 +119,16 @@ def change_macros(self, ioc_name, macros_to_change):
103
119
macros = ioc .getElementsByTagName ("macros" )[0 ]
104
120
for macro in macros .getElementsByTagName ("macro" ):
105
121
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 )
111
128
112
129
self ._file_access .write_xml_file (path , ioc_xml )
113
130
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 :
115
132
"""Replaces all instances of old_ioc_name with new_ioc_name in an XML tree
116
133
Args:
117
134
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):
131
148
132
149
self ._file_access .write_xml_file (path , ioc_xml )
133
150
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 :
135
152
"""Replaces instances of old_ioc_name with new_ioc_name
136
153
137
154
Args:
@@ -155,7 +172,10 @@ def change_ioc_name_in_synoptics(self, old_ioc_name, new_ioc_name):
155
172
for element in synoptic_xml .getElementsByTagName ("value" ):
156
173
# Obtain text between the <value> tags (https://stackoverflow.com/a/317494 and https://stackoverflow.com/a/13591742)
157
174
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
+ ):
159
179
ioc_name_with_suffix = element .firstChild .nodeValue
160
180
161
181
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):
166
186
167
187
self ._file_access .write_xml_file (xml_path , synoptic_xml )
168
188
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 ]:
170
192
"""Generator giving all the IOC tags in all configurations.
171
193
172
194
Args:
0 commit comments