Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-xmltodict for
openSUSE:Factory checked in at 2026-03-15 14:31:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-xmltodict (Old)
and /work/SRC/openSUSE:Factory/.python-xmltodict.new.8177 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-xmltodict"
Sun Mar 15 14:31:52 2026 rev:17 rq:1338812 version:1.0.4
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-xmltodict/python-xmltodict.changes
2026-03-10 17:47:01.763984106 +0100
+++
/work/SRC/openSUSE:Factory/.python-xmltodict.new.8177/python-xmltodict.changes
2026-03-15 14:31:53.466212901 +0100
@@ -1,0 +2,11 @@
+Fri Mar 13 20:42:04 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 1.0.4:
+ * **unparse:** add bytes_errors policy and handle bytes scalars
+ consistently
+- update to 1.0.3:
+ * **unparse:** serialize None text/attrs as empty values (fixes
+ #401)
+ * **readme:** fix Fedora and Arch package links
+
+-------------------------------------------------------------------
Old:
----
xmltodict-1.0.2.tar.gz
New:
----
xmltodict-1.0.4.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-xmltodict.spec ++++++
--- /var/tmp/diff_new_pack.j3Ii72/_old 2026-03-15 14:31:54.338248797 +0100
+++ /var/tmp/diff_new_pack.j3Ii72/_new 2026-03-15 14:31:54.342248961 +0100
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-xmltodict
-Version: 1.0.2
+Version: 1.0.4
Release: 0
Summary: Module to make XML working resemble JSON
License: MIT
++++++ xmltodict-1.0.2.tar.gz -> xmltodict-1.0.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmltodict-1.0.2/MANIFEST.in
new/xmltodict-1.0.4/MANIFEST.in
--- old/xmltodict-1.0.2/MANIFEST.in 2025-09-17 23:59:06.000000000 +0200
+++ new/xmltodict-1.0.4/MANIFEST.in 2026-02-22 03:21:02.000000000 +0100
@@ -1,3 +1 @@
-include README.md
-include LICENSE
recursive-include tests *
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmltodict-1.0.2/PKG-INFO new/xmltodict-1.0.4/PKG-INFO
--- old/xmltodict-1.0.2/PKG-INFO 2025-09-17 23:59:11.217250600 +0200
+++ new/xmltodict-1.0.4/PKG-INFO 2026-02-22 03:21:09.137860300 +0100
@@ -1,19 +1,11 @@
Metadata-Version: 2.4
Name: xmltodict
-Version: 1.0.2
+Version: 1.0.4
Summary: Makes working with XML feel like you are working with JSON
Author: Martin Blech
-License: Copyright (C) 2012 Martin Blech and individual contributors.
-
- Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
-
+License-Expression: MIT
Project-URL: Homepage, https://github.com/martinblech/xmltodict
Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
@@ -263,6 +255,7 @@
- `input_dict`: Dictionary to convert to XML.
- `output=None`: File-like object to write XML to; returns string if None.
- `encoding='utf-8'`: Encoding of the output XML.
+- `bytes_errors='replace'`: Error handler used when decoding byte values
during unparse (for example `'replace'`, `'strict'`, `'ignore'`).
- `full_document=True`: Include XML declaration if True.
- `short_empty_elements=False`: Use short tags for empty elements (`<tag/>`).
- `attr_prefix='@'`: Prefix for dictionary keys representing attributes.
@@ -346,15 +339,15 @@
### RPM-based distro (Fedora, RHEL, …)
-There is an [official Fedora package for
xmltodict](https://apps.fedoraproject.org/packages/python-xmltodict).
+There is an [official Fedora package for
xmltodict](https://packages.fedoraproject.org/pkgs/python-xmltodict/).
```sh
-$ sudo yum install python-xmltodict
+$ sudo yum install python3-xmltodict
```
### Arch Linux
-There is an [official Arch Linux package for
xmltodict](https://www.archlinux.org/packages/community/any/python-xmltodict/).
+There is an [official Arch Linux package for
xmltodict](https://archlinux.org/packages/extra/any/python-xmltodict/).
```sh
$ sudo pacman -S python-xmltodict
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmltodict-1.0.2/README.md
new/xmltodict-1.0.4/README.md
--- old/xmltodict-1.0.2/README.md 2025-09-17 23:59:06.000000000 +0200
+++ new/xmltodict-1.0.4/README.md 2026-02-22 03:21:02.000000000 +0100
@@ -228,6 +228,7 @@
- `input_dict`: Dictionary to convert to XML.
- `output=None`: File-like object to write XML to; returns string if None.
- `encoding='utf-8'`: Encoding of the output XML.
+- `bytes_errors='replace'`: Error handler used when decoding byte values
during unparse (for example `'replace'`, `'strict'`, `'ignore'`).
- `full_document=True`: Include XML declaration if True.
- `short_empty_elements=False`: Use short tags for empty elements (`<tag/>`).
- `attr_prefix='@'`: Prefix for dictionary keys representing attributes.
@@ -311,15 +312,15 @@
### RPM-based distro (Fedora, RHEL, …)
-There is an [official Fedora package for
xmltodict](https://apps.fedoraproject.org/packages/python-xmltodict).
+There is an [official Fedora package for
xmltodict](https://packages.fedoraproject.org/pkgs/python-xmltodict/).
```sh
-$ sudo yum install python-xmltodict
+$ sudo yum install python3-xmltodict
```
### Arch Linux
-There is an [official Arch Linux package for
xmltodict](https://www.archlinux.org/packages/community/any/python-xmltodict/).
+There is an [official Arch Linux package for
xmltodict](https://archlinux.org/packages/extra/any/python-xmltodict/).
```sh
$ sudo pacman -S python-xmltodict
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmltodict-1.0.2/pyproject.toml
new/xmltodict-1.0.4/pyproject.toml
--- old/xmltodict-1.0.2/pyproject.toml 2025-09-17 23:59:06.000000000 +0200
+++ new/xmltodict-1.0.4/pyproject.toml 2026-02-22 03:21:02.000000000 +0100
@@ -1,18 +1,18 @@
[build-system]
-requires = ["setuptools>=61", "wheel"]
+requires = ["setuptools>=77.0.3"]
build-backend = "setuptools.build_meta"
[project]
name = "xmltodict"
-version = "1.0.2"
+version = "1.0.4"
description = "Makes working with XML feel like you are working with JSON"
readme = "README.md"
requires-python = ">=3.9"
-license = { file = "LICENSE" }
+license = "MIT"
+license-files = ["LICENSE"]
authors = [{ name = "Martin Blech" }]
classifiers = [
"Intended Audience :: Developers",
- "License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmltodict-1.0.2/tests/test_dicttoxml.py
new/xmltodict-1.0.4/tests/test_dicttoxml.py
--- old/xmltodict-1.0.2/tests/test_dicttoxml.py 2025-09-17 23:59:06.000000000
+0200
+++ new/xmltodict-1.0.4/tests/test_dicttoxml.py 2026-02-22 03:21:02.000000000
+0100
@@ -178,6 +178,29 @@
assert xml == "<!--t1--><!--t2--><a>1</a>"
+def test_unparse_with_bytes_comment_uses_output_encoding():
+ obj = {"#comment": b"caf\xe9", "a": "1"}
+ xml = _strip(unparse(obj, full_document=True, encoding="iso-8859-1"))
+ assert xml == "<!--caf\xe9--><a>1</a>"
+
+
+def test_unparse_invalid_bytes_comment_replaced_by_default():
+ obj = {"#comment": b"\xff", "a": "1"}
+ xml = _strip(unparse(obj, full_document=True, encoding="utf-8"))
+ assert xml == "<!--\ufffd--><a>1</a>"
+
+
+def test_unparse_rejects_invalid_bytes_comment_for_encoding_with_strict():
+ obj = {"#comment": b"\xff", "a": "1"}
+ with pytest.raises(UnicodeDecodeError, match="'utf-8' codec can't decode
byte 0xff"):
+ unparse(
+ obj,
+ full_document=True,
+ encoding="utf-8",
+ bytes_errors="strict",
+ )
+
+
def test_unparse_rejects_comment_with_double_hyphen():
obj = {"#comment": "bad--comment", "a": "1"}
with pytest.raises(ValueError, match="cannot contain '--'"):
@@ -298,6 +321,39 @@
assert xml == expected_xml
+def test_xmlns_values_use_consistent_boolean_coercion():
+ xml = unparse({"root": {"@xmlns": {"a": True}}}, full_document=False)
+ assert xml == '<root xmlns:a="true"></root>'
+
+
+def test_xmlns_values_decode_bytes_with_output_encoding():
+ xml = unparse(
+ {"root": {"@xmlns": {"a": b"http://ex\xe9.com/"}}},
+ full_document=False,
+ encoding="iso-8859-1",
+ )
+ assert xml == '<root xmlns:a="http://ex\xe9.com/"></root>'
+
+
+def test_xmlns_values_replace_invalid_bytes_by_default():
+ xml = unparse(
+ {"root": {"@xmlns": {"a": b"\xff"}}},
+ full_document=False,
+ encoding="utf-8",
+ )
+ assert xml == '<root xmlns:a="\ufffd"></root>'
+
+
+def test_xmlns_values_reject_invalid_bytes_with_strict():
+ with pytest.raises(UnicodeDecodeError, match="'utf-8' codec can't decode
byte 0xff"):
+ unparse(
+ {"root": {"@xmlns": {"a": b"\xff"}}},
+ full_document=False,
+ encoding="utf-8",
+ bytes_errors="strict",
+ )
+
+
def test_boolean_unparse():
expected_xml = '<?xml version="1.0" encoding="utf-8"?>\n<x>true</x>'
xml = unparse(dict(x=True))
@@ -307,6 +363,56 @@
xml = unparse(dict(x=False))
assert xml == expected_xml
+ expected_xml = '<?xml version="1.0" encoding="utf-8"?>\n<x
attr="true"></x>'
+ xml = unparse({'x': {'@attr': True}})
+ assert xml == expected_xml
+
+ expected_xml = '<?xml version="1.0" encoding="utf-8"?>\n<x
attr="false"></x>'
+ xml = unparse({'x': {'@attr': False}})
+ assert xml == expected_xml
+
+
+def test_unparse_bytes_in_attributes_and_cdata_use_output_encoding():
+ xml = unparse({"x": {"@attr": b"caf\xe9", "#text": b"caf\xe9"}},
full_document=False, encoding="iso-8859-1")
+ assert xml == '<x attr="caf\xe9">caf\xe9</x>'
+
+
+def test_unparse_bytes_text_node_uses_output_encoding():
+ xml = unparse({"x": b"caf\xe9"}, full_document=False,
encoding="iso-8859-1")
+ assert xml == "<x>caf\xe9</x>"
+
+
+def test_unparse_bytes_text_node_with_expand_iter_uses_output_encoding():
+ xml = unparse({"x": b"caf\xe9"}, full_document=False,
encoding="iso-8859-1", expand_iter="item")
+ assert xml == "<x>caf\xe9</x>"
+
+
+def test_unparse_invalid_bytes_in_attributes_and_cdata_replaced_by_default():
+ xml = unparse({"x": {"@attr": b"\xff", "#text": b"\xff"}},
full_document=False, encoding="utf-8")
+ assert xml == '<x attr="\ufffd">\ufffd</x>'
+
+
+def test_unparse_invalid_bytes_text_node_replaced_by_default():
+ xml = unparse({"x": b"\xff"}, full_document=False, encoding="utf-8")
+ assert xml == "<x>\ufffd</x>"
+
+
+def
test_unparse_rejects_invalid_bytes_in_attributes_and_cdata_for_encoding_with_strict():
+ with pytest.raises(UnicodeDecodeError, match="'utf-8' codec can't decode
byte 0xff"):
+ unparse({"x": {"@attr": b"\xff"}}, full_document=False,
encoding="utf-8", bytes_errors="strict")
+ with pytest.raises(UnicodeDecodeError, match="'utf-8' codec can't decode
byte 0xff"):
+ unparse({"x": {"#text": b"\xff"}}, full_document=False,
encoding="utf-8", bytes_errors="strict")
+
+
+def test_unparse_rejects_invalid_bytes_text_node_for_encoding_with_strict():
+ with pytest.raises(UnicodeDecodeError, match="'utf-8' codec can't decode
byte 0xff"):
+ unparse({"x": b"\xff"}, full_document=False, encoding="utf-8",
bytes_errors="strict")
+
+
+def test_unparse_rejects_invalid_bytes_errors_handler():
+ with pytest.raises(ValueError, match="Invalid bytes_errors handler: nope"):
+ unparse({"x": {"@attr": b"\xff"}}, full_document=False,
bytes_errors="nope")
+
def test_rejects_tag_name_with_angle_brackets():
# Minimal guard: disallow '<' or '>' to prevent breaking tag context
@@ -573,7 +679,7 @@
assert unparse({"a": {"@param": "flag", "#text": True}},
full_document=False) == '<a param="flag">true</a>'
- assert unparse({"a": {"@param": "test", "#text": None}},
full_document=False) == '<a param="test">None</a>'
+ assert unparse({"a": {"@param": "test", "#text": None}},
full_document=False) == '<a param="test"></a>'
assert unparse({"a": {"@param": "test", "#text": "string"}},
full_document=False) == '<a param="test">string</a>'
@@ -594,3 +700,13 @@
assert unparse({"a": True}, full_document=False) == unparse({"a":
{"#text": True}}, full_document=False)
assert unparse({"a": "hello"}, full_document=False) == unparse({"a":
{"#text": "hello"}}, full_document=False)
+ assert unparse({"a": None}, full_document=False) == unparse({"a":
{"#text": None}}, full_document=False)
+
+
+def test_none_text_with_short_empty_elements_and_attributes():
+ obj = {"x": {"#text": None, "@pro": None}, "y": None}
+ assert unparse(obj, short_empty_elements=True, full_document=False) == '<x
pro=""/><y/>'
+
+
+def test_none_attribute_serializes_as_empty_string():
+ assert unparse({"x": {"@pro": None}}, full_document=False) == '<x
pro=""></x>'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmltodict-1.0.2/xmltodict.egg-info/PKG-INFO
new/xmltodict-1.0.4/xmltodict.egg-info/PKG-INFO
--- old/xmltodict-1.0.2/xmltodict.egg-info/PKG-INFO 2025-09-17
23:59:11.000000000 +0200
+++ new/xmltodict-1.0.4/xmltodict.egg-info/PKG-INFO 2026-02-22
03:21:09.000000000 +0100
@@ -1,19 +1,11 @@
Metadata-Version: 2.4
Name: xmltodict
-Version: 1.0.2
+Version: 1.0.4
Summary: Makes working with XML feel like you are working with JSON
Author: Martin Blech
-License: Copyright (C) 2012 Martin Blech and individual contributors.
-
- Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
-
+License-Expression: MIT
Project-URL: Homepage, https://github.com/martinblech/xmltodict
Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
@@ -263,6 +255,7 @@
- `input_dict`: Dictionary to convert to XML.
- `output=None`: File-like object to write XML to; returns string if None.
- `encoding='utf-8'`: Encoding of the output XML.
+- `bytes_errors='replace'`: Error handler used when decoding byte values
during unparse (for example `'replace'`, `'strict'`, `'ignore'`).
- `full_document=True`: Include XML declaration if True.
- `short_empty_elements=False`: Use short tags for empty elements (`<tag/>`).
- `attr_prefix='@'`: Prefix for dictionary keys representing attributes.
@@ -346,15 +339,15 @@
### RPM-based distro (Fedora, RHEL, …)
-There is an [official Fedora package for
xmltodict](https://apps.fedoraproject.org/packages/python-xmltodict).
+There is an [official Fedora package for
xmltodict](https://packages.fedoraproject.org/pkgs/python-xmltodict/).
```sh
-$ sudo yum install python-xmltodict
+$ sudo yum install python3-xmltodict
```
### Arch Linux
-There is an [official Arch Linux package for
xmltodict](https://www.archlinux.org/packages/community/any/python-xmltodict/).
+There is an [official Arch Linux package for
xmltodict](https://archlinux.org/packages/extra/any/python-xmltodict/).
```sh
$ sudo pacman -S python-xmltodict
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmltodict-1.0.2/xmltodict.py
new/xmltodict-1.0.4/xmltodict.py
--- old/xmltodict-1.0.2/xmltodict.py 2025-09-17 23:59:06.000000000 +0200
+++ new/xmltodict-1.0.4/xmltodict.py 2026-02-22 03:21:02.000000000 +0100
@@ -6,6 +6,7 @@
from xml.sax.xmlreader import AttributesImpl
from io import StringIO
from inspect import isgenerator
+import codecs
class ParsingInterrupted(Exception):
pass
@@ -369,16 +370,20 @@
return handler.item
-def _convert_value_to_string(value):
+def _convert_value_to_string(value, encoding='utf-8', bytes_errors='replace'):
"""Convert a value to its string representation for XML output.
Handles boolean values consistently by converting them to lowercase.
"""
- if isinstance(value, (str, bytes)):
+ if isinstance(value, str):
return value
if isinstance(value, bool):
return "true" if value else "false"
+ if isinstance(value, (bytes, bytearray, memoryview)):
+ return bytes(value).decode(encoding, errors=bytes_errors)
return str(value)
+
+
def _validate_name(value, kind):
"""Validate an element/attribute name for XML safety.
@@ -446,6 +451,8 @@
namespaces=None,
full_document=True,
expand_iter=None,
+ encoding='utf-8',
+ bytes_errors='replace',
comment_key='#comment'):
if isinstance(key, str) and key == comment_key:
comments_list = value if isinstance(value, list) else [value]
@@ -454,7 +461,9 @@
for comment_text in comments_list:
if comment_text is None:
continue
- comment_text = _convert_value_to_string(comment_text)
+ comment_text = _convert_value_to_string(
+ comment_text, encoding=encoding, bytes_errors=bytes_errors
+ )
if not comment_text:
continue
if pretty:
@@ -472,7 +481,7 @@
key, value = result
# Minimal validation to avoid breaking out of tag context
_validate_name(key, "element")
- if not hasattr(value, '__iter__') or isinstance(value, (str, dict)):
+ if not hasattr(value, '__iter__') or isinstance(value, (str, bytes,
bytearray, memoryview, dict)):
value = [value]
for index, v in enumerate(value):
if full_document and depth == 0 and index > 0:
@@ -480,10 +489,10 @@
if v is None:
v = {}
elif not isinstance(v, (dict, str)):
- if expand_iter and hasattr(v, '__iter__'):
+ if expand_iter and hasattr(v, '__iter__') and not isinstance(v,
(bytes, bytearray, memoryview)):
v = {expand_iter: v}
else:
- v = _convert_value_to_string(v)
+ v = _convert_value_to_string(v, encoding=encoding,
bytes_errors=bytes_errors)
if isinstance(v, str):
v = {cdata_key: v}
cdata = None
@@ -491,7 +500,10 @@
children = []
for ik, iv in v.items():
if ik == cdata_key:
- cdata = _convert_value_to_string(iv)
+ if iv is None:
+ cdata = None
+ else:
+ cdata = _convert_value_to_string(iv, encoding=encoding,
bytes_errors=bytes_errors)
continue
if isinstance(ik, str) and ik.startswith(attr_prefix):
ik = _process_namespace(ik, namespaces, namespace_separator,
@@ -500,10 +512,14 @@
for k, v in iv.items():
_validate_name(k, "attribute")
attr = 'xmlns{}'.format(f':{k}' if k else '')
- attrs[attr] = str(v)
+ attrs[attr] = '' if v is None else
_convert_value_to_string(
+ v, encoding=encoding, bytes_errors=bytes_errors
+ )
continue
- if not isinstance(iv, str):
- iv = str(iv)
+ if iv is None:
+ iv = ''
+ elif not isinstance(iv, str):
+ iv = _convert_value_to_string(iv, encoding=encoding,
bytes_errors=bytes_errors)
attr_name = ik[len(attr_prefix) :]
_validate_name(attr_name, "attribute")
attrs[attr_name] = iv
@@ -523,7 +539,8 @@
attr_prefix, cdata_key, depth+1, preprocessor,
pretty, newl, indent, namespaces=namespaces,
namespace_separator=namespace_separator,
- expand_iter=expand_iter, comment_key=comment_key)
+ expand_iter=expand_iter, encoding=encoding,
+ bytes_errors=bytes_errors, comment_key=comment_key)
if cdata is not None:
content_handler.characters(cdata)
if pretty and children:
@@ -558,8 +575,16 @@
The `pretty` parameter (default=`False`) enables pretty-printing. In this
mode, lines are terminated with `'\n'` and indented with `'\t'`, but this
can be customized with the `newl` and `indent` parameters.
+ The `bytes_errors` parameter controls decoding errors for byte values and
+ defaults to `'replace'`.
"""
+ bytes_errors = kwargs.pop('bytes_errors', 'replace')
+ try:
+ codecs.lookup_error(bytes_errors)
+ except LookupError as exc:
+ raise ValueError(f"Invalid bytes_errors handler: {bytes_errors}") from
exc
+
must_return = False
if output is None:
output = StringIO()
@@ -574,7 +599,16 @@
for key, value in input_dict.items():
if key != comment_key and full_document and seen_root:
raise ValueError("Document must have exactly one root.")
- _emit(key, value, content_handler, full_document=full_document,
comment_key=comment_key, **kwargs)
+ _emit(
+ key,
+ value,
+ content_handler,
+ full_document=full_document,
+ encoding=encoding,
+ bytes_errors=bytes_errors,
+ comment_key=comment_key,
+ **kwargs,
+ )
if key != comment_key:
seen_root = True
if full_document and not seen_root: