Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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 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
8 changes: 8 additions & 0 deletions Doc/whatsnew/3.14.rst
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,14 @@ 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
24 changes: 14 additions & 10 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')
if not self.compact:
self.file.write(self._indent_level * self.indent)
self.file.write(line)
self.file.write(b'\n')
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,11 +645,12 @@ 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
self._aware_datetime = aware_datetime
self._compact = compact

def write(self, value):

Expand Down Expand Up @@ -917,23 +921,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