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:

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}")