util.persistence.serialize module

This module represents a Strategy pattern (Gamma et al) class (SerializationStrategy) that serves to serialize and unserialize Python objects with proper support for multiple references to the same object. Thus, if [a, b] where a is b is stored, then when [a, b] is read back, a is b will still be true (although the read-back a will not likely have the same id as the original a).

This module contains the following classes/functions:

class:

SerializationStrategy: The main class programs use to write and read persistent data to files or URLs. It serves both as an abstract superclass to all specific strategies/protocols (eg: XML, JSON) and it’s class methods support easy access to these specific strategies.

class:

Serializable: If you want to store user-defined classes, you must include this abstract class as a superclass. This obligates defining the Serializable.getInstantiationInfo() method.

class:

InstantiationInfo: A data class the is returned by the above method.

class:

ParamInfo and PropertyInfo: A data class that forms part of the information in InstantiationInfo.

class:

strdict: A direct sublclass of dict that restricts keys to str. Many of the serialization protocols use such a structure and you can significantly reduce the size of files by storing dictionary-type data using this class rather than dict whenever you have a dict with string keys.

func:

getInstantiationInfo(): A utility function to retrieve the instantiation information from a Serializable subclass.

SerializationStrategy is an abstract class that supports various storage formats such as XML or JSON through concrete subclasses. Other possibilities are plist, marshal, and pickle. This an application can hold a reference to SerializationStrategy witch could, for example, be either a concrete SerializeXML or SerializeJSON and use the write() and read() methods to write/read data in the relevant data formats.

Object types supported:

  • int

  • float

  • str

  • list

  • tuple

  • set

  • dict

  • strdict: a subclass of dict restricted to str keys.

  • Any properly implemented subclass of Serializable.

Any user-defined class to be stored using SerializationStrategy must inherit from Serializable, which obligates it to override the getInstantiationInfo() method. This method must return a InstantiationInfo object, which has five properties:

cls:

[type] The class of the object

conArgs:

[Optional[list[ParamInfo]]] Information about the each of the positional arguments to the object’s constructor.

conKWArgs:

[Optional[list[ParamInfo]]] Information about the each of the keyword arguments to the object’s constructor.

postconSetters:

[Optional[list[PropertyInfo]]] Information about each of the updates to be done immediately after the constructor is called (other “sibling” objects may not have been created yet).

finalSetters:

[Optional[list[PropertyInfo]]] Information about the each of the updates to be done after ALL of the “sibling” objects have been created.

where ParamInfo and PropertyInfo are data classes defining:

name:

[str] The name of the parameter in the class’s constructor (__init__()).

typ:

[type] The fully qualified class name.

getter:

[getter: Optional[Callable[[Serializable], SerializableType]]=None] A function taking a this object as a parameter and returning a value to be passed to the constructor. If this is None or not given, name will be taken to the a property of this object and will be taken as the value to pass to the constructor.

setter:

(PropertyInfo only) [Optional[Callable[[Serializable, SerializableType], None]]=None] A function taking two arguments: a newly constructed version of this object, and the object produced by getter(). This is applied on restoration of the object either immediately after the constructor or after all objects entailed by the construction of the object are complete. If this is None or not given, name will be taken to the a property of this object that property will be updated with the restored getter() object at the appropriate time.

Programs using concrete SerializationStrategy objects have the following interface (the “public” methods without prefix underscores):

  • writex(): (class method) Looks up a protocol to write an object to a file or URL.

  • readx(): (class method) Looks up a protocol to read an object from a file or URL.

  • tostringx(): (class method) Looks up a protocol to convert an object to a serialized string.

  • fromstringx(): (class method) Looks up a protocol to convert a serialized string to an object.

  • getAvailableStrategies(): (class method) Retrieves basic information about all known available concrete persistent strategies.

  • write(): Writes an object to a file or URL.

  • read(): Reads an object from a file or URL.

  • tostring(): Converts an object to a serialized string.

  • fromstring(): Converts a serialized string to an object.

  • defaultExtension(): Returns the default file extension for the strategy.

  • protocolName(): Returns the name of the concrete strategy.

  • protocoVersion(): Returns the version of the concrete strategy in n.n… form as a string.

  • header: A dict containing header info from the last file, URL, or string read.

  • appName: Apps should set this string to the name of the app at initialization. To be recorded in file headers.

  • appVersion: Apps should set this string to the version of the app at initialization. To be recorded in file headers.

  • version: (read only) The <appVersion>:<serializationVersion>:<protocolVersion> string.

Inheritance diagram of SerializationStrategy, Serializable, InstantiationInfo, ParamInfo, PropertyInfo, strdict


Created on Mar 20, 2026

Code author: Rob Kremer <robkremer@me.com>


util.persistence.serialize.VERSION = '2.0'

The version of this framework (SerializationStrategy): of what’s common to all strategies – eg: a document being a head and one object (see SerializationStrategy.tostring(): since 2.0). (Each strategy has its own version too: see SerializationStrategy.protocolVersion().)

util.persistence.serialize.HEAD = 'head'

A document’s head (see SerializationStrategy.tostring()).

util.persistence.serialize.BODY = 'object'

A document’s object – its body (see SerializationStrategy.tostring()).

util.persistence.serialize.OLD_HEADER = 'header'

The head and object of a document written before VERSION 2.0.

util.persistence.serialize.OLD_ROOT = 'root'

The head and object of a document written before VERSION 2.0.

util.persistence.serialize.HEAD_FORMAT = 'format'

In a head: the strategy that wrote it (see SerializationStrategy.protocolName()).

util.persistence.serialize.HEAD_FORMAT_VERSION = 'formatVersion'

In a head: its version (see SerializationStrategy.protocolVersion()).

util.persistence.serialize.HEAD_SERIALIZATION_VERSION = 'serializationVersion'

In a head: the framework’s version (VERSION).

util.persistence.serialize.HEAD_APPLICATION = 'application'

In a head: the application that wrote it (see SerializationStrategy.appName).

util.persistence.serialize.HEAD_APPLICATION_VERSION = 'applicationVersion'

In a head: its version (see SerializationStrategy.appVersion).

util.persistence.serialize.HEAD_TYPE = 'type'

In a head: the class of the document’s object (its fully qualified name).

util.persistence.serialize.HEAD_SAVED = 'saved'

In a head: when it was written (ISO 8601, with the time zone).

util.persistence.serialize.HeadValue = str | int | float | bool | list | dict

What a head holds: strings, numbers, booleans; lists of those; and tables (dicts with str keys) of those. Nothing else – no None, no objects, no references – so any format can hold it, and anything can read it.

util.persistence.serialize.isHeadValue(value: Any, depth: int = 0) → bool
Parameters:

value (Any)

Returns:

Whether value can be in a head (see HeadValue).

Return type:

bool

class util.persistence.serialize.Serializable

Bases: object

Defines the required protocol (one class method) for any user-defined objects being saved under the framework.

abstractmethod classmethod getInstantiationInfo() → InstantiationInfo
Returns:

A InstantiationInfo structure describing the constructor parameters and how to fill them (conArgs, conKWArgs), and a further description of any additional data to be filled after immediately after the constructor (postconSetters) and more after any contained objects have been fully constructed (finalSetters), both how to write them and read them.

Return type:

util.persistence.serialize.InstantiationInfo

class util.persistence.serialize.strdict(*args, **kwargs)

Bases: dict[str, T], Generic

A simple subclass of dict that restricts the type of keys to type str.

__init__(*args, **kwargs)
Parameters:
  • args

  • kwargs

__setitem__(key, value) → None
Parameters:
  • key

  • value

class util.persistence.serialize.InstantiationInfo(class_: type, conArgs: list[ParamInfo] = <factory>, conKWArgs: list[ParamInfo] = <factory>, postconSetters: list[PropertyInfo] = <factory>, finalSetters: list[PropertyInfo] = <factory>)

Bases: object

The data structure for information for storing and retrieving user-defined persistent objects (Serializable subclasses).

class_: type

The type of the class

conArgs: list[ParamInfo]

An ordered list of ParamInfo structures describing the positional parameters of the constructor.

conKWArgs: list[ParamInfo]

An dict of ParamInfo structures describing the keyword parameters of the constructor.

postconSetters: list[PropertyInfo]

An dict of PropertyInfo structures describing the storing and restoring of object data occurring immediately after the constructor.

finalSetters: list[PropertyInfo]

An dict of PropertyInfo structures describing the storing and restoring of object data occurring after all other objects implied by the object construction have been restored.

property className
Returns:

the fully qualified class name of the described class.

__init__(class_: type, conArgs: list[ParamInfo] = <factory>, conKWArgs: list[ParamInfo] = <factory>, postconSetters: list[PropertyInfo] = <factory>, finalSetters: list[PropertyInfo] = <factory>) → None
util.persistence.serialize.getInstantiationInfo(className: str) → InstantiationInfo
Parameters:

className (str) – The name of a Serializable subclass.

Returns:

the InstantiationInfo structure for className.

Return type:

InstantiationInfo

Raises:

TypeError – if the class cannot be found or

Look up the InstantiationInfo structure for className and return it.

class util.persistence.serialize.ParamInfo(name: str, typ: type | None, getter: Callable[[Serializable], Serializable | int | float | bool | str | list | dict | strdict | tuple | set | None] | None = None, setter: Callable[[Serializable | int | float | bool | str | list | dict | strdict | tuple | set | None], Any] | None = None, unique: bool = False, optional: bool = False, inHead: bool = False)

Bases: object

A data class to describe how to construct an object.

__init__(name: str, typ: type | None, getter: Callable[[Serializable], Serializable | int | float | bool | str | list | dict | strdict | tuple | set | None] | None = None, setter: Callable[[Serializable | int | float | bool | str | list | dict | strdict | tuple | set | None], Any] | None = None, unique: bool = False, optional: bool = False, inHead: bool = False)
Parameters:
  • name (str) – The name of the parameter in the classes constructor (__init__()).

  • typ (type) – The fully qualified class name for the saved type (which could be different from the actual type used in the constructor).

  • getter (Optional[Callable[[Serializable], SerializableType]]=None) – A function taking a this object as a parameter and returning a value to be passed to the constructor. If this is None or not given, name will be taken to the a property of this object and will be taken as the value to pass to the constructor.

  • setter – A function called just before restoring this object that takes the object stored by getter() and returns an object to be applied as the relevant argument in the constructor.

  • unique (bool)

  • optional (bool)

name: str

the name of the parameter

typ: type | None

the type of the parameter

getter: Callable[[Serializable], Serializable | int | float | bool | str | list | dict | strdict | tuple | set | None]

A function taking 1 “self” parameter and returning the run-time value of this parameter.

setter: Callable[[Serializable | int | float | bool | str | list | dict | strdict | tuple | set | None], Any]
unique: bool
optional: bool

Iff True, a file without this parameter still loads: it is left out of the constructor call (so its default applies). For parameters added after files were saved.

inHead: bool

Iff True, when the object is a document’s object (see SerializationStrategy.tostring()), this is written in the document’s head, not with the object – eg: a reference to another document. Its value must be a HeadValue.

class util.persistence.serialize.PropertyInfo(name: str, typ: type, getter: Callable[[Serializable], Serializable | int | float | bool | str | list | dict | strdict | tuple | set | None] | None = None, setter: Callable[[Serializable, Serializable | int | float | bool | str | list | dict | strdict | tuple | set | None], None] | None = None, unique: bool = False, optional: bool = False, omitIfNone: bool = False, inHead: bool = False)

Bases: object

A data class to describe how to construct and restore an object.

__init__(name: str, typ: type, getter: Callable[[Serializable], Serializable | int | float | bool | str | list | dict | strdict | tuple | set | None] | None = None, setter: Callable[[Serializable, Serializable | int | float | bool | str | list | dict | strdict | tuple | set | None], None] | None = None, unique: bool = False, optional: bool = False, omitIfNone: bool = False, inHead: bool = False)
Parameters:
  • name (str) – The name of the property in the class’s definition. You may also use the value “_” in order the just execute the setter function without reference to any property (eg: you want to set a property to a constant after the constructor has completed).

  • typ (type) – The fully qualified class name for the saved type (which could be different from the actual type in the object).

  • getter (Optional[Callable[[Serializable], SerializableType]]=None) – A function taking a this object as a parameter and returning a value to be passed to the constructor. If this is None or not given, name will be taken to the a property of this object and will be taken as the value to pass to the constructor.

  • setter (Optional[Callable[[Serializable, SerializableType], None]]=None) – A function taking two arguments: a newly constructed version of this object, and the object saved by getter(). This is applied on restoration of the object either immediately after the constructor or after all objects entailed by the construction of the object are complete. If this is None or not given, name will be taken to the a property of this object that property will be updated with the restored getter() object at the appropriate time.

  • unique (bool)

  • optional (bool) – Whether it may be missing from a file (eg: one written before the property existed): the setter is then not called.

  • omitIfNone (bool) – Whether to leave it out of the file when its value is None – eg: a property that’s almost always None, so as not to fill every file with it. (It’s then optional too.)

name: str

the name of the parameter

typ: type | None

the type of the parameter

getter: Callable[[Serializable], Serializable | int | float | bool | str | list | dict | strdict | tuple | set | None]

A function taking 1 “self” parameter and returning the run-time value of this parameter.

setter: Callable[[Serializable, Serializable | int | float | bool | str | list | dict | strdict | tuple | set | None], None]
unique: bool
optional: bool
omitIfNone: bool

Whether it’s left out of the file when its value is None (see __init__()).

inHead: bool

Whether it’s written in the document’s head (see ParamInfo.inHead).

util.persistence.serialize.DEFAULT_STRATEGY = 'XML3'

The name of the strategy things are saved with unless told otherwise (see util.persistence.serializeXML2).

class util.persistence.serialize.SerializationStrategy

Bases: ABC, Generic

A Strategy pattern class designed to save objects in a manner that allows for multiple storage formats (eg: XML, JSON, etc). This class proposes to support build-in data types: int, float, bool, str, list, dict, tuple, set, as well as any (properly constructed) user-defined subclass of Serializable.

For subclass (concrete protocol) developers:

The T generic type is the artifact type used by the concrete protocol (subclass). For example, for XML implemented with etree package, it’s Element and for JSON implemented with the json package, it’s Union[dict, list, int, float, bool, str].

Subclasses (defining specific strategies) must override (minimally) the following abstract methods:

Subclasses may override the following concrete methods (by default they are implmented in terms of the methods above):

