--- Begin Message ---
Package: debmutate
Version: 0.71
Severity: important
Tags: python3.13
The python3-debmutate package fails to handle UTF-8 encoded files when
running under Python 3.13. This affects multiple Debian packaging
tools including lintian-brush, making it impossible to process
packages containing non-ASCII characters.
When running lintian-brush, the following error occurs:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position
705: ordinal not in range(128)
This error occurs in debmutate/reformatting.py, line 223:
self._orig_content = f.read()
The error appears when processing both debian/copyright and
debian/changelog files that contain UTF-8 characters. Setting
PYTHONIOENCODING=utf8 does not resolve the issue.
Steps to reproduce:
1. Have a package with non-ASCII characters in debian/copyright or
debian/changelog
2. Run: lintian-brush --no-update-changelog --modern --uncertain
3. Observe the UnicodeDecodeError
The error occurs with multiple lintian-brush fixers:
- global-files-wildcard-not-first-paragraph-in-dep5-copyright
- new-package-uses-date-based-version-number
This appears to be a regression in Python 3.13 handling, as these
files are valid UTF-8 and can be processed correctly by iconv and
other tools.
Full log of lintian-brush on package MariaDB in Debian unstable for
further reference below.
***************
# dpkg -l | grep -E 'debmutate|lintian'
ii lintian 2.121.1
all Debian package checker
ii lintian-brush 0.160+b2
amd64 automatically fix lintian problems
ii python3-debmutate 0.71
all Format-preserving manipulation of Debian control files
in Python
# file -i debian/copyright debian/changelog
debian/copyright: text/plain; charset=utf-8
debian/changelog: text/plain; charset=utf-8
# PYTHONIOENCODING=utf8 lintian-brush --no-update-changelog --modern --uncertain
[ ] 154/154No changes made.
Some fixer scripts failed to run:
copyright-missing-upstream-info: Script failed:
/usr/share/lintian-brush/fixers/copyright-missing-upstream-info.py
(exit code 1) (stderr:
Traceback (most recent call last):
File "/usr/share/lintian-brush/fixers/copyright-missing-upstream-info.py",
line 80, in <module>
), CopyrightEditor() as updater:
~~~~~~~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/debmutate/reformatting.py",
line 223, in __enter__
self._orig_content = f.read()
~~~~~~^^
File "/usr/lib/python3.13/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position
5806: ordinal not in range(128)
)
debian-changelog-line-too-long: Script failed:
/usr/share/lintian-brush/fixers/debian-changelog-line-too-long.py
(exit code 1) (stderr:
Traceback (most recent call last):
File "/usr/share/lintian-brush/fixers/debian-changelog-line-too-long.py",
line 42, in <module>
with ChangelogEditor() as updater:
~~~~~~~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/debmutate/reformatting.py",
line 223, in __enter__
self._orig_content = f.read()
~~~~~~^^
File "/usr/lib/python3.13/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position
705: ordinal not in range(128)
)
obsolete-field-in-dep5-copyright: Script failed:
/usr/share/lintian-brush/fixers/obsolete-field-in-dep5-copyright.py
(exit code 1) (stderr:
Traceback (most recent call last):
File "/usr/share/lintian-brush/fixers/obsolete-field-in-dep5-copyright.py",
line 47, in <module>
), CopyrightEditor() as updater:
~~~~~~~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/debmutate/reformatting.py",
line 223, in __enter__
self._orig_content = f.read()
~~~~~~^^
File "/usr/lib/python3.13/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position
5806: ordinal not in range(128)
)
upstream-metadata-file: Timeout after 10s
initial-upload-closes-no-bugs: Script failed:
/usr/share/lintian-brush/fixers/initial-upload-closes-no-bugs.py (exit
code 1) (stderr:
Traceback (most recent call last):
File "/usr/share/lintian-brush/fixers/initial-upload-closes-no-bugs.py",
line 21, in <module>
with ChangelogEditor() as editor:
~~~~~~~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/debmutate/reformatting.py",
line 223, in __enter__
self._orig_content = f.read()
~~~~~~^^
File "/usr/lib/python3.13/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position
705: ordinal not in range(128)
)
ancient-maintscript-entry: Script failed:
/usr/share/lintian-brush/fixers/ancient-maintscript-entry.py (exit
code 1) (stderr:
Traceback (most recent call last):
File "/usr/share/lintian-brush/fixers/ancient-maintscript-entry.py",
line 52, in <module>
with ChangelogEditor() as cl:
~~~~~~~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/debmutate/reformatting.py",
line 223, in __enter__
self._orig_content = f.read()
~~~~~~^^
File "/usr/lib/python3.13/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position
705: ordinal not in range(128)
)
space-in-std-shortname-in-dep5-copyright: Script failed:
/usr/share/lintian-brush/fixers/space-in-std-shortname-in-dep5-copyright.py
(exit code 1) (stderr:
Traceback (most recent call last):
File
"/usr/share/lintian-brush/fixers/space-in-std-shortname-in-dep5-copyright.py",
line 68, in <module>
), CopyrightEditor() as updater:
~~~~~~~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/debmutate/reformatting.py",
line 223, in __enter__
self._orig_content = f.read()
~~~~~~^^
File "/usr/lib/python3.13/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position
5806: ordinal not in range(128)
)
debian-changelog-has-wrong-day-of-week: Script failed:
/usr/share/lintian-brush/fixers/debian-changelog-has-wrong-day-of-week.py
(exit code 1) (stderr:
Traceback (most recent call last):
File
"/usr/share/lintian-brush/fixers/debian-changelog-has-wrong-day-of-week.py",
line 12, in <module>
with ChangelogEditor() as updater:
~~~~~~~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/debmutate/reformatting.py",
line 223, in __enter__
self._orig_content = f.read()
~~~~~~^^
File "/usr/lib/python3.13/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position
705: ordinal not in range(128)
)
invalid-short-name-in-dep5-copyright: Script failed:
/usr/share/lintian-brush/fixers/invalid-short-name-in-dep5-copyright.py
(exit code 1) (stderr:
Traceback (most recent call last):
File
"/usr/share/lintian-brush/fixers/invalid-short-name-in-dep5-copyright.py",
line 50, in <module>
), CopyrightEditor() as updater:
~~~~~~~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/debmutate/reformatting.py",
line 223, in __enter__
self._orig_content = f.read()
~~~~~~^^
File "/usr/lib/python3.13/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position
5806: ordinal not in range(128)
)
dep5-file-paragraph-references-header-paragraph: Script failed:
/usr/share/lintian-brush/fixers/dep5-file-paragraph-references-header-paragraph.py
(exit code 1) (stderr:
Traceback (most recent call last):
File
"/usr/share/lintian-brush/fixers/dep5-file-paragraph-references-header-paragraph.py",
line 41, in <module>
with CopyrightEditor() as updater:
~~~~~~~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/debmutate/reformatting.py",
line 223, in __enter__
self._orig_content = f.read()
~~~~~~^^
File "/usr/lib/python3.13/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position
5806: ordinal not in range(128)
)
out-of-date-standards-version: Script failed:
/usr/share/lintian-brush/fixers/out-of-date-standards-version.py (exit
code 1) (stderr:
Traceback (most recent call last):
File "/usr/share/lintian-brush/fixers/out-of-date-standards-version.py",
line 301, in <module>
svs = dict(iter_standards_versions())
File "/usr/lib/python3/dist-packages/lintian_brush/standards_version.py",
line 41, in iter_standards_versions
data = json.load(f)
File "/usr/lib/python3.13/json/__init__.py", line 293, in load
return loads(fp.read(),
~~~~~~~^^
File "/usr/lib/python3.13/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position
4315: ordinal not in range(128)
)
global-files-wildcard-not-first-paragraph-in-dep5-copyright: Script
failed:
/usr/share/lintian-brush/fixers/global-files-wildcard-not-first-paragraph-in-dep5-copyright.py
(exit code 1) (stderr:
Traceback (most recent call last):
File
"/usr/share/lintian-brush/fixers/global-files-wildcard-not-first-paragraph-in-dep5-copyright.py",
line 11, in <module>
), CopyrightEditor() as editor:
~~~~~~~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/debmutate/reformatting.py",
line 223, in __enter__
self._orig_content = f.read()
~~~~~~^^
File "/usr/lib/python3.13/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position
5806: ordinal not in range(128)
)
common-license: Script failed:
/usr/share/lintian-brush/fixers/common-license.py (exit code 1)
(stderr:
Traceback (most recent call last):
File "/usr/share/lintian-brush/fixers/common-license.py", line 271,
in <module>
), CopyrightEditor() as updater:
~~~~~~~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/debmutate/reformatting.py",
line 223, in __enter__
self._orig_content = f.read()
~~~~~~^^
File "/usr/lib/python3.13/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position
5806: ordinal not in range(128)
)
changelog-has-duplicate-line: Script failed:
/usr/share/lintian-brush/fixers/changelog-has-duplicate-line.py (exit
code 1) (stderr:
Traceback (most recent call last):
File "/usr/share/lintian-brush/fixers/changelog-has-duplicate-line.py",
line 7, in <module>
with ChangelogEditor() as updater:
~~~~~~~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/debmutate/reformatting.py",
line 223, in __enter__
self._orig_content = f.read()
~~~~~~^^
File "/usr/lib/python3.13/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position
705: ordinal not in range(128)
)
possible-missing-colon-in-closes: Script failed:
/usr/share/lintian-brush/fixers/possible-missing-colon-in-closes.py
(exit code 1) (stderr:
Traceback (most recent call last):
File "/usr/share/lintian-brush/fixers/possible-missing-colon-in-closes.py",
line 88, in <module>
with ChangelogEditor() as updater:
~~~~~~~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/debmutate/reformatting.py",
line 223, in __enter__
self._orig_content = f.read()
~~~~~~^^
File "/usr/lib/python3.13/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position
705: ordinal not in range(128)
)
unnecessary-team-upload: Script failed:
/usr/share/lintian-brush/fixers/unnecessary-team-upload.py (exit code
1) (stderr:
Traceback (most recent call last):
File "/usr/share/lintian-brush/fixers/unnecessary-team-upload.py",
line 19, in <module>
with ChangelogEditor() as updater:
~~~~~~~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/debmutate/reformatting.py",
line 223, in __enter__
self._orig_content = f.read()
~~~~~~^^
File "/usr/lib/python3.13/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position
705: ordinal not in range(128)
)
unused-license-paragraph-in-dep5-copyright: Script failed:
/usr/share/lintian-brush/fixers/unused-license-paragraph-in-dep5-copyright.py
(exit code 1) (stderr:
Traceback (most recent call last):
File
"/usr/share/lintian-brush/fixers/unused-license-paragraph-in-dep5-copyright.py",
line 33, in <module>
with CopyrightEditor() as updater:
~~~~~~~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/debmutate/reformatting.py",
line 223, in __enter__
self._orig_content = f.read()
~~~~~~^^
File "/usr/lib/python3.13/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position
5806: ordinal not in range(128)
)
copyright-refers-to-symlink-license: Script failed:
/usr/share/lintian-brush/fixers/copyright-refers-to-symlink-license.py
(exit code 1) (stderr:
Traceback (most recent call last):
File "/usr/share/lintian-brush/fixers/copyright-refers-to-symlink-license.py",
line 42, in <module>
), CopyrightEditor() as updater:
~~~~~~~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/debmutate/reformatting.py",
line 223, in __enter__
self._orig_content = f.read()
~~~~~~^^
File "/usr/lib/python3.13/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position
5806: ordinal not in range(128)
)
debian-rules-uses-unnecessary-dh-argument: Script failed:
/usr/share/lintian-brush/fixers/debian-rules-uses-unnecessary-dh-argument.py
(exit code 1) (stderr:
Traceback (most recent call last):
File
"/usr/share/lintian-brush/fixers/debian-rules-uses-unnecessary-dh-argument.py",
line 20, in <module>
compat_version = get_debhelper_compat_level()
File "/usr/lib/python3/dist-packages/debmutate/debhelper.py", line
123, in get_debhelper_compat_level
control = Deb822(f)
File "/usr/lib/python3/dist-packages/debian/deb822.py", line 673, in __init__
self._internal_parser(iterable, fields, strict)
~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/debian/deb822.py", line 817, in
_internal_parser
for linebytes in self._gpg_stripped_paragraph(
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
self._skip_useless_lines(sequence), strict):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/debian/deb822.py", line 1184,
in _gpg_stripped_paragraph
return cls._split_gpg_and_payload(sequence, strict)[1]
~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/debian/deb822.py", line 1133,
in _split_gpg_and_payload
for line in sequence:
^^^^^^^^
File "/usr/lib/python3/dist-packages/debian/deb822.py", line 773, in
_skip_useless_lines
for line in sequence:
^^^^^^^^
File "/usr/lib/python3.13/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position
152: ordinal not in range(128)
)
license-file-listed-in-debian-copyright: Script failed:
/usr/share/lintian-brush/fixers/license-file-listed-in-debian-copyright.py
(exit code 1) (stderr:
Traceback (most recent call last):
File
"/usr/share/lintian-brush/fixers/license-file-listed-in-debian-copyright.py",
line 19, in <module>
with CopyrightEditor() as updater:
~~~~~~~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/debmutate/reformatting.py",
line 223, in __enter__
self._orig_content = f.read()
~~~~~~^^
File "/usr/lib/python3.13/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position
5806: ordinal not in range(128)
)
invalid-standards-version: Script failed:
/usr/share/lintian-brush/fixers/invalid-standards-version.py (exit
code 1) (stderr:
Traceback (most recent call last):
File "/usr/share/lintian-brush/fixers/invalid-standards-version.py",
line 11, in <module>
release_dates = dict(iter_standards_versions())
File "/usr/lib/python3/dist-packages/lintian_brush/standards_version.py",
line 41, in iter_standards_versions
data = json.load(f)
File "/usr/lib/python3.13/json/__init__.py", line 293, in load
return loads(fp.read(),
~~~~~~~^^
File "/usr/lib/python3.13/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position
4315: ordinal not in range(128)
)
new-package-uses-date-based-version-number: Script failed:
/usr/share/lintian-brush/fixers/new-package-uses-date-based-version-number.py
(exit code 1) (stderr:
Traceback (most recent call last):
File
"/usr/share/lintian-brush/fixers/new-package-uses-date-based-version-number.py",
line 11, in <module>
with ChangelogEditor() as editor:
~~~~~~~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/debmutate/reformatting.py",
line 223, in __enter__
self._orig_content = f.read()
~~~~~~^^
File "/usr/lib/python3.13/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position
705: ordinal not in range(128)
)
Run with --verbose for details.
--- End Message ---