Skip to content

Commit a91d88a

Browse files
committed
#16 Improve file handling
1 parent 197798c commit a91d88a

File tree

5 files changed

+30
-37
lines changed

5 files changed

+30
-37
lines changed

pyproject.toml

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -99,22 +99,6 @@ ignore = [
9999
"PLR0915",
100100
# Magic value used in comparison
101101
"PLR2004",
102-
# TODO Enable checks for usage of pathlib.
103-
"PTH100",
104-
"PTH103",
105-
"PTH107",
106-
"PTH109",
107-
"PTH110",
108-
"PTH112",
109-
"PTH114",
110-
"PTH118",
111-
"PTH119",
112-
"PTH120",
113-
"PTH122",
114-
"PTH123",
115-
"PTH202",
116-
"PTH207",
117-
"PTH208",
118102
# Unneccesarry assign → We regularly use `result = ...; return result` to examine the result in the debugger.
119103
"RET504",
120104
# Mutable class attributes should be annotated with `typing.ClassVar`

sanpo/command.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import glob
55
import logging
66
import sys
7+
from pathlib import Path
78

89
from . import __version__, log
910
from .sanitize import sanitize_file
@@ -19,6 +20,7 @@ def _parsed_args(args=None):
1920
# However, when passing multiple files this results in
2021
# ResourceWarning: unclosed file <_io.TextIOWrapper...>.
2122
nargs="+",
23+
type=Path,
2224
help='PO file(s) to sanitize; use glob patterns to process multiple files; use "**" for recursive scans',
2325
)
2426
return parser.parse_args(args)
@@ -27,13 +29,20 @@ def _parsed_args(args=None):
2729
def main_without_logging_setup(args=None) -> int:
2830
result = 0
2931
po_path = None
32+
actual_args = [(str(arg) if isinstance(arg, Path) else arg) for arg in args]
3033
sanitized_file_count = 0
31-
arguments = _parsed_args(args)
34+
arguments = _parsed_args(actual_args)
3235
try:
3336
for po_path_pattern in arguments.po_paths:
34-
for po_path in glob.iglob(po_path_pattern, recursive=True):
35-
sanitize_file(po_path)
37+
if po_path_pattern.is_file():
38+
sanitize_file(po_path_pattern)
3639
sanitized_file_count += 1
40+
else:
41+
for po_path in glob.iglob(str(po_path_pattern), recursive=True): # noqa: PTH207
42+
# There does not seem to be a way for `path.glob(pattern)` to separate `path` from the `pattern`,
43+
# while `iglob(path_with_pattern)` can process a single combined path and pattern.
44+
sanitize_file(po_path)
45+
sanitized_file_count += 1
3746
except Exception as error:
3847
log.error('cannot sanitize "%s": %s', po_path, error)
3948
result = 1

sanpo/sanitize.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
# All rights reserved. Distributed under the BSD 3-Clause License.
33
import logging
44
import re
5+
from collections.abc import Iterable
6+
from pathlib import Path
57

68
_LINE_PATTERNS_TO_REMOVE = [
79
re.compile(line)
@@ -20,16 +22,17 @@
2022
_log = logging.getLogger("sanpo")
2123

2224

23-
def sanitize_file(po_path: str):
25+
def sanitize_file(po_path: Path):
26+
assert isinstance(po_path, Path), f"po_path must be a Path: {po_path!r}"
2427
_log.info("sanitizing %s", po_path)
25-
with open(po_path, encoding="utf-8") as po_file:
26-
lines_to_write = list(sanitize_lines(po_file))
27-
with open(po_path, "w", encoding="utf-8") as po_file:
28+
with po_path.open(encoding="utf-8") as po_file:
29+
lines_to_write = list(sanitized_lines(po_file))
30+
with po_path.open("w", encoding="utf-8") as po_file:
2831
for line_to_write in lines_to_write:
2932
po_file.write(line_to_write)
3033

3134

32-
def sanitize_lines(source_lines):
35+
def sanitized_lines(source_lines: Iterable[str]) -> Iterable[str]:
3336
for line in source_lines:
3437
line_has_to_be_removed = any(
3538
line_pattern_to_remove.match(line) for line_pattern_to_remove in _LINE_PATTERNS_TO_REMOVE

tests/_common.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Copyright (c) 2021, Thomas Aglassinger
22
# All rights reserved. Distributed under the BSD 3-Clause License.
3-
import os
3+
from pathlib import Path
44
from typing import Optional
55
from unittest import TestCase
66

7-
TEST_TEMP_FOLDER = os.path.join(os.path.dirname(__file__), "temp")
7+
TEST_TEMP_FOLDER = Path(__file__).parent / "temp"
88

99

1010
class PoFileTest(TestCase):
@@ -26,17 +26,14 @@ def write_po_file(self, test_name: str):
2626
'msgid "spam"',
2727
'msgstr ""',
2828
]
29-
self.po_path = os.path.join(TEST_TEMP_FOLDER, test_name + ".po")
30-
with open(self.po_path, "w", encoding="utf-8") as po_file:
31-
for po_line in po_lines:
32-
po_file.write(f"{po_line}\n")
29+
self.po_path = TEST_TEMP_FOLDER / (test_name + ".po")
30+
self.po_path.write_text("\n".join(po_lines) + "\n")
3331
self._po_paths_to_remove.append(self.po_path)
3432

35-
def po_lines(self, po_path: Optional[str] = None) -> list[str]:
33+
def po_lines(self, po_path: Optional[Path] = None) -> list[str]:
3634
actual_po_path = po_path if po_path is not None else self.po_path
37-
with open(actual_po_path, encoding="utf-8") as po_file:
38-
return [line.rstrip("\n") for line in po_file]
35+
return actual_po_path.read_text().split("\n")
3936

4037
def tearDown(self):
4138
for po_path_to_remove in self._po_paths_to_remove:
42-
os.remove(po_path_to_remove)
39+
po_path_to_remove.unlink()

tests/test_sanitize.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# All rights reserved. Distributed under the BSD 3-Clause License.
33
from unittest import TestCase
44

5-
from sanpo.sanitize import sanitize_file, sanitize_lines
5+
from sanpo.sanitize import sanitize_file, sanitized_lines
66
from tests._common import PoFileTest
77

88

@@ -17,7 +17,7 @@ def test_can_remove_pointless_lines(self):
1717
r'"Language-Team: LANGUAGE [email protected]\n"',
1818
"PRESERVE",
1919
]
20-
self.assertEqual(list(sanitize_lines(source_lines)), ["PRESERVE"])
20+
self.assertEqual(list(sanitized_lines(source_lines)), ["PRESERVE"])
2121

2222
def test_can_preserve_metadata_lines(self):
2323
source_lines = [
@@ -26,7 +26,7 @@ def test_can_preserve_metadata_lines(self):
2626
r'"Last-Translator: John Doe [email protected]\n"',
2727
r'"Language-Team: en [email protected]\n"',
2828
]
29-
self.assertEqual(list(sanitize_lines(source_lines)), source_lines)
29+
self.assertEqual(list(sanitized_lines(source_lines)), source_lines)
3030

3131

3232
class TransformFileTest(PoFileTest):

0 commit comments

Comments
 (0)