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.0.tar.gz (5.7 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.0-py3-none-any.whl (5.4 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for nullplus-1.0.tar.gz
Algorithm Hash digest
SHA256 d66ba6017414247d37f1a5a36e72d5a087558596b788722469c28690ac271757
MD5 e2650e1f8247676b1178c63a9fe0a232
BLAKE2b-256 3e1e80c43cb45fdfeb51ec8d038db6eca7cb66da58284b3fe0e1e5d41cb104ad

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nullplus-1.0-py3-none-any.whl
  • Upload date:
  • Size: 5.4 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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 303ac3e441f5d961841cca87c51f3ceb1558d7c1dac628742ef44464a1165ee7
MD5 fb51a2f7afda31aadef5d2f30df28707
BLAKE2b-256 f720d285e2941492c2afea4d10b0977c10e4a9e4b1a0c30917d74c126f182385

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