simplibs-sentinels
Shared sentinel values for the simplibs ecosystem — precise tools for distinguishing different states of absence and intent.
Contents
- Installation
- Why sentinels?
- Overview
- UNSET
- MISSING
- DEFAULT
- EMPTY
- Type annotations
- About the simplibs ecosystem
Installation
pip install simplibs-sentinels
Why sentinels?
Python has no built-in way to distinguish between "parameter was not provided",
"value is intentionally absent", and "value is None" — yet these are three
different situations requiring different logic.
# Problem — None can mean anything
def connect(host: str, timeout: int | None = None):
if timeout is None:
# was timeout omitted? or intentionally passed as None?
...
# Solution — each state has its own sentinel
def connect(host: str, timeout: int | UnsetType = UNSET):
if timeout is UNSET:
timeout = get_default_timeout() # not provided → use default
elif timeout is None:
timeout = 0 # None passed intentionally → no timeout
All sentinels are singletons and falsy — always compare using is.
Overview
| Sentinel | Semantics | Typical context |
|---|---|---|
UNSET |
function parameter was not provided | default parameter values |
MISSING |
value was expected but is absent from input data | input data validation |
DEFAULT |
explicit request for default behaviour | overriding dynamic defaults |
EMPTY |
intentional emptiness, distinct from None |
clearing or resetting values |
UNSET
Distinguishes a parameter that was not provided from an intentionally passed None.
from simplibs.sentinels import UNSET, UnsetType
def connect(host: str, timeout: int | UnsetType = UNSET):
if timeout is UNSET:
timeout = get_default_timeout()
elif timeout is None:
timeout = 0
MISSING
Signals that a value was expected but is entirely absent from the input data. Useful when validating dictionaries, forms, or API payloads.
from simplibs.sentinels import MISSING, MissingType
def validate(data: dict, key: str):
value = data.get(key, MISSING)
if value is MISSING:
raise ValueError(f"Required key '{key}' is missing.")
elif value is None:
... # key exists, value is None — different logic applies
DEFAULT
Expresses the explicit intent "I want the default behaviour" — even when the default value is not static but decided at runtime.
from simplibs.sentinels import DEFAULT, DefaultType
def render(color: str | DefaultType = DEFAULT):
if color is DEFAULT:
color = theme.primary_color
Difference from UNSET: UNSET means "the user provided nothing",
DEFAULT means "the user explicitly wants the default value".
EMPTY
Intentional emptiness — a signal that a value should be explicitly cleared, without needing to pass an empty collection of a specific type.
from simplibs.sentinels import UNSET, EMPTY, EmptyType
def set_tags(tags: list | EmptyType | UnsetType = UNSET):
if tags is UNSET:
pass # not provided → change nothing
elif tags is EMPTY:
self.tags = [] # intentionally clear all tags
else:
self.tags = tags
Type annotations
Use the sentinel types directly in type annotations:
from simplibs.sentinels import UNSET, UnsetType
def process(value: str | UnsetType = UNSET) -> None:
...
About the simplibs ecosystem
simplibs-sentinels is part of the simplibs ecosystem — a collection of
small, self-contained Python libraries. Each one solves exactly one thing —
but all of them share a common philosophy:
Dyslexia-friendly — minimise mental load. Atomise code into self-contained units, name files after the logic they contain, write explanations that describe why — not just what.
Programmer's zen — nothing should be missing and nothing should be superfluous. The journey is the destination: code should be fully understood; better to go slowly and correctly than quickly and with mistakes. The crystallisation approach — not perfection on the first try, but gradual refinement towards it.
Defensive style — anticipate all possible failure modes so that only safe paths remain. Never raise unexpected errors; degrade gracefully.
Minimalism — find the path to the goal in as few steps as possible, but leave nothing out. Each file has one responsibility.
Code as craft — code should be pleasant to look at and evoke a sense of harmony. Treat code as a small work of art — like a carpenter carving a sculpture. Optimise for the user: everything should make sense without having to study the documentation at length.
These are aspirations — a sense of direction. And that is exactly what the note about the journey becoming the destination is all about. 🙂
The library is covered by tests across all modules. Tests are part of the repository and serve as living documentation of the expected behaviour.
Release files for simplibs-sentinels 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| simplibs_sentinels-0.1.0.tar.gz | 9.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| simplibs_sentinels-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 19.7 kB
Release files / simplibs_sentinels-0.1.0.tar.gz
| Download URL | simplibs_sentinels-0.1.0.tar.gz |
|---|---|
| Size | 9.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c3017a28fdc381f2380238e5fa9d8c2f15526af22013511bfa4d8b7da30a9dd4
|
|
BLAKE2b-256 checksum How to use checksums |
cb0d622a9199117ce97ec569dc3ca080490e0d5cb9cdd49dfb24450b73788c0d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|
Release files / simplibs_sentinels-0.1.0-py3-none-any.whl
| Download URL | simplibs_sentinels-0.1.0-py3-none-any.whl |
|---|---|
| Size | 9.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7e4cd027d82828e4ac44bf6627d919aed97093b28df44f1dd24ac42b3d78b63b
|
|
BLAKE2b-256 checksum How to use checksums |
91121bdc7992db7a11a83fd48b606011203f2702862d7af7c26d982b3749fc2c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|