bpylist2
bpylist2 is a Python library for parsing and generating NSKeyedArchiver archives, an Apple proprietary serialization format for Cocoa objects. It is a fork of the original `Marketcircle/bpylist` project, maintained to be more responsive to contributions. While it specializes in NSKeyedArchiver, it also includes a bundled `plistlib` compatible with Python 3.8 for older Python versions, though for standard binary plists, the `stdlib` `plistlib` is recommended. The current version is 4.1.1, released in September 2023.
Common errors
-
AttributeError: 'MyCustomClass' object has no attribute 'encode_archive'
cause You are attempting to archive an instance of a custom Python class without having properly defined the archiving interface for it.fixEnsure your custom class `MyCustomClass` either inherits from `bpylist2.archive_types.DataclassArchiver` (if it's a dataclass) or implements `encode_archive(obj, archive)` and `decode_archive(archive)` as static methods. -
bpylist2.archiver.UnarchiveError: Unknown class: 'SomeCustomCocoaClass'
cause The NSKeyedArchiver archive contains a custom Apple Cocoa class ('SomeCustomCocoaClass' in this example) that `bpylist2` does not have a registered Python class mapping for.fixDefine a corresponding Python class (e.g., `MyPythonClass`) that can handle the structure of 'SomeCustomCocoaClass', and then register it using `archiver.update_class_map({'SomeCustomCocoaClass': MyPythonClass})` before attempting to unarchive. -
bpylist2.archiver.UnarchiveError: Invalid magic string: 'bplist00' expected
cause This error typically occurs when you are trying to unarchive a file that is not a valid NSKeyedArchiver format, but rather a standard binary plist, or a corrupted file.fixVerify that the file is indeed an `NSKeyedArchiver` archive. If it's a regular binary plist, use Python's standard `plistlib` module instead. If it's expected to be `NSKeyedArchiver`, check the file's integrity.
Warnings
- gotcha When working with plain binary `.plist` files (not NSKeyedArchiver), `bpylist2` is not the correct tool. It will likely raise `UnarchiveError`.
- gotcha To archive or unarchive custom Python objects (that are not standard types like dicts, lists, strings, numbers), you must either implement `encode_archive` and `decode_archive` static methods on your class or inherit from `bpylist2.archive_types.DataclassArchiver`.
- gotcha When unarchiving a `NSKeyedArchiver` file containing custom Cocoa classes (not standard `NSString`, `NSArray`, etc.), `bpylist2` needs to know how to map these Cocoa classes to Python classes.
Install
-
pip install bpylist2
Imports
- archiver
from bpylist2 import archiver
- DataclassArchiver
from bpylist2.archive_types import DataclassArchiver
Quickstart
from bpylist2 import archiver
import io
# An object to archive
my_object = {'foo': 'bar', 'some_array': [1, 2, 3, 4], 'nested': {'key': 'value'}}
# Archive the object into bytes
archived_data = archiver.archive(my_object)
print(f"Archived data (first 50 bytes): {archived_data[:50]}...")
# Unarchive the bytes back into an object
unarchived_object = archiver.unarchive(archived_data)
print(f"Unarchived object: {unarchived_object}")
# Verify round-trip
assert my_object == unarchived_object
print("Archiving and unarchiving successful!")