Skip to main content

Undercat

PyPI - Version GitHub Actions Workflow Status Coverage Status License: MIT pre-commit

Undercat logo (a striped cat walking on the ceiling)

Undercat is a small Python library implementing a functional programming construct called the Reader functor. This pattern is particularly useful for dependency injection, composing functions, and operating on immutable, context-aware computations.

The Reader functor is ideal when you need to:

  • Pass a shared dependency or context (e.g., configuration, environment) through multiple computations without explicitly threading it through function calls.
  • Create pipelines of computation where each step depends on a shared state.
  • Enhance code readability by abstracting common operations such as accessing attributes or combining results.

Features

  • Function composition: Compose computations using a clean, declarative style.
  • Attribute and item access: Retrieve nested attributes or indexed elements with ease.
  • Operator overloading: Perform arithmetic, logical, and comparison operations directly on Reader objects.

Installation

pip install undercat

or (using uv)

uv pip install undercat

Quickstart

1. Basic Usage

Define a Reader that retrieves data from a context and operates on it:

import undercat as uc

class Context:
    """A context with a dict attribute."""
    def __init__(self, value):
        self.data = {'key': value}

# Define a Reader to get a nested value from a context.
get_value = uc.attrgetter('data').getitem('key')

context = Context(42)

# Execute the Reader with a context.
get_value(context)  # output: 42

2. Function Composition

Readers can be composed using .map to transform outputs:

get_value_and_increment = get_value.map(lambda x: x + 1)

# Execute the modified Reader.
get_value_and_increment(context)  # output: 43

3. Combining Readers

Combine multiple Readers into one using operators:

# Define a Reader that squares its input.
square = uc.Reader(lambda x: x * x)

# Define a Reader that leaves its input alone.
identity = uc.Reader(lambda x: x)

# Combine Readers arithmetically.
combined = square + identity

# Execute the Reader.
# Its constituent Readers act independently on the same input; the results are then added.
combined(3)  # output: 12 (3 * 3 + 3)
combined(5)  # output: 30 (5 * 5 + 5)

# Combine Readers to make a new Reader that produces a tuple.
combined = uc.make_tuple(square, identity)

combined(3)  # output: (9, 3)

# Create a Reader that produces a constant value for any input.
const10 = uc.const(10)

# Create a Reader that multiplies the output of its constituent Readers.
combined = uc.prod([const10, identity, square])

combined(3)  # Output: 270 (10 * 3 * 9)

API Overview

Core Methods

  • Reader(func): Wrap a function into a Reader.
  • uc.const(val): Create a Reader that always returns a constant value.
  • uc.attrgetter(attr, [default]): Access an attribute (or nested attributes) from a context.
  • uc.make_tuple(*readers): Combine multiple Readers into one that returns a tuple.

Operators

Readers support most logical/arithmetic operations:

  • Arithmetic: +, -, *, **, /, //, %, @
  • Boolean/bitwise logic: and, or, &, |, ^, ~
  • Comparisons: <, <=, >=, >
    • For equality you cannot use == and !=; instead use reader.equals(other) and reader.not_equals(other).

You can also apply operations to sequences of Readers using uc.sum, uc.prod, uc.all, uc.any, uc.min, uc.max, and uc.reduce.

License

This library is open-source and licensed under the MIT License.

Contributions are welcome!

Metadata

Release files for undercat 0.1.2

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

Source distribution (sdist)

Source distribution for undercat 0.1.2
File Size Uploaded
undercat-0.1.2.tar.gz 9.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for undercat 0.1.2
File Interpreter ABI Platform
undercat-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 16.6 kB

Release files / undercat-0.1.2.tar.gz

Download URL undercat-0.1.2.tar.gz
Size 9.2 kB
Tags Source
SHA-256 checksum
How to use checksums
352df9b4935ef0e761a74773800f9638aea012b4822d21cc77521d5a33a40cae
BLAKE2b-256 checksum
How to use checksums
feca4ff2dc04a2bda6d65f51b4f0cfe15785f2f6a1838c0fb56e1208673d2d12
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via python-httpx/0.23.3

Release files / undercat-0.1.2-py3-none-any.whl

Download URL undercat-0.1.2-py3-none-any.whl
Size 7.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
abf3a0935ae1fe09ab561fd99745fc890e79dc8ce0c84b0cdd3a20036dcdcd3d
BLAKE2b-256 checksum
How to use checksums
73257348fab9be964fd1cbd0f5af140148abeb1e30d4597caa125d00964fe9a7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via python-httpx/0.23.3

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

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