Skip to main content

A tiny typed sentinel for distinguishing None from not provided

Project description

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

Project details


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.

Supported by

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