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+.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

maybe_missing-1.0.tar.gz (7.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

maybe_missing-1.0-py3-none-any.whl (7.7 kB view details)

Uploaded Python 3

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

Hashes for maybe_missing-1.0.tar.gz
Algorithm Hash digest
SHA256 4dc4dfc1c7549474809bc77dd7daa655857e4dc463e6e66c64471c21d3d6927b
MD5 267dbd86b17198de7a30c6f6f5fb16ba
BLAKE2b-256 a9b552b67f1e9e31af6da0f00e9d13743addecacec9980e2df44628b442f571c

See more details on using hashes here.

Provenance

The following attestation bundles were made for maybe_missing-1.0.tar.gz:

Publisher: publish.yml on Fatal1ty/maybe-missing

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for maybe_missing-1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6ef2f61b082323a16961e9968bac6b83486b5cd6324ebf59d0eb5f364df9627f
MD5 b3836e9dec675757f6b98632cf163f84
BLAKE2b-256 820cd0b5c515a3fb323f7c8738304d9a548dbe76769a3f4f82a0058f7460407f

See more details on using hashes here.

Provenance

The following attestation bundles were made for maybe_missing-1.0-py3-none-any.whl:

Publisher: publish.yml on Fatal1ty/maybe-missing

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

1.0 This release

2 files

0.1

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page