Parse Apple Plist Files in Python with plistlib
Apple property list (.plist) files are structured
serialization files widely used across macOS and iOS systems to store
user settings, configuration profiles, and application metadata. Python
provides built-in support for reading and writing these files through
the plistlib standard library module, removing the need for
third-party dependencies. This guide covers how plistlib
functions, how it maps plist data to native Python types, and how to
parse and generate both XML and binary plist formats.
Understanding plistlib
The plistlib module is part of Python's standard
library. It natively handles standard Apple plist types, including XML
plists and binary plists (commonly known as bplist00).
Because modern plists are often stored in binary form, all file
operations using plistlib must be conducted in binary mode
(rb or wb).
Reading and Parsing Plist Files
To read a .plist file from disk, use
plistlib.load(). If the plist data is already stored in
memory as a bytes object, use
plistlib.loads().
import plistlib
# Reading from a file on disk
with open("com.apple.example.plist", "rb") as fp:
plist_data = plistlib.load(fp)
# The result is typically a Python dictionary
print(plist_data)If you receive raw plist bytes (such as from a network request or process output):
raw_bytes = b'<?xml version="1.0" encoding="UTF-8"?>...'
plist_data = plistlib.loads(raw_bytes)plistlib automatically detects whether the input is in
XML or binary format and parses it into corresponding Python objects
without requiring format-specific flags.
Data Type Mapping
When plistlib parses a file, it converts plist types
into native Python objects:
<dict>becomesdict<array>becomeslist<string>becomesstr<integer>becomesint<real>becomesfloat<true/>/<false/>becomesbool<date>becomesdatetime.datetime<data>becomesbytes
Writing Plist Files
To export Python data back into a plist file, use
plistlib.dump() for files or plistlib.dumps()
to return a bytes object. By default, Python writes files
using the XML format (plistlib.FMT_XML), but you can
specify binary output (plistlib.FMT_BINARY) for reduced
file size and compatibility with macOS preferences.
import plistlib
from datetime import datetime
data = {
"ApplicationName": "DemoApp",
"Version": 1.2,
"IsEnabled": True,
"LastUpdated": datetime.now(),
"Items": ["Item1", "Item2", "Item3"],
}
# Writing as a binary plist
with open("output.plist", "wb") as fp:
plistlib.dump(data, fp, fmt=plistlib.FMT_BINARY)
# Writing as an XML plist
with open("output.xml.plist", "wb") as fp:
plistlib.dump(data, fp, fmt=plistlib.FMT_XML)Error Handling
When parsing untrusted or corrupted plists, plistlib
raises plistlib.InvalidFileException. Catching this
exception allows applications to handle malformed files gracefully.
try:
with open("corrupted.plist", "rb") as fp:
plist_data = plistlib.load(fp)
except plistlib.InvalidFileException as e:
print(f"Failed to parse plist: {e}")