stratified_packager.toolbelt.mapping_proxy

QGIS-free foundation for the typed key/value proxies: conversions, mapping base, environment.

This module holds the parts of the persistence layer that touch no QGIS objects, so it is importable (and thread-safe) without a QGIS runtime:

The conversion registry here covers the stdlib types (str, int, float, bool, list[str], pathlib.Path, datetime.datetime, datetime.date) and any enum.Enum. QGIS-only types (e.g. QColor) are registered by the modules that own them — see settings, which also adds the QGIS-backed proxies (QgsSettings, QgsProject, layer properties) on top of this base.

Dict-like and typed-descriptor access mirror how a typed entry sits over a flat store:

env = EnvironmentVariables()
env["MY_FLAG"] = True  # stored as the string "True"
env.get("MY_PORT", 5678, cast=int)  # -> int, with a default


class DebugEnv(EnvironmentVariables):
    QGIS_DEBUGPY = BoolEnvVar(default=False)
    QGIS_DEBUGPY_PORT = IntEnvVar(default=5678)


DebugEnv().QGIS_DEBUGPY  # -> bool

Module Attributes

StorableValue

Union of representations every backend can persist natively.

Functions

from_storage(raw, target_type)

Rebuild a value of target_type from a stored representation.

register_converter(py_type, serialize, ...)

Register conversion callables for py_type, replacing any existing entry.

to_storage(value)

Convert a Python value into a representation a QGIS backend can persist.

Classes

BoolEnvVar(*, default[, description, key])

A bool environment variable, parsed via the converter registry.

EnvVar(cast, default[, description, key])

Descriptor mapping a class attribute to a typed environment variable.

EnvironmentVariables([environ])

Dict-like proxy over the process environment (os.environ).

FloatEnvVar(*, default[, description, key])

A float environment variable.

IntEnvVar(*, default[, description, key])

An int environment variable.

MappingProxy()

Common MutableMapping plumbing for the proxies.

PathEnvVar(*, default[, description, key])

A Path environment variable.

StrEnvVar(*, default[, description, key])

A str environment variable.

TypeConverter(serialize, deserialize)

Round-trips a single Python type to and from a backend-storable representation.

class stratified_packager.toolbelt.mapping_proxy.BoolEnvVar(*, default, description='', key=None)[source]

A bool environment variable, parsed via the converter registry.

Parameters:
__init__(*, default, description='', key=None)[source]

Initialize the descriptor.

Parameters:
  • default (bool) – Value returned when the variable is unset.

  • description (str) – Human-readable description (documentation only).

  • key (str | None) – Variable name; defaults to the attribute name.

class stratified_packager.toolbelt.mapping_proxy.EnvVar(cast, default, description='', *, key=None)[source]

Descriptor mapping a class attribute to a typed environment variable.

Declare instances as class attributes of an EnvironmentVariables subclass; the attribute name is used as the variable name unless key overrides it. Reads and writes route through the owning EnvironmentVariables proxy (hence the converter registry), so schema.NAME and schema["NAME"] address the same variable — the former typed and defaulted.

Concrete subclasses (BoolEnvVar and siblings) bind T by forwarding the target type to __init__.

Parameters:
__init__(cast, default, description='', *, key=None)[source]

Initialize the descriptor.

Parameters:
  • cast (type[TypeVar(T)]) – Target Python type the stored string is converted to on read.

  • default (TypeVar(T)) – Value returned when the variable is unset.

  • description (str) – Human-readable description (documentation only).

  • key (str | None) – Variable name; defaults to the attribute name the descriptor is assigned to.

reset(instance)[source]

Unset the variable so its default applies again.

Parameters:

instance (EnvironmentVariables) – The owning proxy instance.

Return type:

None

_cast: type[T]
_default: T
_description: str
_explicit_key: str | None
_name: str
property key: str

Environment variable name (the explicit key, or the attribute name).

Returns:

The variable name this descriptor reads and writes.

class stratified_packager.toolbelt.mapping_proxy.EnvironmentVariables(environ=None)[source]

Dict-like proxy over the process environment (os.environ).

Reads and writes environment variables through the shared converter registry, so callers get typed access without hand-rolling string parsing:

env = EnvironmentVariables()
env.get("MY_PORT", 5678, cast=int)  # -> int, with a default
env["MY_FLAG"] = True  # stored as the string "True"

Subclass it and declare EnvVar descriptors for a typed, self-documenting schema — self.<NAME> returns the typed value (its default when unset) and self.<NAME> = value writes it, while the instance stays a full dict-like proxy for any other variable:

class DebugEnv(EnvironmentVariables):
    QGIS_DEBUGPY = BoolEnvVar(default=False)
    QGIS_DEBUGPY_PORT = IntEnvVar(default=5678)


env = DebugEnv()
env.QGIS_DEBUGPY  # -> bool
env.QGIS_DEBUGPY_PORT  # -> int

