A tiny typed sentinel for distinguishing None from not provided
Project description
maybe-missing
maybe-missing is a tiny typed helper for one annoyingly real distinction:
Nonemeans “the caller explicitly sent null”MISSINGmeans “the caller did not send this value at all”
That difference matters in patch APIs, dataclasses, settings layers, and anywhere a database column is nullable but an omitted field should mean “leave it alone”.
Why this exists
Python’s Optional[T] answers only one question: can the value be None?
It does not answer the other question: was there a value in the first place?
That becomes awkward fast:
- JSON
nullis a valid payload value - a nullable Postgres column may need to be set to
NULLintentionally - omitting a field in a PATCH request should usually mean “don’t update it”
- a dataclass default should sometimes mean “missing”, not “defaulted to null”
So this package gives you exactly two public names:
Maybe[T]MISSING
And then gets out of your way.
Installation
pip install maybe-missing
Usage
from maybe_missing import Maybe, MISSING
def update_display_name(display_name: Maybe[str | None] = MISSING) -> None:
if display_name is MISSING:
print("leave the existing value alone")
elif display_name is None:
print("explicitly store NULL")
else:
print(f"store {display_name!r}")
Dataclass example
from dataclasses import dataclass
from maybe_missing import Maybe, MISSING
@dataclass(slots=True)
class UserPatch:
nickname: Maybe[str | None] = MISSING
bio: Maybe[str | None] = MISSING
def apply_patch(patch: UserPatch) -> None:
if patch.nickname is not MISSING:
# update nickname to a string or to NULL
...
if patch.bio is not MISSING:
# update bio to a string or to NULL
...
API example
Imagine a request body for partial updates:
{
"nickname": null
}
This should mean:
nicknamewas provided- its value is explicitly
null - the server should write
NULL
While this body:
{}
should mean:
nicknamewas not provided- keep the current value as is
Maybe[T] helps model that cleanly in Python code.
There are only a couple of lines though
Yes.
There are only a couple of lines.
And that’s exactly why it’s more pleasant not to duplicate them across your projects and just do:
from maybe_missing import Maybe, MISSING
Isn’t it?
Typing
The package includes py.typed, so type checkers and IDEs can treat it as a typed distribution.
Compatibility
This package currently targets Python 3.10+.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file maybe_missing-1.0.tar.gz.
File metadata
- Download URL: maybe_missing-1.0.tar.gz
- Upload date:
- Size: 7.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4dc4dfc1c7549474809bc77dd7daa655857e4dc463e6e66c64471c21d3d6927b
|
|
| MD5 |
267dbd86b17198de7a30c6f6f5fb16ba
|
|
| BLAKE2b-256 |
a9b552b67f1e9e31af6da0f00e9d13743addecacec9980e2df44628b442f571c
|
Provenance
The following attestation bundles were made for maybe_missing-1.0.tar.gz:
Publisher:
publish.yml on Fatal1ty/maybe-missing
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
maybe_missing-1.0.tar.gz -
Subject digest:
4dc4dfc1c7549474809bc77dd7daa655857e4dc463e6e66c64471c21d3d6927b - Sigstore transparency entry: 1058393193
- Sigstore integration time:
-
Permalink:
Fatal1ty/maybe-missing@6f02750597b0f62407f777bab19247be75682d79 -
Branch / Tag:
refs/tags/v1.0 - Owner: https://github.com/Fatal1ty
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6f02750597b0f62407f777bab19247be75682d79 -
Trigger Event:
release
-
Statement type:
File details
Details for the file maybe_missing-1.0-py3-none-any.whl.
File metadata
- Download URL: maybe_missing-1.0-py3-none-any.whl
- Upload date:
- Size: 7.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6ef2f61b082323a16961e9968bac6b83486b5cd6324ebf59d0eb5f364df9627f
|
|
| MD5 |
b3836e9dec675757f6b98632cf163f84
|
|
| BLAKE2b-256 |
820cd0b5c515a3fb323f7c8738304d9a548dbe76769a3f4f82a0058f7460407f
|
Provenance
The following attestation bundles were made for maybe_missing-1.0-py3-none-any.whl:
Publisher:
publish.yml on Fatal1ty/maybe-missing
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
maybe_missing-1.0-py3-none-any.whl -
Subject digest:
6ef2f61b082323a16961e9968bac6b83486b5cd6324ebf59d0eb5f364df9627f - Sigstore transparency entry: 1058393194
- Sigstore integration time:
-
Permalink:
Fatal1ty/maybe-missing@6f02750597b0f62407f777bab19247be75682d79 -
Branch / Tag:
refs/tags/v1.0 - Owner: https://github.com/Fatal1ty
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6f02750597b0f62407f777bab19247be75682d79 -
Trigger Event:
release
-
Statement type: