Changelog¶
1.0.0 (unreleased)¶
Version 1.0 adds a C implementation of every type, makes the types behave more like the builtins, and redesigns lazy values. Some of these changes are not backward compatible; they are marked (breaking).
Implementation¶
The types are implemented in C. The pure-Python implementation remains as a fallback, and both are tested against the same test suite.
If the C extension can’t be loaded, importing
pcollectionsissues aRuntimeWarning.pcollections.using_c_extensionsays which implementation is in use andpcollections.backend_errorsays why the C extension couldn’t be loaded. The environment variablesPCOLLECTIONS_NO_C_EXTENSIONSandPCOLLECTIONS_REQUIRE_Cchoose the implementation.pcollectionsno longer depends onphamt, or on any other package.Objects pickled with one implementation can be unpickled with the other.
Type stubs are included.
Python 3.8 through 3.15 are supported, including the free-threaded builds of 3.13 and later. Python 3.7 is no longer supported. (breaking)
Setting
PCOLLECTIONS_REQUIRE_C=1when buildingpcollectionsmakes the build fail if the C extension doesn’t compile.On Python 3.8, only the first interpreter in a process that imports
pcollectionsgets the C backend; other interpreters use the Python backend.
Deprecated¶
Support for Python 3.8 is deprecated, and will be removed in a future minor release (1.1 or 1.2, for example).
Transient collections¶
A modification of a transient collection that overlaps another modification of the same collection (from another thread, or from a key’s
__eq__or__hash__) raisesRuntimeErrorinstead of corrupting the collection. So does a read (a lookup or a step of an iteration) made while a modification is in progress.Changing the keys of a
tdictortsetwhile iterating over it raisesRuntimeError, as it does fordictandset. Iterating over atlistwhile changing it behaves as it does forlist.tlistsupports slice assignment and deletion (t[1:3] = ...,del t[::2]).tlist += iterableaccepts any iterable.Transient collections are unhashable. (breaking)
Persistent collections¶
drop(key, error=False)is available onpdict,pset, andplist. It returns the collection unchanged when the key or index isn’t present, or, iferroris true, raisesKeyError(orIndexError).delete(key)always raises.
Subclasses¶
All types can be subclassed, and methods that return a new collection return an instance of the subclass.
The class attributes
__transient_type__and__persistent_type__name a class’s partner type, used bytransient()andpersistent().
Lazy values¶
A read from a lazy collection computes the lazy values it returns; lazy values in any other collection are ordinary objects. Converting a lazy collection to another collection computes its values. (breaking)
A lazy value is computed at most once, even when several threads request it at the same time.
A failed computation is remembered: every later request raises a new
LazyErrorwhose__cause__is the original exception and whose message says where thelazywas created.LazyErrorhas the attributesfunc,func_args,func_kwargs,origin,origin_stack,cause, androot_cause. (breaking)lazy.trace = True, or the environment variablePCOLLECTIONS_LAZY_TRACE=1, records the stack where eachlazyis created.A lazy value that fails because a lazy value it depends on failed raises a
LazyErrorthat names the dependency and the original exception; its cause is the dependency’sLazyError.LazyError.root_causeis the exception that started the failure.lazy_error_unwrapreturns the root cause of aLazyError, and, as a context manager, re-raises the root cause in place of theLazyError.A lazy value whose computation requests its own value raises
LazyError.lazycan be subclassed, and a subclass’s__call__is used by the lazy collections and byunlazy.Pickling a
lazycomputes it and pickles its value.ldict.as_pdict,llist.as_plist, andtldict.as_tdictare renamedheld_pdict,held_plist, andheld_tdict, andtllist.held_tlistis new. (breaking)holdlazy(coll)returns a lazy collection as the equivalent plain collection, with its lazy values uncomputed.
0.4.0¶
Added
lazy_error_unwrap.pdict(ld)computes the lazy values of theldictld, andldict(d)keeps lazy values uncomputed for subclasses ofldict.tllistandtldictare exported frompcollections, andtldicthas the lazy-value methods ofldict.