It touches no QGIS objects, so it is usable from any thread; writes do, however, mutate process-global state. The environment stores only strings, so scalar types (bool, int, float, str, Path) round-trip, while structured values are stored as their str form and do not.

Parameters:

environ (MutableMapping[str, str] | None)

__init__(environ=None)[source]

Initialize the proxy.

Parameters:

environ (MutableMapping[str, str] | None) – Backing environment mapping; defaults to os.environ.

_raw_del(key)[source]

Unset environment variable key.

Parameters:

key (str) – The variable name.

Return type:

None

_raw_get(key)[source]

Read environment variable key.

Parameters:

key (str) – The variable name.

Return type:

tuple[object, bool]

Returns:

A (value, present) pair.

_raw_keys()[source]

Return the defined environment variable names.

Return type:

list[str]

Returns:

The list of variable names.

_raw_set(key, value)[source]

Set environment variable key to the string form of value.

Parameters:
  • key (str) – The variable name.

  • value (object) – The storable value; coerced to str because the environment holds only strings.

Return type:

None

_abc_impl = <_abc._abc_data object>
_environ: MutableMapping[str, str]
class stratified_packager.toolbelt.mapping_proxy.FloatEnvVar(*, default, description='', key=None)[source]

A float environment variable.

Parameters:
__init__(*, default, description='', key=None)[source]

Initialize the descriptor.

Parameters:
  • default (float) – Value returned when the variable is unset.

  • description (str) – Human-readable description (documentation only).

  • key (str | None) – Variable name; defaults to the attribute name.

class stratified_packager.toolbelt.mapping_proxy.IntEnvVar(*, default, description='', key=None)[source]

An int environment variable.

Parameters:
__init__(*, default, description='', key=None)[source]

Initialize the descriptor.

Parameters:
  • default (int) – Value returned when the variable is unset.

  • description (str) – Human-readable description (documentation only).

  • key (str | None) – Variable name; defaults to the attribute name.

class stratified_packager.toolbelt.mapping_proxy.MappingProxy[source]

Common MutableMapping plumbing for the proxies.

Subclasses implement four hooks — _raw_get(), _raw_set(), _raw_del(), and _raw_keys() — and inherit consistent []/in/len/iteration semantics plus a typed get(). The typed-read routing lives in _typed_get(), which backends with type-specific read APIs may override.

abstractmethod _raw_del(key)[source]

Delete key from the backend (only called when the key is present).

Parameters:

key (str) – The key to remove.

Return type:

None

abstractmethod _raw_get(key)[source]

Read key from the backend.

Parameters:

key (str) – The lookup key.

Return type:

tuple[object, bool]

Returns:

A (value, present) pair; value is unspecified when present is False.

abstractmethod _raw_keys()[source]

Return the keys exposed by this proxy.

Return type:

list[str]

Returns:

The list of keys for iteration and length.

abstractmethod _raw_set(key, value)[source]

Write value at key (already converted via to_storage()).

Parameters:
  • key (str) – The destination key.

  • value (object) – The storable value.

Return type:

None

_typed_get(key, cast)[source]

Read key and convert it to cast when present.

The default uses _raw_get() plus from_storage(); backends with type-specific read APIs override this.

Parameters:
  • key (str) – The lookup key.

  • cast (type[object] | None) – Target Python type, or None for the raw value.

Return type:

tuple[object, bool]

Returns:

A (value, present) pair.

get(key, default=None, *, cast=None)[source]
Overloads:
  • self, key (str) → object | None

  • self, key (str), default (object) → object

  • self, key (str), default (T | None), cast (type[T]) → T | None

Return the value for key, optionally converted to cast.

Parameters:
  • key (str) – The lookup key.

  • default (object) – Value returned when key is absent.

  • cast (type[object] | None) – Target Python type; when given, the stored value is converted (via the backend’s typed read or from_storage()).

Returns:

The (optionally converted) value, or default when absent.

_abc_impl = <_abc._abc_data object>
class stratified_packager.toolbelt.mapping_proxy.PathEnvVar(*, default, description='', key=None)[source]

A Path environment variable.

Parameters:
__init__(*, default, description='', key=None)[source]

Initialize the descriptor.

Parameters:
  • default (Path) – Value returned when the variable is unset.

  • description (str) – Human-readable description (documentation only).

  • key (str | None) – Variable name; defaults to the attribute name.

class stratified_packager.toolbelt.mapping_proxy.StrEnvVar(*, default, description='', key=None)[source]

A str environment variable.

Parameters:
__init__(*, default, description='', key=None)[source]

Initialize the descriptor.

Parameters:
  • default (str) – Value returned when the variable is unset.

  • description (str) – Human-readable description (documentation only).

  • key (str | None) – Variable name; defaults to the attribute name.

class stratified_packager.toolbelt.mapping_proxy.TypeConverter(serialize, deserialize)[source]

