Skip to main content

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:

  • 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-0.1.tar.gz (7.5 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-0.1-py3-none-any.whl (7.5 kB view details)

Uploaded Python 3

File details

Details for the file maybe_missing-0.1.tar.gz.

File metadata

  • Download URL: maybe_missing-0.1.tar.gz
  • Upload date:
  • Size: 7.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.12.12 Darwin/25.3.0

File hashes

Hashes for maybe_missing-0.1.tar.gz
Algorithm Hash digest
SHA256 9edef67a472d55cb21d0c3d1a8425300673ef0a7b1d7a987336f084a86e9e93e
MD5 52da5e1924ebf627daba547875eddda5
BLAKE2b-256 cdd87db208f728f36abbfb3aa6b3eb75777e1897140d72663ddbc5dde99c870a

See more details on using hashes here.

File details

Details for the file maybe_missing-0.1-py3-none-any.whl.

File metadata

  • Download URL: maybe_missing-0.1-py3-none-any.whl
  • Upload date:
  • Size: 7.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.12.12 Darwin/25.3.0

File hashes

Hashes for maybe_missing-0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 adaa61d379edd934a221104d65921c899f942b84e85ead5c31c9c3cbec16f6ee
MD5 35f1e730a3f0d5c807b0379d709cb2d2
BLAKE2b-256 5b25e3e5fdc6faef63bf8b4ad59d6e5723eae90abc89657eee3728f0678a3c9d

See more details on using hashes here.

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