Skip to main content

Optional.py

Build Status test lint typecheck format editorconfig License Python Versions Contributors Open Source Love Downloads

An Implementation of the Optional Object for Python

Why

There is a difference between None as Empty and None as the result for an Error. A common bad practice is to return None to indicate the absence of something. Doing this introduces ambiguity into you code.

For example:

thing = stuff.getSomeThing().getAnotherThing()

What will happen if the result from getSomeThing returns None? We will get an AttributeError: 'NoneType' object has no attribute 'getAnotherThing'.

What can you do to prevent these kinds of exceptions? You can write defensively:

something = stuff.getSomeThing()
if something is not None:
    thing = something.getAnotherThing()

However, if we add to our chain, you can imagine how the nesting of defensive checks adds up quickly. These defensive checks obfuscate our actual business logic, decreasing readability. Furthermore, defensive checking is an error prone process, because it is easy to forget to check a required condition.

So we present you with an Optional object as an alternative.

Install

Compatible with Python 3.10 and up!

pip install optional.py

Usage

  1. You can import it using:

    from optional import Nothing, Option, Optional, Something
    
  2. You can set it to empty:

    instead of: 🙀

    return None
    

    you can do: 😸

    return Optional.empty()
    

    or

    return Optional.of()
    
  3. You can set it to have content:

    instead of: 🙀

    return "thing"
    

    you can do: 😸

    return Optional.of("thing")
    
  4. You can check if its present:

    instead of: 🙀

    if thing is not None:
    

    you can do: 😸

    thing = some_func_returning_an_optional()
    if thing:
    
  5. You can check if its empty:

    instead of: 🙀

    if thing is None:
    

    you can do: 😸

    thing = some_func_returning_an_optional()
    if not thing:
    
  6. You can match against the result and destructure the value:

    instead of: 🙀

    print(thing)
    

    you can do: 😼

    match some_func_returning_an_optional():
        case Something(thing):
            print(thing)
    
  7. You can match against an empty optional, but can't destructure the value:

    instead of: 😿

    if thing is None:
        print(None) # very odd
    

    you can do: 😼

    match some_func_returning_an_optional()
        case Nothing():
            print("We didn't get a thing!")
    
  8. You can compare two optionals: 😸

    Optional.empty() == Optional.empty() # True
    Optional.of("thing") == Optional.of("thing") # True
    Optional.of("thing") == Optional.empty() # False
    Optional.of("thing") == Optional.of("PANTS") # False
    

Tests

There is complete test coverage and they pass in all Python versions 3.10 and up.

Running Unit Tests

First, install poetry using the instructions located here.

Then, install the requirements using:

poetry install

You can run the tests (with coverage) using:

poetry run pytest

Metadata

Release files for optional.py 2.0.0

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

Source distribution (sdist)

Source distribution for optional.py 2.0.0
File Size Uploaded
optional_py-2.0.0.tar.gz 4.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for optional.py 2.0.0
File Interpreter ABI Platform
optional_py-2.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 8.9 kB

Release files / optional_py-2.0.0.tar.gz

Download URL optional_py-2.0.0.tar.gz
Size 4.0 kB
Tags Source
SHA-256 checksum
How to use checksums
567f4cb8b80e14dd36693afa39c2897c82912abdfba3574212aed9353d4a7725
BLAKE2b-256 checksum
How to use checksums
dcccc14db2da7c2d643b4b0bb77ff6a957bcf86a63d7fbd15d268ecf089b76af
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.0.0 CPython/3.12.2

Release files / optional_py-2.0.0-py3-none-any.whl

Download URL optional_py-2.0.0-py3-none-any.whl
Size 4.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b79434effb80ff77a5c10c2f577a8618f7ea21d96587eb6b15bab32150a4a9bd
BLAKE2b-256 checksum
How to use checksums
9cb00f589f70c979bc12abf24a576caa5ed007d53b15a1737e23aad5aef482fb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.0.0 CPython/3.12.2

Release history Release notifications | RSS feed

This release

2.0.0 This release

2 release files

1.3.2

2 release files

1.3.1

2 release files

1.1.0

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.2

1 release file

0.2.1

1 release file

0.2.0

1 release file

0.1.4

1 release file

0.1.3

1 release file

0.1.2

1 release file

0.1.1

1 release file

0.1.0

1 release file

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