Skip to main content

maybe-missing

Build Status Latest Version Python Version License

maybe-missing is a tiny typed helper for one annoyingly real distinction:

  • None means “the caller explicitly sent null”
  • MISSING means “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 null is a valid payload value
  • a nullable Postgres column may need to be set to NULL intentionally
  • 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:

  • nickname was provided
  • its value is explicitly null
  • the server should write NULL

While this body:

{}

should mean:

  • nickname was 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+.

Metadata

Release files for maybe-missing 1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for maybe-missing 1.0
File Size Uploaded
maybe_missing-1.0.tar.gz 7.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for maybe-missing 1.0
File Interpreter ABI Platform
maybe_missing-1.0-py3-none-any.whl Python 3 none any Details

Total release size: 15.3 kB

Release files / maybe_missing-1.0.tar.gz

Download URL maybe_missing-1.0.tar.gz
Size 7.6 kB
Tags Source
SHA-256 checksum
How to use checksums
4dc4dfc1c7549474809bc77dd7daa655857e4dc463e6e66c64471c21d3d6927b
BLAKE2b-256 checksum
How to use checksums
a9b552b67f1e9e31af6da0f00e9d13743addecacec9980e2df44628b442f571c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 7, 2026.

Transparency log

Release files / maybe_missing-1.0-py3-none-any.whl

Download URL maybe_missing-1.0-py3-none-any.whl
Size 7.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6ef2f61b082323a16961e9968bac6b83486b5cd6324ebf59d0eb5f364df9627f
BLAKE2b-256 checksum
How to use checksums
820cd0b5c515a3fb323f7c8738304d9a548dbe76769a3f4f82a0058f7460407f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 7, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0 This release

2 release files

0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page