Source code for ocebuild.third_party.cpython.plistlib

#pragma preserve-exports

## @file
# Copyright (c) 2023, Cory Bennett. All rights reserved.
# SPDX-License-Identifier: BSD-3-Clause
##
"""Overrides the `plistlib` module to support backports and custom subclasses."""

import plistlib
from plistlib import InvalidFileException, FMT_BINARY, FMT_XML
from plistlib import dump, dumps, load, loads
from plistlib import PlistFormat, _FORMATS

from binascii import b2a_base64

from .. import inject_module_namespace


[docs]class UID(plistlib.UID): """A `plistlib.UID` subclass that enforces a 32-bit limit on the UID value. Apple handles UIDs assuming 32-bit unsigned integers: - [CF/CFBinaryPList.c#L138-L146](https://github.com/apple-oss-distributions/CF/blob/dc54c6bb1c1e5e0b9486c1d26dd5bef110b20bf3/CFBinaryPList.c#L138-L146) - [CF/CFPropertyList.c#L1538-L1547](https://github.com/apple-oss-distributions/CF/blob/dc54c6bb1c1e5e0b9486c1d26dd5bef110b20bf3/CFPropertyList.c#L1538-L1547) The original `plistlib.UID` class does not enforce this limit, so we must override the constructor to ensure the value is within the 32-bit limit. """ def __init__(self, data): # Ensure MRO is cooperative with subclassing super(UID, self).__init__(data) # Hook into the `plistlib.UID` constructor super(plistlib.UID, self).__init__() # Enforce a 32-bit limit to the UID value if data >= 1 << 32: raise ValueError("UIDs cannot be >= 2**32")
#TODO: Implement _BinaryPlistWriter fixes class _PlistWriter(plistlib._PlistWriter): def write_bytes(self, data): """Writes a base64-encoded data element to a plist file.""" # Calculate the maximum line length (from the original _PlistWriter writer) indent = self.indent.replace(b"\t", b" " * 8) maxlinelength = max(16, 76 - len(indent * (self._indent_level - 1))) # Calculate the number of newlines required (from _encode_base64 binning) maxbinsize = (maxlinelength//4)*3 num_newlines = len(data) / maxbinsize # Write the data as a single-line base64 string if no newlines are needed if num_newlines < 1: base64_data = b2a_base64(data, newline=False) self.simple_element("data", base64_data.decode('utf-8')) # Otherwise write the data as a multi-line base64 string else: super().write_bytes(data) # Override the `plistlib` module's writer class _FORMATS[FMT_XML]['writer'] = _PlistWriter # Inject the `plistlib` namespace into the current module inject_module_namespace(plistlib, namespace=globals()) __all__ = [ "InvalidFileException", "FMT_XML", "FMT_BINARY", "load", "dump", "loads", "dumps", "UID" ]