metricengine.null_behaviour

Null Behavior Management Module for Metric Engine

This module provides a comprehensive system for controlling how None values are handled during financial calculations. It implements a context-aware approach using Python’s ContextVar to manage null handling behavior across different operations without requiring explicit parameter passing.

Core Components:
  • NullBinaryMode: Controls None handling in binary operations (+, -, *, /)

  • NullReductionMode: Controls None handling in reduction operations (sum, mean)

  • NullBehavior: Configuration class combining both modes

  • Context managers for temporary behavior changes

  • Predefined behavior configurations for common scenarios

Null Binary Modes:
  • PROPAGATE (default): Safe mode where any None operand results in None

  • RAISE: Strict mode that raises exceptions when encountering None values

Null Reduction Modes:
  • PROPAGATE: Returns None if any None values are present in collections

  • SKIP (default): Ignores None values and processes only valid values

  • ZERO: Treats None values as zero for additive reductions

  • RAISE: Raises exceptions when encountering None values

Usage Examples:

# Set global null behavior with use_nulls(NullBehavior(reduction=NullReductionMode.RAISE)):

result = fv_sum([FV(100), FV.none(), FV(200)]) # Raises exception

# Temporary reduction mode change with with_reduction(NullReductionMode.ZERO):

total = fv_sum([FV(100), FV.none(), FV(200)]) # Result: FV(300)

# Predefined behaviors with use_nulls(SUM_ZERO): # Treat None as zero

revenue_total = fv_sum(revenue_data)

Thread Safety:

Uses ContextVar for thread-local storage, making it safe for multi-threaded applications. Each thread maintains its own null behavior context.

Integration:

Works seamlessly with FinancialValue arithmetic operations and reduction functions like fv_sum and fv_mean throughout the metric engine.

class metricengine.null_behaviour.NullBinaryMode(value)[source]

Bases: Enum

How None is handled in binary ops (a ⊕ b).

PROPAGATE = 1
RAISE = 2
class metricengine.null_behaviour.NullReductionMode(value)[source]

Bases: Enum

How None is handled in reductions (sum/avg/etc.).

PROPAGATE = 1
SKIP = 2
ZERO = 3
RAISE = 4
class metricengine.null_behaviour.NullBehavior(binary=NullBinaryMode.PROPAGATE, reduction=NullReductionMode.SKIP)[source]

Bases: object

Combined null-handling strategy for binary ops and reductions.

binary: NullBinaryMode = 1
reduction: NullReductionMode = 2
class metricengine.null_behaviour.use_nulls(behavior)[source]

Bases: object

Context manager for temporarily setting null behavior. Usage:

with use_nulls(STRICT_RAISE):

metricengine.null_behaviour.use_reduction(mode)[source]

Temporarily override reduction mode only.

Return type:

Iterator[None]

metricengine.null_behaviour.use_binary(mode)[source]

Temporarily override binary mode only.

Return type:

Iterator[None]

metricengine.null_behaviour.with_reduction(mode)

Temporarily override reduction mode only.

Return type:

Iterator[None]

metricengine.null_behaviour.with_binary(mode)

Temporarily override binary mode only.

Return type:

Iterator[None]

metricengine.null_behaviour.get_nulls()[source]

Return the currently active null behavior.

Return type:

NullBehavior

metricengine.null_behaviour.with_nulls(behavior)[source]

Decorator to run a function under a specific null behavior.

Return type:

Callable[[TypeVar(F, bound= Callable[..., Any])], TypeVar(F, bound= Callable[..., Any])]

@with_nulls(STRICT_RAISE) def compute(…):

Null Behaviour Enum

Null Handling Functions