Skip to content

Commit f89010f

Browse files
chore: Fix py3.10 regex compile error (#1072)
In python 3.10, re.compile fails when there is a "++" in the pattern, which can happen in unread data checker, since the columns can be anything (and scientific data can have ++'s)
1 parent b8a4057 commit f89010f

3 files changed

Lines changed: 29 additions & 11 deletions

File tree

src/allotropy/parsers/utils/json.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,22 @@ def _get_custom_key(self, key: str) -> float | str | None:
7373
return float_value
7474
return self.get(str, key)
7575

76+
def _key_matches(self, match_key: str, key: str) -> bool:
77+
if key == match_key:
78+
return True
79+
# "++" can cause re.compile to fail. Since it is never a valid regex expression
80+
# it is safe to escape it to prevent the error.
81+
match_key = match_key.replace("++", r"\+\+")
82+
return bool(re.fullmatch(match_key, key))
83+
7684
def _get_matching_keys(self, key_or_keys: str | set[str]) -> set[str]:
7785
return {
7886
matched
7987
for regex_key in (
8088
key_or_keys if isinstance(key_or_keys, set) else {key_or_keys}
8189
)
8290
for matched in [
83-
k
84-
for k in self.data.keys()
85-
if k == regex_key or re.fullmatch(regex_key, k)
91+
k for k in self.data.keys() if self._key_matches(str(regex_key), str(k))
8692
]
8793
}
8894

src/allotropy/parsers/utils/pandas.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,14 @@ def _get_custom_key(self, key: str) -> float | str | None:
273273
return float_value
274274
return self.get(str, key)
275275

276+
def _key_matches(self, match_key: str, key: str) -> bool:
277+
if key == match_key:
278+
return True
279+
# "++" can cause re.compile to fail. Since it is never a valid regex expression
280+
# it is safe to escape it to prevent the error.
281+
match_key = match_key.replace("++", r"\+\+")
282+
return bool(re.fullmatch(match_key, key))
283+
276284
def _get_matching_keys(self, key_or_keys: str | set[str]) -> set[str]:
277285
return {
278286
matched
@@ -282,7 +290,7 @@ def _get_matching_keys(self, key_or_keys: str | set[str]) -> set[str]:
282290
for matched in [
283291
k
284292
for k in self.series.index
285-
if k == regex_key or re.fullmatch(str(regex_key), str(k))
293+
if self._key_matches(str(regex_key), str(k))
286294
]
287295
}
288296

src/allotropy/parsers/utils/strict_xml_element.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,14 @@ def _get_all_available_keys(self) -> set[str]:
137137

138138
return keys
139139

140+
def _key_matches(self, match_key: str, key: str) -> bool:
141+
if key == match_key:
142+
return True
143+
# "++" can cause re.compile to fail. Since it is never a valid regex expression
144+
# it is safe to escape it to prevent the error.
145+
match_key = match_key.replace("++", r"\+\+")
146+
return bool(re.fullmatch(match_key, key))
147+
140148
def _get_matching_keys(self, key_or_keys: str | set[str]) -> set[str]:
141149
"""Get keys that match the given pattern(s)."""
142150
all_keys = self._get_all_available_keys()
@@ -155,9 +163,7 @@ def _get_matching_keys(self, key_or_keys: str | set[str]) -> set[str]:
155163
matches_found = False
156164

157165
# Check for exact match
158-
if any(
159-
k for k in all_keys if k == attr_key or re.fullmatch(attr_key, k)
160-
):
166+
if any(k for k in all_keys if self._key_matches(attr_key, k)):
161167
normalized_keys.add(attr_key)
162168
matches_found = True
163169

@@ -184,9 +190,7 @@ def _get_matching_keys(self, key_or_keys: str | set[str]) -> set[str]:
184190
return {
185191
matched
186192
for regex_key in normalized_keys
187-
for matched in [
188-
k for k in all_keys if k == regex_key or re.fullmatch(regex_key, k)
189-
]
193+
for matched in [k for k in all_keys if self._key_matches(str(regex_key), k)]
190194
}
191195

192196
def mark_read(self, key_or_keys: str | set[str]) -> None:
@@ -266,7 +270,7 @@ def _apply_regex_filter(
266270
) -> set[str]:
267271
"""Apply regex filter to attribute keys if provided."""
268272
if regex:
269-
return {k for k in attribute_keys if re.fullmatch(regex, k)}
273+
return {k for k in attribute_keys if self._key_matches(regex, k)}
270274
return attribute_keys
271275

272276
def _process_attr_key(

0 commit comments

Comments
 (0)