Round-trips a single Python type to and from a backend-storable representation.

Instances are registered with register_converter() and looked up by to_storage() and from_storage().

Parameters:
__init__(serialize, deserialize)[source]

Store the two conversion callables.

Parameters:
deserialize: Final[Callable[[object], T]]
serialize: Final[Callable[[T], StorableValue]]
stratified_packager.toolbelt.mapping_proxy._as_float(raw)[source]

Coerce a stored value to float.

Parameters:

raw (object) – The stored value.

Return type:

float

Returns:

The floating-point value.

stratified_packager.toolbelt.mapping_proxy._as_int(raw)[source]

Coerce a stored value to int.

Parameters:

raw (object) – The stored value.

Return type:

int

Returns:

The integer value (numbers are truncated; strings are parsed).

stratified_packager.toolbelt.mapping_proxy._as_str(raw)[source]

Coerce a stored value to str.

Parameters:

raw (object) – The stored value.

Return type:

str

Returns:

raw if already a string, otherwise str(raw).

stratified_packager.toolbelt.mapping_proxy._find_converter(klass)[source]

Return the converter registered for klass or its nearest registered base.

Walking the MRO lets a converter registered for an abstract base (e.g. pathlib.Path) handle the concrete instances QGIS hands back (e.g. pathlib.PosixPath / pathlib.WindowsPath).

Parameters:

klass (type) – The type to resolve a converter for.

Return type:

Optional[TypeConverter[Any]]

Returns:

The matching TypeConverter, or None if none is registered.

stratified_packager.toolbelt.mapping_proxy._is_item_iterable(value)[source]

Return whether value should be treated as a sequence of stringifiable items.

True for any Iterable except strings, bytes, and mappings: a string is stored whole (never exploded into characters), bytes are stored whole, and a mapping is not silently reduced to its keys.

Parameters:

value (object) – The value to classify.

Return type:

TypeGuard[Iterable[object]]

Returns:

True if value is a non-string, non-mapping iterable.

stratified_packager.toolbelt.mapping_proxy._to_str_list(raw)[source]

Coerce a stored value into a list of strings.

Parameters:

raw (object) – The stored value (any non-string iterable, or a scalar).

Return type:

list[str]

Returns:

A list of strings; a non-string iterable is stringified item by item, a scalar becomes a single-element list, and an empty or None value becomes an empty list.

stratified_packager.toolbelt.mapping_proxy.from_storage(raw, target_type)[source]

Rebuild a value of target_type from a stored representation.

enum.Enum subclasses are reconstructed by value lookup (target_type(raw)); every other type must have a converter registered for it or a base, whose deserialize callable is then applied.

Parameters:
  • raw (object) – The stored value, possibly read back as a different type.

  • target_type (type[TypeVar(T)]) – The desired Python type.

Return type:

TypeVar(T)

Returns:

raw converted to target_type.

Raises:
  • TypeError – If no converter is registered for target_type.

  • ValueError – If the registered converter cannot parse raw (e.g. a non-numeric string).

stratified_packager.toolbelt.mapping_proxy.register_converter(py_type, serialize, deserialize)[source]

Register conversion callables for py_type, replacing any existing entry.

Parameters:
Return type:

None

stratified_packager.toolbelt.mapping_proxy.to_storage(value)[source]

Convert a Python value into a representation a QGIS backend can persist.

enum.Enum members are reduced to their value; otherwise the converter registered for the value’s type (or nearest registered base) is used. Values whose type has no converter are returned unchanged (assumed natively storable).

Parameters:

value (object) – The Python value to convert.

Return type:

object

Returns:

A backend-storable representation of value.

stratified_packager.toolbelt.mapping_proxy._CONVERTERS: Final[dict[type, TypeConverter[Any]]] = {<class 'bool'>: <stratified_packager.toolbelt.mapping_proxy.TypeConverter object>, <class 'datetime.date'>: <stratified_packager.toolbelt.mapping_proxy.TypeConverter object>, <class 'datetime.datetime'>: <stratified_packager.toolbelt.mapping_proxy.TypeConverter object>, <class 'float'>: <stratified_packager.toolbelt.mapping_proxy.TypeConverter object>, <class 'int'>: <stratified_packager.toolbelt.mapping_proxy.TypeConverter object>, <class 'list'>: <stratified_packager.toolbelt.mapping_proxy.TypeConverter object>, <class 'pathlib.Path'>: <stratified_packager.toolbelt.mapping_proxy.TypeConverter object>, <class 'str'>: <stratified_packager.toolbelt.mapping_proxy.TypeConverter object>, qgis.PyQt.QtGui.QColor: <stratified_packager.toolbelt.mapping_proxy.TypeConverter object>}

Registry mapping each Python type to its TypeConverter.

type stratified_packager.toolbelt.mapping_proxy.StorableValue = str | int | float | bool | list[str]

Union of representations every backend can persist natively.