Skip to content

Commit 89666b6

Browse files
jensensclaude
andcommitted
Warn about non-UTF-8 files instead of crashing with UnicodeDecodeError
XML/ZCML/PT files should be UTF-8. Instead of silently skipping or crashing, emit a warning so users can fix the encoding. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 807e6bf commit 89666b6

3 files changed

Lines changed: 53 additions & 4 deletions

File tree

CHANGES.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Changelog
22

3+
## 1.0.0a5 (2026-03-02)
4+
5+
- Warn about non-UTF-8 encoded files instead of crashing with
6+
`UnicodeDecodeError`. XML/ZCML/PT files should be UTF-8; the tool
7+
now prints a warning and skips the file so users can fix the encoding.
8+
[jensens]
9+
310
## 1.0.0a4 (2026-03-02)
411

512
- Fix Phase 1 failing with "Could not find plone_codemod.import_migrator

src/plone_codemod/pt_migrator.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from pathlib import Path
1414
from typing import Any
1515

16+
import warnings
1617
import yaml
1718

1819

@@ -59,7 +60,17 @@ def _migrate_files(
5960
"""Walk directory, apply transformer to matching files."""
6061
modified = []
6162
for filepath in sorted(root.rglob(pattern)):
62-
content = filepath.read_text(encoding="utf-8")
63+
try:
64+
content = filepath.read_text(encoding="utf-8")
65+
except UnicodeDecodeError:
66+
warnings.warn(
67+
f"{filepath} is not UTF-8 encoded — skipping. "
68+
f"XML/PT files should be UTF-8. Please fix the encoding.",
69+
stacklevel=2,
70+
)
71+
continue
72+
except OSError:
73+
continue
6374
new_content = transformer(content, **kwargs)
6475
if new_content != content:
6576
modified.append(filepath)

src/plone_codemod/zcml_migrator.py

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from pathlib import Path
1313
from typing import Any
1414

15+
import warnings
1516
import yaml
1617

1718

@@ -82,7 +83,17 @@ def migrate_file(
8283
filepath: Path, transformer: Callable[..., str], **kwargs: Any
8384
) -> bool:
8485
"""Read file, apply transformer, write back if changed. Returns True if modified."""
85-
content = filepath.read_text(encoding="utf-8")
86+
try:
87+
content = filepath.read_text(encoding="utf-8")
88+
except UnicodeDecodeError:
89+
warnings.warn(
90+
f"{filepath} is not UTF-8 encoded — skipping. "
91+
f"XML/ZCML files should be UTF-8. Please fix the encoding.",
92+
stacklevel=2,
93+
)
94+
return False
95+
except OSError:
96+
return False
8697
new_content = transformer(content, **kwargs)
8798
if new_content != content:
8899
filepath.write_text(new_content, encoding="utf-8")
@@ -102,7 +113,17 @@ def migrate_zcml_files(
102113
modified = []
103114
for zcml_file in sorted(root.rglob("*.zcml")):
104115
if dry_run:
105-
content = zcml_file.read_text(encoding="utf-8")
116+
try:
117+
content = zcml_file.read_text(encoding="utf-8")
118+
except UnicodeDecodeError:
119+
warnings.warn(
120+
f"{zcml_file} is not UTF-8 encoded — skipping. "
121+
f"ZCML files should be UTF-8. Please fix the encoding.",
122+
stacklevel=2,
123+
)
124+
continue
125+
except OSError:
126+
continue
106127
new_content = migrate_zcml_content(content, replacements)
107128
if new_content != content:
108129
modified.append(zcml_file)
@@ -139,7 +160,17 @@ def migrate_genericsetup_files(
139160
continue
140161

141162
if dry_run:
142-
content = xml_file.read_text(encoding="utf-8")
163+
try:
164+
content = xml_file.read_text(encoding="utf-8")
165+
except UnicodeDecodeError:
166+
warnings.warn(
167+
f"{xml_file} is not UTF-8 encoded — skipping. "
168+
f"XML files should be UTF-8. Please fix the encoding.",
169+
stacklevel=2,
170+
)
171+
continue
172+
except OSError:
173+
continue
143174
new_content = migrate_genericsetup_content(
144175
content, replacements, view_replacements
145176
)

0 commit comments

Comments
 (0)