Skip to main content

py-maybetype

Linting Testing PyPI publishing

Documentation: https://py-maybetype.readthedocs.io/en/latest/

PyPI: https://pypi.org/project/py-maybetype/

[!WARNING] This project is in beta, and breaking changes are likely with each 0.x release.

A basic implementation of a maybe/option type in Python, largely aiming for parity (within reason) with Rust's Option and Result types implemented in a way that makes sense for Python, with a few additional methods.

Usage

Install with pip:

pip install py-maybetype

Call the maybe() function with a T | None value to return either a Some[T] instance containing the wrapped value, or the Nothing singleton. You can also directly use the Some constructor or the Nothing singleton explicitly e.g. when returning a value from a function. Maybe only serves as a base class to provide methods for Some and Nothing and to be used for typing, it should not be instanced directly. If it is, MaybeInstanceError is raised.

Nothing is an instance of the NothingType class, and should be used instead of creating new NothingType instances since all are functionally identical. NothingTypeInitError if the class is instanced more than once.

from maybetype import Maybe, maybe

# Only the maybe() function should be used,
# the Maybe class is only imported here for type annotations

def try_int(x: str) -> int | None:
    """Attempts to convert a string of digits into an `int`, returning `None` if not possible."""
    try:
        return int(x)
    except ValueError:
        return None

num1: Maybe[int] = maybe(try_int('5'))
num2: Maybe[int] = maybe(try_int('five'))

print(num1.unwrap()) # 5
print(num2.unwrap()) # (raises ValueError)

# Some() instances are always truthy, NothingType() is falsy

assert bool(num1) is True
assert bool(num2) is False

The maybe constructor can be given an optional predicate argument to specify a custom condition for which Some(value) is returned. This argument must be a Callable that returns bool, where returning False causes the constructor to return Nothing.

[!NOTE] maybe(None) will always return Nothing, even if predicate(None) would return True

import re
import uuid

from maybetype import maybe

def is_valid_uuid(s: str) -> bool:
    return re.match(r"[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}|[0-9a-f]{32}", s) is not None

assert maybe('3b1bcc3a-41d5-49a5-8273-10cc605e31f9', is_valid_uuid)
assert maybe('3b1bcc3a41d549a5827310cc605e31f9', is_valid_uuid)
assert not maybe('qwertyuiopasdfghjklzxcvbnm', is_valid_uuid)
assert not maybe('nf0cmmdq-l0gt-rq5a-upry-706trht3ocv9', is_valid_uuid)

Maybe instances can also be used in match/case pattern matching to access the wrapped value, like so:

from maybetype import maybe, Some

match maybe(1):
    case Some(val):
        print('Value: ', val)
    case _: # "case Nothing:" also works, but just matching else in this case will be identical
        print('No value')

Other examples

Converting a str | None timestamp into a datetime object if not None, otherwise returning None:

from datetime import datetime
from maybetype import maybe

assert maybe('2025-09-06T030000').then(datetime.fromisoformat) == datetime(2025, 9, 6, 3, 0)

assert maybe(None).then(datetime.fromisoformat) is None

assert maybe('' or None).then(datetime.fromisoformat) is None
# Maybe does not treat falsy values as None, only strictly x-is-None values
# Without `or None` here, datetime.fromisoformat would have raised a ValueError

Converting a str | None timestamp into a datetime object if not None, then ensuring that date meets certain criteria:

from datetime import datetime
from maybetype import maybe

assert maybe('2025-09-06T030000').and_then(datetime.fromisoformat).test(lambda dt: dt.year > 2024)

assert not maybe('2024-09-06T030000').and_then(datetime.fromisoformat).test(lambda dt: dt.year > 2024)

match maybe('2025-09-06T030000').and_then(datetime.fromisoformat).test(lambda dt: dt.year > 2024):
    case Some(date):
        ... # Do something with the date
    case _:
        ... # Do something else

Release files for py-maybetype 0.13.1

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

Source distribution (sdist)

Source distribution for py-maybetype 0.13.1
File Size Uploaded
py_maybetype-0.13.1.tar.gz 67.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for py-maybetype 0.13.1
File Interpreter ABI Platform
py_maybetype-0.13.1-py3-none-any.whl Python 3 none any Details

Total release size: 77.7 kB

Release files / py_maybetype-0.13.1.tar.gz

Download URL py_maybetype-0.13.1.tar.gz
Size 67.6 kB
Tags Source
SHA-256 checksum
How to use checksums
4624c5cb8b111235f09656b9173b1801f94197d5fa11496d7ba7e1762fd7f853
BLAKE2b-256 checksum
How to use checksums
01d165da9c2ca23793d07b1113c780f5cde721dc16a1d90b345d801025d7348c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jul 9, 2026.

Transparency log

Release files / py_maybetype-0.13.1-py3-none-any.whl

Download URL py_maybetype-0.13.1-py3-none-any.whl
Size 10.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d181ca7efe4d6dac8bb2dfc16cf8ba16dca49ff9f0d0be082e99c1f1656b2002
BLAKE2b-256 checksum
How to use checksums
67751b767616be45f30149fd069fb5b599339d21b6d3a66439f296a527ae77e4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jul 9, 2026.

Transparency log

Release history Release notifications | RSS feed

0.14.0

2 release files

This release

0.13.1 This release

2 release files

0.13.0

2 release files

0.12.0

2 release files

0.10.1

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

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