Skip to main content

A basic implementation of a maybe/option type in Python, largely inspired by Rust's Option.

Project description

py-maybetype

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

A basic implementation of a maybe/option type in Python, largely inspired by Rust's Option. This was created as part of a separate project I had been working on, but I decided to make it into its own package as I wanted to use it elsewhere and its scope grew. This is not meant to be a 1:1 replication or replacement for Rust's Option or Haskell's Maybe, but rather just an interperetation of the idea that I feel works for Python.

Usage

Install the package with pip using the repository link:

pip install git+https://github.com/svioletg/py-maybetype

Call the maybe() function with a T | None value to return a Maybe[T]—either a Some instance containing the wrapped value, or the Nothing singleton.

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, Nothing is falsy

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

This example in particular can also be done with Maybe's built-in int() class method:

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

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.

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 _:
        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

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

date_str = None
date = maybe(date_str).then(datetime.fromisoformat)
# date == None

date_str = ''
date = maybe(date_str or None).then(datetime.fromisoformat)
# date == 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

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

py_maybetype-0.5.0.tar.gz (14.6 kB view details)

Uploaded Source

Built Distribution

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

py_maybetype-0.5.0-py3-none-any.whl (6.3 kB view details)

Uploaded Python 3

File details

Details for the file py_maybetype-0.5.0.tar.gz.

File metadata

  • Download URL: py_maybetype-0.5.0.tar.gz
  • Upload date:
  • Size: 14.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.8

File hashes

Hashes for py_maybetype-0.5.0.tar.gz
Algorithm Hash digest
SHA256 c02f613b28602984c2f3508031cb1d49cd161298bc089648fbb7288a9053337c
MD5 ec4aef44098fc230c6c2943f5cbb222a
BLAKE2b-256 7c0a42ab590b5c50967e6ae9f2db6a2433fa74998de32941a5b4808b7d80ccbd

See more details on using hashes here.

File details

Details for the file py_maybetype-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: py_maybetype-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 6.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.8

File hashes

Hashes for py_maybetype-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8d32d20c14abde49623f3691ce3c843591319a9d10ec539bfd587d97b930e092
MD5 9ee3da64125c8ac17044f5b38f21eedd
BLAKE2b-256 d6590d29614783fec11953c4bd9aaf2ac8ed0b7bfa15adbe726d220a3df3abdc

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