Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions Doc/library/plistlib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ This module defines the following functions:
.. versionchanged:: 3.13
*data* can be a string when *fmt* equals :data:`FMT_XML`.

.. function:: dump(value, fp, *, fmt=FMT_XML, sort_keys=True, skipkeys=False, aware_datetime=False)
.. function:: dump(value, fp, *, fmt=FMT_XML, sort_keys=True, skipkeys=False, aware_datetime=False, compact=False)

Write *value* to a plist file. *Fp* should be a writable, binary
file object.
Expand All @@ -120,6 +120,8 @@ This module defines the following functions:
is set as an :ref:`aware object <datetime-naive-aware>`, it will convert to
UTC timezone before writing it.

When *compact* is true, the XML elements will be written without indentation.

A :exc:`TypeError` will be raised if the object is of an unsupported type or
a container that contains objects of unsupported types.

Expand All @@ -131,8 +133,11 @@ This module defines the following functions:
.. versionchanged:: 3.13
The keyword-only parameter *aware_datetime* has been added.

.. versionchanged:: 3.14
The keyword-only parameter *compact* has been added.


.. function:: dumps(value, *, fmt=FMT_XML, sort_keys=True, skipkeys=False, aware_datetime=False)
.. function:: dumps(value, *, fmt=FMT_XML, sort_keys=True, skipkeys=False, aware_datetime=False, compact=False)

Return *value* as a plist-formatted bytes object. See
the documentation for :func:`dump` for an explanation of the keyword
Expand Down
9 changes: 9 additions & 0 deletions Doc/whatsnew/3.14.rst
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,15 @@ pydoc
(Contributed by Jelle Zijlstra in :gh:`101552`.)


plistlib
--------

* Add a new parameter *compact* to :func:`plistlib.dump` and
:func:`plistlib.dumps`. When *compact* is true, the XML elements will
be written without indentation.
(Contributed by Jiahao Li in :gh:`113056`.)


symtable
--------

Expand Down
27 changes: 15 additions & 12 deletions Lib/plistlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,11 +287,12 @@ def end_date(self):


class _DumbXMLWriter:
def __init__(self, file, indent_level=0, indent="\t"):
def __init__(self, file, indent_level=0, indent="\t", compact=False):
self.file = file
self.stack = []
self._indent_level = indent_level
self.indent = indent
self.compact = compact

def begin_element(self, element):
self.stack.append(element)
Expand All @@ -308,7 +309,6 @@ def simple_element(self, element, value=None):
if value is not None:
value = _escape(value)
self.writeln("<%s>%s</%s>" % (element, value, element))

else:
self.writeln("<%s/>" % element)

Expand All @@ -319,19 +319,22 @@ def writeln(self, line):
# XXX: is this test needed?
if isinstance(line, str):
line = line.encode('utf-8')
self.file.write(self._indent_level * self.indent)
self.file.write(line)
self.file.write(b'\n')
if not self.compact:
self.file.write(self._indent_level * self.indent)
self.file.write(line)
self.file.write(b'\n')
else:
self.file.write(line)


class _PlistWriter(_DumbXMLWriter):
def __init__(
self, file, indent_level=0, indent=b"\t", writeHeader=1,
sort_keys=True, skipkeys=False, aware_datetime=False):
sort_keys=True, skipkeys=False, aware_datetime=False, compact=False):

if writeHeader:
file.write(PLISTHEADER)
_DumbXMLWriter.__init__(self, file, indent_level, indent)
_DumbXMLWriter.__init__(self, file, indent_level, indent, compact)
self._sort_keys = sort_keys
self._skipkeys = skipkeys
self._aware_datetime = aware_datetime
Expand Down Expand Up @@ -642,7 +645,7 @@ def _count_to_size(count):
_scalars = (str, int, float, datetime.datetime, bytes)

class _BinaryPlistWriter (object):
def __init__(self, fp, sort_keys, skipkeys, aware_datetime=False):
def __init__(self, fp, sort_keys, skipkeys, aware_datetime=False, compact=False):
self._fp = fp
self._sort_keys = sort_keys
self._skipkeys = skipkeys
Expand Down Expand Up @@ -917,23 +920,23 @@ def loads(value, *, fmt=None, dict_type=dict, aware_datetime=False):


def dump(value, fp, *, fmt=FMT_XML, sort_keys=True, skipkeys=False,
aware_datetime=False):
aware_datetime=False, compact=False):
"""Write 'value' to a .plist file. 'fp' should be a writable,
binary file object.
"""
if fmt not in _FORMATS:
raise ValueError("Unsupported format: %r"%(fmt,))

writer = _FORMATS[fmt]["writer"](fp, sort_keys=sort_keys, skipkeys=skipkeys,
aware_datetime=aware_datetime)
aware_datetime=aware_datetime, compact=compact)
writer.write(value)


def dumps(value, *, fmt=FMT_XML, skipkeys=False, sort_keys=True,
aware_datetime=False):
aware_datetime=False, compact=False):
"""Return a bytes object with the contents for a .plist file.
"""
fp = BytesIO()
dump(value, fp, fmt=fmt, skipkeys=skipkeys, sort_keys=sort_keys,
aware_datetime=aware_datetime)
aware_datetime=aware_datetime, compact=compact)
return fp.getvalue()
8 changes: 7 additions & 1 deletion Lib/test/test_plistlib.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# Copyright (C) 2003-2013 Python Software Foundation
import copy
import operator
import pickle
Expand Down Expand Up @@ -900,6 +899,13 @@ def test_dump_naive_datetime_with_aware_datetime_option(self):
expected = dt.astimezone(datetime.UTC).replace(tzinfo=None)
self.assertEqual(parsed, expected)

def test_compact_mode(self):
pl = self._create()
for fmt in ALL_FORMATS:
with self.subTest(fmt=fmt):
data = plistlib.dumps(pl, fmt=fmt, compact=True)
pl2 = plistlib.loads(data)
self.assertEqual(dict(pl), dict(pl2))

class TestBinaryPlistlib(unittest.TestCase):

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Add a new parameter *compact* to :func:`plistlib.dump` and
:func:`plistlib.dumps`. When *compact* is true, the XML elements will be
written without indentation.
Loading