Skip to main content

A simple class that allows for error handling and eating inputs

Project description

NullPlus

PyPI version

A lightweight, robust implementation of the Null Object pattern that silently absorbs all operations while optionally carrying diagnostic data, plus an Unset class for differentiating between explicit None values and unset states.

# Instead of:
result = None
if result is None: 
    handle_error()

# Simply:
result = Null()
result.anything().you.want()  # No crashes, no fuss

# Differentiate unset vs explicit None:
config_value = Unset() if missing else value

Key Features

Universal Operation Absorption (Null)

  • Attribute access (obj.anything) → returns self
  • Method calls (obj.method(arg)) → returns self
  • Mathematical operations (obj + 10) → returns self
  • Item access (obj["key"]) → returns self
  • Iteration (for x in obj) → empty iterator
  • Context managers (with obj:) → no-op
  • Boolean context (if obj:) → always False

Unset Sentinel Value

  • Explicitly represents unset/undefined states
  • Differentiates between explicit None and missing values
  • Safe equality checks: Unset() == Unset()True
  • Distinct from all other values including None and Null

Easy Detection & Intentional Usage

if isinstance(result, Null):  # Explicit error check
    log_errors(result.data)   # Access stored diagnostics

if value is Unset():          # Detect unset state
    load_default_config()

Diagnostic Data Carrier (Null)

n = Null("Error: File not found", debug_id=42)
print(n)  # <Null: ("Error: File not found", {'debug_id': 42})>

Type-Safe Behavior (Null)

  • len(Null())0
  • int(Null())-1
  • float(Null())nan
  • list(Null())[]

Asynchronous Support (Null)

async with Null() as n:
    await n.some_operation()  # No errors

async for x in Null():
    print("Never runs")

Installation

pip install NullPlus

Usage Guide

Basic Error Handling (Null)

from NullPlus import Null

def safe_parser(data):
    try:
        return complex_operation(data)
    except Exception as e:
        return Null(e, original_data=data)

result = safe_parser(invalid_input)
print(result.anything)  # <Null: (ValueError('...'), {...})>

Unset Value Detection

from NullPlus import Unset

def process_config(config=Unset()):
    if config is Unset():
        print("Using default configuration")
        config = load_defaults()
    elif config is None:
        print("Explicitly disabled configuration")
    
    # Normal processing...

API Response Handling (Null)

def fetch_user_data():
    try:
        return api.get("/user")
    except ConnectionError as e:
        return Null(e, status_code=503)

data = fetch_user_data()
for item in data.get('items', Null()):
    # Safely handles either real data or Null
    process(item)

Mathematical Resilience (Null)

def calculate_metrics():
    return Null("Metrics unavailable") if error else real_metrics

result = calculate_metrics() * 10 / 5
print(result)  # <Null: 'Metrics unavailable'>

Advanced Diagnostics (Null)

error_state = Null(
    "Database connection failed",
    error_code=502,
    timestamp=datetime.now(),
    query_params=request.params
)

# Preserves complex diagnostic data
your_log_function(error_state.data)

Technical Highlights

Truthiness & Equality

# Null behavior
bool(Null())  # False
Null() == Null("different data")  # True
Null() == None  # False

# Unset behavior
Unset() == Unset()  # True
Unset() == None     # False
Unset() == Null()   # False
bool(Unset())       # True (normal object truthiness)

Operation Absorption Matrix (Null)

Operation Example Result
Attribute access Null().missing_attr <Null>
Method call Null()() <Null>
Item access Null()['key'] <Null>
Arithmetic Null() + 10 <Null>
Iteration list(Null()) []
Context manager with Null(): ... No-op
Async operations await Null() <Null>

Unset Key Properties

Property Description
Operation Safety Not operation-absorbing (normal attribute rules apply)
Primary Use Case Sentinel value for missing/undefined state
Distinct From None, Null(), empty containers, and falsey values
Serialization Represents as <Unset Value>

Why Choose NullPlus?

  1. Clear State Differentiation

    • Null for controlled error absorption
    • Unset for detecting unconfigured/missing values
    • Both distinct from None
  2. Eliminate Expensive Mistakes Avoid AttributeError, TypeError, and NoneType crashes with Null

  3. Debugging-Friendly Preserve error context without disrupting control flow (Null) Explicit state tracking (Unset)

  4. Context-Aware (Null) Works in sync/async contexts, math operations, and iterations

  5. Semantic API Clearly signals intentional states in your codebase

  6. Zero Dependencies Pure Python implementation

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

nullplus-1.2.tar.gz (5.8 kB view details)

Uploaded Source

Built Distribution

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

nullplus-1.2-py3-none-any.whl (5.5 kB view details)

Uploaded Python 3

File details

Details for the file nullplus-1.2.tar.gz.

File metadata

  • Download URL: nullplus-1.2.tar.gz
  • Upload date:
  • Size: 5.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.10

File hashes

Hashes for nullplus-1.2.tar.gz
Algorithm Hash digest
SHA256 c091a35ed4032a04192461e77ff93e682d4d579e1813da96f81ce39553a1428e
MD5 f077ed482ed384918a435543d85b5480
BLAKE2b-256 908f10f60a80ae6b02b9571152cccbe650d4a0b66357c4b820075838af1a72cf

See more details on using hashes here.

File details

Details for the file nullplus-1.2-py3-none-any.whl.

File metadata

  • Download URL: nullplus-1.2-py3-none-any.whl
  • Upload date:
  • Size: 5.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.10

File hashes

Hashes for nullplus-1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0c3788c90e55ece2021b6c283caf2a8a78b82fb16946c1f6be11e926d00d847b
MD5 28a49c8f01ca980e489f3ac7e7e160fd
BLAKE2b-256 329dc5d72252134dfb23fc6f099f739b4173f322304d12b0fd64661378e80eee

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