Subclasses should NOT override the following methods as they encapsulate all the housekeeping involved in keeping track of object pointers. However, subclasses should USE these methods (rather than the _encode*() and _decode*() methods above when storing objects for that same reason:

class Strategy(name: str, extension: str, cls: type)

Bases: NamedTuple

A serialization strategy’s name, file extension and class.

name: str

Alias for field number 0

extension: str

Alias for field number 1

cls: type

Alias for field number 2

_asdict()

Return a new dict which maps field names to their values.

_field_defaults = {}
_fields = ('name', 'extension', 'cls')
classmethod _make(iterable)

Make a new Strategy object from a sequence or iterable

_replace(**kwds)

Return a new Strategy object replacing specified fields with new values

class _MemStrategy(name: str, extension: str, cls: type, obj: SerializationStrategy)

Bases: object

A known serialization strategy (see knownStrategies), with its instance.

name: str
extension: str
cls: type
obj: SerializationStrategy
__init__(name: str, extension: str, cls: type, obj: SerializationStrategy) → None
knownStrategies: list[_MemStrategy] = [SerializationStrategy._MemStrategy(name='XML3', extension='.xml', cls=<class 'util.persistence.serializeXML3.XML3SerializationStrategy'>, obj=<util.persistence.serializeXML3.XML3SerializationStrategy object>), SerializationStrategy._MemStrategy(name='XML2', extension='.xml', cls=<class 'util.persistence.serializeXML2.XML2SerializationStrategy'>, obj=<util.persistence.serializeXML2.XML2SerializationStrategy object>), SerializationStrategy._MemStrategy(name='XML', extension='.xml', cls=<class 'util.persistence.serializeXML.XMLSerializationStrategy'>, obj=<util.persistence.serializeXML.XMLSerializationStrategy object>), SerializationStrategy._MemStrategy(name='Plist', extension='.plist', cls=<class 'util.persistence.serializePlist.PlistSerializationStrategy'>, obj=<util.persistence.serializePlist.PlistSerializationStrategy object>), SerializationStrategy._MemStrategy(name='JSON', extension='.json', cls=<class 'util.persistence.serializeJSON.JSONSerializationStrategy'>, obj=<util.persistence.serializeJSON.JSONSerializationStrategy object>)]

The list of known persistent strategies. Populated incrementally as strategies are constructed (see __init__() below) – but also, as of module load time, pre-populated with every concrete strategy findable in this package (util.persistence), even ones nothing has imported yet. See _populateKnownStrategiesAtLoad() at the bottom of this module.

__init__()

Create an object from a byte array.

_finalMethodsList: list[Callable]
header: dict[str, Any]

The header information from the last file, url, or string read.

classmethod getAvailableStrategies(packages: Iterable[str] = [], filtr: Callable[[str], bool] | None = None, asString: bool = False) → list[Strategy] | str
Parameters:
  • packages (Iterable[str]) – A list of package names to scan for concrete strategy classes to be loaded.

  • filtr (Optional[Callable[[str], bool]]=None) – If given, the module will only be loaded if filter() called with a scanned module name returns True. All scanned modules who’s name starts with “serialize” will be loaded as well.

  • asString (bool (default: False)) – if True, return a user-readable string listing the names and extensions.

Returns:

A tuple [strategy-name. default-file-extension, strategy-class].

Return type:

list[tuple[str, str, type]]

Returns a list of name/class/extension 3-tuples of available strategies. That is, all the concrete subtypes of this abstract class.

preferred: bool = False

If True, this strategy is chosen when a file extension is matched by more than one strategy (see findStrategy()) – eg: one that can read what the others write.

appName = '/Library/Frameworks/Python.framework/Versions/3.14/bin/sphinx-build'

The name of the Application – should be reassigned by the application at startup.

appVersion = 'Unknown'

The version of the Application – should be reassigned by the application at startup.

property serializationStrategyVersion
Returns:

The version string of this class.

Note

This is different from the protocolVersion() method that returns the version string of the actual concrete strategy.

property version
Returns:

Return type:

classmethod _byPreference() → list[Strategy]

The available strategies (see getAvailableStrategies()), preferred ones first.

Returns:

Return type:

list[SerializationStrategy.Strategy]

classmethod findStrategy(strategy: str) → SerializationStrategy
Parameters:

strategy (str)

Returns:

Return type:

SerializationStrategy

classmethod tostringx(strategy: str, obj: Serializable | int | float | bool | str | list | dict | strdict | tuple | set | None, *, wrap: bool | dict = False, assume: list[Any] = [], **kwargs) → str

Return the data in obj as a strategy-specific formatted string. the

Parameters:
  • strategy (str) – The name or extension (starting with a dot) of some protocol-specific strategy (a concrete subclass of this class) to use to encode obj. If strategy is an extension and there is more than one strategy with that extension, the last matching one used will be selected, of if this is the first one, the selection is unspecified.

  • obj (SerializableType) – The object to serialise and returned.

  • wrap (Union[bool,dict[) – If wrap is False there is not wrapping, if True or a dict a dictionary is created containing keys “header” (which is mapped to wrap if it’s a dict or a default header if it’s True) and “root” (which maps to (obj). The *fromstring() method will automatically unwrap and save the header info (if it’s there) as the property self.header:dict.

  • assume (list[Any])

  • kwargs

Returns:

The serialized object as a string.

Return type:

str

classmethod fromstringx(strategy: str, string: str, **kwargs) → Serializable | int | float | bool | str | list | dict | strdict | tuple | set | None

Return an object made from a strategy-specific formatted string.

Parameters:
  • strategy – The name or extension (starting with a dot) of some protocol-specific strategy (a concrete subclass of this class) to use to encode obj. If strategy is an extension and there is more than one strategy with that extension, the last matching one used will be selected, of if this is the first one, the selection is unspecified.

  • string (str) – The string to interpret.

  • kwargs (dict[str, Any]) – A set of keyword arguments to be passed to concrete subclass.

Returns:

The object interpreted from string.

Return type:

SerializableType

classmethod writex(url: str, obj: Serializable | int | float | bool | str | list | dict | strdict | tuple | set | None, strategy: str | None = None, replaceExt: bool | None = True, wrap: bool | dict = True, **kwargs) → None

Write an the data to a URL.

For file: URLs the data is written directly to the local filesystem path. For all other schemes (e.g. http:, https:) the XML is uploaded via urllib.request.urlopen() as an HTTP PUT request with content-type application/xml.

Parameters:
  • url (str) – The destination URL. Use file:///absolute/path or file://relative/path for local files.

  • obj (SerializableType) – The object to serialise and write.

  • strategy (Optional[str]) – (default=None) The name or extension (starting with a dot) of some protocol-specific strategy (a concrete subclass of this class) to use to encode obj. If strategy is an extension and there is more than one strategy with that extension, the last matching one used will be selected, of if this is the first one, the selection is unspecified. If strategy is missing or None, the strategy will be inferred from the extension in url as though it had been given in the strategy parameter.

  • replaceExt (Optional[bool]) – If True, (the default) any extension will be replace with the default extension; if False, the default will extension will be appended to the path if it’s not already there; if None, nothing will be done to the path.

  • kwargs (dict[str, Any]) – A set of keyword arguments to be passed to concrete subclass.

Returns:

None

Return type:

None

Raises:
  • ValueError – If url is an empty string.

  • FileNotFoundError – If the parent directory of a file: URL path does not exist.

  • urllib.error.URLError – If a remote URL cannot be reached.

Usage:

>>> tree = ET.parse("data.xml")
>>> write("file:///tmp/output.xml", tree)
>>> write("https://example.com/api/document", tree)
Parameters:

wrap (Union[bool, dict])

classmethod readx(url: str, strategy: str | None = None, replaceExt: bool | None = True, mode='w', **kwargs) → Serializable | int | float | bool | str | list | dict | strdict | tuple | set | None
Parameters:
  • url (str) – The destination URL. Use file:///absolute/path or file://relative/path for local files.

  • strategy (Optional[str]) – (default=None) The name or extension (starting with a dot) of some protocol-specific strategy (a concrete subclass of this class) to use to encode obj. If strategy is an extension matched by more than one strategy, the preferred one (see preferred) is used. If strategy is missing or None, each strategy is tried in turn until one succeeds: those for url’s extension first (preferred ones first), then the rest (see _tryInOrder()).

  • kwargs (dict[str, Any]) – A set of keyword arguments to be passed to concrete subclass.

Returns:

An object read from url

Return type:

SerializableType

Raises:

NotImlementedError – If the subclass failed to implement one of its required methods.

Converts a byte array to an object using _decode_() and _speicializeBytes().

Parameters:
  • replaceExt (bool | None)

  • mode (str)

classmethod _tryInOrder(url: str, caller: str, action: Callable[[SerializationStrategy], R]) → R

Try action with each available strategy in turn until one succeeds: those for url’s file extension first (preferred ones first: see preferred), then the rest – eg: a “.xml” file written by one of several XML strategies, or a file whose extension isn’t any strategy’s.

Raises:
  • OSError – At once, if url can’t be opened (eg: it doesn’t exist): no other strategy would do better.

  • LookupError – If every strategy fails; the message says why each did.

Parameters:
Returns:

Return type:

R

classmethod _start(url: str) → bytes
Returns:

The start of the file at url (see SNIFF_SIZE), if it’s on this computer; else b”” (it isn’t fetched just for this).

classmethod peekTypex(url: str, strategy: str | None = None, mode: str = 'w', **kwargs) → type
Parameters:
  • url (str) – The URL to inspect. Use file:///absolute/path or file://relative/path for local files.

  • strategy (Optional[str]) – (default=None) The name or extension (starting with a dot) of some protocol-specific strategy to use. If missing or None, the strategy is inferred from url’s extension – falling back to trying every known strategy in turn, exactly as readx() does – since a URL using a domain-specific extension (e.g. “.snv”) won’t match any registered strategy’s own extension.

  • kwargs (dict[str, Any]) – A set of keyword arguments to be passed to _fromstring().

Returns:

The class of the top-level object stored at url.

Return type:

type

Raises:

LookupError – If no strategy matches (or, when none is named, if every known strategy fails to peek at url).

Classmethod counterpart to readx(): resolves which strategy to use the same way, but calls peekType() instead of read() – returning the top-level object’s class WITHOUT constructing it (or anything it contains).

Parameters:

mode (str)

abstractmethod classmethod defaultExtension() → str
Returns:

Return type:

str

abstractmethod classmethod protocolName() → str
Returns:

Return type:

str

abstractmethod classmethod protocolVersion() → str
Returns:

Return type:

str

write(url: str, obj: Serializable | int | float | bool | str | list | dict | strdict | tuple | set | None, replaceExt: bool | None = True, wrap: bool | dict = True, **kwargs) → None

Write an the data to a URL.

For file: URLs the data is written directly to the local filesystem path. For all other schemes (e.g. http:, https:) the XML is uploaded via urllib.request.urlopen() as an HTTP PUT request with content-type application/xml.

Parameters:
  • url (str) – The destination URL. Use file:///absolute/path or file://relative/path for local files.

  • obj (SerializableType) – The object to serialise and write.

  • replaceExt (Optional[bool]) – If True, (the default) any extension will be replace with the default extension; if False, the default will extension will be appended to the path if it’s not already there; if None, nothing will be done to the path.

  • kwargs (dict[str, Any]) – A set of keyword arguments to be passed to concrete subclass.

Returns:

None

Return type:

None

Raises:
  • ValueError – If url is an empty string.

  • FileNotFoundError – If the parent directory of a file: URL path does not exist.

  • urllib.error.URLError – If a remote URL cannot be reached.

Usage:

>>> tree = ET.parse("data.xml")
>>> write("file:///tmp/output.xml", tree)
>>> write("https://example.com/api/document", tree)
Parameters:

wrap (Union[bool, dict])

read(url: str, replaceExt: bool | None = True, mode='w', **kwargs) → Serializable | int | float | bool | str | list | dict | strdict | tuple | set | None
Parameters:
  • url (str) – The source URL. Use file:///absolute/path or file://relative/path for local files.

  • replaceExt (Optional[bool]) – If True, (the default) any extension will be replace with the default extension; if False, the default extension will be appended to the path if it’s not already there; if None, nothing will be done to the path.

  • kwargs (dict[str, Any]) – A set of keyword arguments to be passed to concrete subclass.

Returns:

An object read from buf

Return type:

Any

Raises:

NotImlementedError – If the subclass failed to implement one of its required methods.

Converts a byte array to an object using _decode_() and _speicializeBytes().

Parameters:

mode (str)

_fetchContents(url: str, parsedUrl: ParseResult) → str
Parameters:
  • url (str) – A URL already normalized by fixURL().

  • parsedUrl (ParseResult) – Its parsed form, as returned alongside it by fixURL().

Returns:

The raw text found at url.

Return type:

str

Raises:
  • ValueError – If the URL’s scheme isn’t “file”, “http”, or “https”.

  • FileNotFoundError – If there’s nothing there (eg: an HTTP 404): no strategy would do better (see _tryInOrder()).

Shared by read() and peekType(): fetches the raw text a URL points to, with no interpretation of its content at all – not even far enough to know what strategy it’s meant for.

peekType(url: str, mode: str = 'w', **kwargs) → type
Parameters:
  • url (str) – The source URL to inspect.

  • mode (str) – Passed through to fixURL() exactly as read() does.

  • kwargs (dict[str, Any]) – Passed through to _fromstring().

Returns:

The class of the top-level (“root”) object stored at url.

Return type:

type

Raises:
  • TypeError – If the declared type name can’t be resolved to an actual class.

  • ValueError – If the URL’s scheme isn’t “file”, “http”, or “https”.

Learns what’s stored at url WITHOUT constructing it – or anything it contains: parses just far enough to read the top-level object’s declared “type” attribute, using exactly the same structural primitives (_fromstring(), _getKVPair(), _getAttr()) that _decode_() itself uses for that same lookup; it simply stops there instead of going on to call any constructor. _fromstring() returns a lightweight strategy-specific representation of the parsed document (an ElementTree.Element for XML, a plain dict for JSON) – turning bytes into that shape, not into Serializable objects, so nothing in this method has any side effect on the object graph the document describes.

This exists so callers who only need to know what a file is (e.g. Application.openWindow(), which must tell a Model file from a SNGView file before deciding what to do) don’t have to fully read – and thereby construct and register – the object just to find out.

Important

This default implementation is only correct for a strategy whose _fromstring() returns a representation that doesn’t itself construct any Serializable object – true of XMLSerializationStrategy and JSONSerializationStrategy, both of which only ever produce an inert data structure at the _fromstring() stage. A strategy for which parsing and object construction are inherently fused – e.g. one based on Python’s pickle protocol, where finding a class name ordinarily means unpickling – MUST override this method with its own cheap, format-specific technique (for pickle, overriding Unpickler.find_class() to record the class and raise before any GLOBAL/REDUCE opcode actually builds anything is the standard trick). Inheriting this default for such a strategy would silently make peekType() just as expensive, and just as side-effecting, as a full read() – defeating its purpose.

peekString(url: str, section: str, key: str, mode: str = 'w', **kwargs) → str | None
Returns:

The value of string property key of the section (“header” or “root”) of the document at url – eg: (“root”, “url”) for a stored PRDb’s URL – or None if there isn’t one (or it isn’t a string). Like peekType(), nothing in the document is constructed.

Parameters:
  • url (str)

  • section (str)

  • key (str)

  • mode (str)

  • kwargs

classmethod peekStringx(url: str, section: str, key: str, mode: str = 'w', **kwargs) → str | None

Like peekString(), choosing the strategy as readx() does.

Parameters:
  • url (str)

  • section (str)

  • key (str)

  • mode (str)

  • kwargs

Returns:

Return type:

Optional[str]

tostring(obj: Serializable | int | float | bool | str | list | dict | strdict | tuple | set | None, *, wrap: bool | dict = False, assume: list[Any] = [], **kwargs) → str

Return the data as a strategy-specific formatted string.

Parameters:
  • obj (SerializableType) – The object to serialise and returned.

  • wrap (Union[bool,dict]) – If False, just obj is written. Otherwise it’s written as a document: a head, then obj (the document’s object). The head is a table of plain values (see HeadValue) – the format, the versions, the application, obj’s class, when it was written (see makeHead()); what obj adds (its serializationHeader(), if it has one); its parameters and properties marked inHead (see ParamInfo.inHead), which aren’t written with it; and wrap’s, if it’s a dict. It’s written first, so it can be read without reading the rest (see readHead()). The strategy decides how (see _tostringDocument()).

  • assume (list[Any])

  • kwargs

Returns:

The serialized object as a string.

Return type:

str

makeHead(obj: Serializable | int | float | bool | str | list | dict | strdict | tuple | set | None) → dict[str, str | int | float | bool | list | dict]
Parameters:

obj (SerializableType) – A document’s object (see tostring()).

Returns:

Its document’s head: the format and the versions, the application, obj’s class, the time; and what obj adds (its serializationHeader(), if it has one).

Return type:

dict[str, HeadValue]

_tostringDocument(head: dict[str, HeadValue], body: T, kwargs: dict[str, Any]) → str

Write a document (see tostring()). By default, as a table of two entries, head first: HEAD (a table of the head’s values) and BODY. A strategy may write it its own way (eg: two values one after another; see XML3SerializationStrategy), so long as _fromstringDocument() reads it, and the head comes first.

Parameters:
  • head (dict[str, HeadValue])

  • body (T) – The document’s object, encoded.

  • kwargs (dict[str, Any])

Returns:

Return type:

str

_fromstringDocument(string: str, kwargs: dict[str, Any]) → tuple[dict[str, HeadValue], T]

Read a document (see tostring(), _tostringDocument()) – or an old one (OLD_HEADER, OLD_ROOT), or just an object (an empty head, then).

Parameters:
  • string (str)

  • kwargs (dict[str, Any])

Returns:

Its head, and its object (still encoded).

Return type:

tuple[dict[str, HeadValue], T]

_documentParts(top: T) → tuple[dict[str, HeadValue], T]
Parameters:

top (T) – The top of a document read with _fromstring().

Returns:

Its head, and its object (still encoded): see _fromstringDocument().

Return type:

tuple[dict[str, HeadValue], T]

fromstring(string: str, **kwargs) → Serializable | int | float | bool | str | list | dict | strdict | tuple | set | None

Return an object made from a strategy-specific formatted string: a document’s object, if it’s a document (see tostring()) – its head is then header.

Parameters:
  • string (str) – The string to interpret.

  • kwargs (dict[str, Any]) – A set of keyword arguments to be passed to concrete subclass.

Returns:

The object interpreted from string.

Return type:

SerializableType

readHead(url: str, mode: str = '', **kwargs) → dict[str, str | int | float | bool | list | dict]
Parameters:
  • url (str) – Where a document is.

  • mode (str) – As for fixURL().

Returns:

Its head (see tostring()) – for an old document, its header, and its object’s class (HEAD_TYPE). By default, the whole document is read (but no object in it is made); a strategy that can read just the start of it does (see XML3SerializationStrategy).

Return type:

dict[str, HeadValue]

classmethod readHeadx(url: str, mode: str = '', **kwargs) → dict[str, str | int | float | bool | list | dict]

Like readHead(), choosing the strategy as readx() does.

Parameters:
  • url (str)

  • mode (str)

Returns:

Return type:

dict[str, HeadValue]

_abc_impl = <_abc._abc_data object>
SNIFF_SIZE: ClassVar[int] = 2048

How much of the start of a file is looked at to tell its format (see sniff()).

classmethod sniff(start: bytes) → int
Parameters:

start (bytes) – The start of a file (see SNIFF_SIZE).

Returns:

How sure this strategy is that it wrote it: 0 (not at all, or can’t tell) up – eg: 1 for the right kind of file (XML), 2 for one in its own format. Strategies that are surer are tried first (see _tryInOrder()).

Return type:

int

abstractmethod _tostring(obj: T, kwargs: dict[str, Any]) → str
Parameters:
  • obj (SerializableType) – The object to be serialized.

  • kwargs (dict[str, Any]) – A set of keyword arguments to be passed to concrete subclass. This is passed as dict rather than with the ** syntax so that concrete subclasses can ignore unexpected arguments gracefully (as they should).

Returns:

The serialized object as a string.

Return type:

str

Return the data as a strategy-specific formatted string. Called by tostring().

abstractmethod _fromstring(string: str, kwargs: dict[str, Any]) → T

Return an object made from a strategy-specific formatted string. Called by fromstring().

Parameters:
  • string (str) – The string to interpret.

  • kwargs (dict[str, Any]) – A set of keyword arguments to be passed to concrete subclass. This is passed as dict rather than with the ** syntax so that concrete subclasses can ignore unexpected arguments gracefully (as they should).

Returns:

The object interpreted from string.

Return type:

SerializableType

abstractmethod _encodeStr(obj: str) → T
Parameters:

obj (str)

Returns:

Return type:

T

abstractmethod _decodeStr(readerObj: T) → str
Parameters:

readerObj (T)

Returns:

Return type:

str

abstractmethod _encodeList() → T
Returns:

Return type:

T

abstractmethod _decodeList(readerObj: T) → list[T]
Parameters:

readerObj (T)

Returns:

Return type:

list[T]

abstractmethod _setAttr(elem: T, name: str, value: str) → None

Contract: _setAttr(elem, name, value) -> _getAttr(elem, naem) == value

This method must be implemented if any of _encodeInt(), _encodeFloat(), _encodeBool(), _encodeTuple(), _encodeSet(), or _encodeSerializable() are left the default implementations in this class.

May be called for ANY type.

Parameters:
  • elem (T)

  • name (str)

  • value (str)

abstractmethod _getAttr(elem: T, name: str, default: Any = <class 'KeyError'>) → Any

Contract: _setAttr(elem, name, value) -> _getAttr(elem, naem) == value

This method must be implemented if any of _decodeInt(), _decodeFloat(), _decodeBool(), _decodeTuple(), _decodeSet(), or _decodeSerializable() are left the default implementations in this class.

May be called for ANY type.

Parameters:
  • elem (T)

  • name (str)

  • default (Any)

Returns:

Return type:

Any

abstractmethod _appendItem(elem: T, newItem: T) → None

May be called for list, tuple, and set types only.

Parameters:
  • elem (T)

  • newItem (T)

abstractmethod _getItems(elem: T) → list[T]

May be called for list, tuple, and set types only.

Parameters:

elem (T)

Returns:

Return type:

list[T]

abstractmethod _setKVPair(elem: T, key: T | str, value: T) → None
Parameters:
  • elem (T) – The T object to add the key/value pair to. Must be a *dict type, strdict type, or a subtype of Serializable representation.

  • key (T|str) – The key part, not that if elem is a regular dict representation, key must be a T type; but if elem is a strdict or subtype of Serializable, key must be a str.

  • value (T) – The value part.

May be called for dict types, strdict types, and Serializable subtypes only.

abstractmethod _getKVPairs(elem: T) → list[tuple[T, T]] | dict[str, T]
Parameters:

elem (T) – The T object to deserialize to a key/value pair. Must be a *dict type, strdict type, or a subtype of Serializable representation.

Returns:

If elem represents a dict object, then the return must be a tuple; if elem represents a strdict or a subtype of Serializable, then the return must be a dict.

Return type:

list[tuple[T,T]]|dict[str,T]

May be called for dict types, strdict types, and Serializable subtypes only.

_getKVPair(elem: T, key: str) → T | None

May be called for strdict types Serializable subtypes only.

Parameters:
  • elem (T)

  • key (str)

Returns:

Return type:

Optional[T]

_encodeInt(obj: int) → T
Parameters:

obj (int)

Returns:

Return type:

T

_decodeInt(elem: T) → int
Parameters:

elem (T)

Returns:

Return type:

int

_encodeNone() → T
Returns:

Return type:

T

_decodeNone(elem: T) → None
Parameters:

elem (T)

_encodeFloat(obj: float) → T
Parameters:

obj (float)

Returns:

Return type:

T

_decodeFloat(elem: T) → float
Parameters:

elem (T)

Returns:

Return type:

float

_encodeBool(obj: bool) → T
Parameters:

obj (bool)

Returns:

Return type:

T

_decodeBool(elem: T) → bool
Parameters:

elem (T)

Returns:

Return type:

bool

_encodeTuple() → T
Returns:

Return type:

T

_decodeTuple(elem: T) → tuple[T, ...]
Parameters:

elem (T)

Returns:

Return type:

tuple[T, …]

_encodeSet() → T
Returns:

Return type:

T

_decodeSet(elem: T) → set[T]
Parameters:

elem (T)

Returns:

Return type:

set[T]

_encodeDict() → T
Returns:

Return type:

T

_decodeDict(elem: T) → list[tuple[T, T]]
Parameters:

elem (T)

Returns:

Return type:

list[tuple[T, T]]

_encodeStrdict() → T
Returns:

Return type:

T

_decodeStrdict(elem: T) → dict[str, T]
Parameters:

elem (T)

Returns:

Return type:

dict[str, T]

_encodeSerializable() → T
Returns:

Return type:

T

_decodeSerializable(elem: T) → dict[str, T]
Parameters:

elem (T)

Returns:

Return type:

dict[str, T]

_encode_(obj: SerializableType, unique: bool = False) → T
..note:

Tuple members referencing the tuple are NOT supported.

Parameters:
  • obj (SerializableType)

  • unique (bool)

Returns:

Return type:

T

_decode_(elem: T) → SerializableType
Parameters:

elem (T)

Returns:

Return type:

SerializableType

class util.persistence.serialize._Reference(referenceID: int)

Bases: Serializable

A reference to an object already written, by its id: how an object referred to more than once is written only once.

__init__(referenceID: int) → None
Parameters:

referenceID (int)

referenceID: int
classmethod getInstantiationInfo() → InstantiationInfo
Returns:

A InstantiationInfo structure describing the constructor parameters and how to fill them (conArgs, conKWArgs), and a further description of any additional data to be filled after immediately after the constructor (postconSetters) and more after any contained objects have been fully constructed (finalSetters), both how to write them and read them.

Return type:

util.persistence.serialize.InstantiationInfo