Replace the inside of `qsTr(...)` / similar calls with ASCII filler so only non-ASCII outside the call body is reported. Handles balanced parens, string-aware so nested parens inside string literals don't end the call early.
(line: str)
| 1320 | |
| 1321 | |
| 1322 | def _strip_translation_args(line: str) -> str: |
| 1323 | """Replace the inside of `qsTr(...)` / similar calls with ASCII filler so |
| 1324 | only non-ASCII outside the call body is reported. Handles balanced parens, |
| 1325 | string-aware so nested parens inside string literals don't end the call |
| 1326 | early.""" |
| 1327 | out: list[str] = [] |
| 1328 | i = 0 |
| 1329 | n = len(line) |
| 1330 | while i < n: |
| 1331 | m = _TRANSLATION_CALL_RE.match(line, i) |
| 1332 | if not m: |
| 1333 | out.append(line[i]) |
| 1334 | i += 1 |
| 1335 | continue |
| 1336 | |
| 1337 | out.append(line[i : m.end()]) |
| 1338 | i = m.end() |
| 1339 | depth = 1 |
| 1340 | in_str: str | None = None |
| 1341 | escape = False |
| 1342 | while i < n and depth > 0: |
| 1343 | ch = line[i] |
| 1344 | if in_str is not None: |
| 1345 | if escape: |
| 1346 | escape = False |
| 1347 | elif ch == "\\": |
| 1348 | escape = True |
| 1349 | elif ch == in_str: |
| 1350 | in_str = None |
| 1351 | # Replace any non-ASCII *inside* the string with a placeholder |
| 1352 | # so the outer scan ignores it. |
| 1353 | out.append("." if ord(ch) >= 128 else ch) |
| 1354 | i += 1 |
| 1355 | continue |
| 1356 | |
| 1357 | if ch in ("'", '"', "`"): |
| 1358 | in_str = ch |
| 1359 | out.append(ch) |
| 1360 | elif ch == "(": |
| 1361 | depth += 1 |
| 1362 | out.append(ch) |
| 1363 | elif ch == ")": |
| 1364 | depth -= 1 |
| 1365 | out.append(ch) |
| 1366 | else: |
| 1367 | out.append("." if ord(ch) >= 128 else ch) |
| 1368 | i += 1 |
| 1369 | return "".join(out) |
| 1370 | |
| 1371 | |
| 1372 | def find_non_ascii_violations( |
no test coverage detected