Skip to main content

extensionmethods

Mimics C#-style extension methods in Python.

extensionmethods is a tiny package that lets you “attach” functions to existing types without modifying their source code, enabling method-like syntax, better chaining, and cleaner separation of optional dependencies.

Example usage

In C#, you can add methods to existing types:

public static class IntExtensions
{
    public static int Double(this int x)
    {
        return x * 2;
    }
}

int result = 7.Double();

You get method syntax without modifying int.

With the extensionmethods package you can achieve similiar functionality like so:

from extensionmethods import extension

@extension
def double(x: int) -> int:
    return x * 2

result = 7 | double()
print(result)  # 14

With parameters:

@extension
def add_then_multiply(x: int, to_add: int, to_multiply: int) -> int:
    return (x + to_add) * to_multiply

result = 7 | add_then_multiply(11, 3)
print(result)  # 54

The value on the left side becomes the first argument of the function.

Type safety and IDE integration

The extension methods are type-aware, based on the type of their first parameter. Type checkers and editors can detect incorrect usage:

"hello" | double()  # type error

Your IDE (e.g. VS Code) can flag this because the extension has its first argument of type int, not str.

Furtermore, the extension methods support docstrings and code suggestions in your IDE:

IDE Integration

Installation

Using pip:

pip install extensionmethods

Using uv:

uv pip install extensionmethods

Why use extension methods?

Readability through chaining

Instead of nested calls:

result = normalize(scale(center(data)))

You can express the same flow step-by-step:

result = data | center() | scale() | normalize()

This reads left-to-right and mirrors how data is conceptually transformed.

Modularity and dependency isolation

Suppose you maintain a core class:

class Dataset:
    ...

You want export helpers:

  • to_pandas()
  • to_numpy()
  • to_torch()

If you put these methods directly on Dataset, your core package must depend on pandas, numpy, and torch.

Instead, keep the core dependency-free:

# core package
class Dataset:
    ...

Then provide optional extensions:

# dataset_pandas package
import pandas as pd
from extensionmethods import extension
from core import Dataset

@extension(to=Dataset)
def to_pandas(ds: Dataset) -> pd.DataFrame:
    ...

Usage:

import dataset_pandas  # registers the extension

df = dataset | to_pandas()

Now:

  • The core package has zero heavy dependencies
  • Users only install what they need
  • Functionality stays logically grouped

Known caveats

Uses the | operator (__ror__)

The system works by overriding the right-side bitwise OR operator.

result = value | extension_call()

This only works if the left-hand type does not fully consume the | operator itself.

For example, sets already use |:

{1, 2} | {3}   # set union

If a type defines its own __or__ in a way that prevents fallback to __ror__, the extension method will not run.

License

This project is licensed under the MIT License. See the LICENSE file for details.

Metadata

Release files for extensionmethods 0.1.5

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

Source distribution (sdist)

Source distribution for extensionmethods 0.1.5
File Size Uploaded
extensionmethods-0.1.5.tar.gz 51.9 kB Details

Built distribution (wheel)

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

Total release size: 56.5 kB

Release files / extensionmethods-0.1.5.tar.gz

Download URL extensionmethods-0.1.5.tar.gz
Size 51.9 kB
Tags Source
SHA-256 checksum
How to use checksums
5dd1601e6f5159bd41de9a24881e567d36bfb4c69026eddd73d0c78d51a2ebcb
BLAKE2b-256 checksum
How to use checksums
093a12a6e3560ea00981ada787f6d9012fb0f1f9889e874f3f7ce27621fc5654
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 15, 2026.

Transparency log

Release files / extensionmethods-0.1.5-py3-none-any.whl

Download URL extensionmethods-0.1.5-py3-none-any.whl
Size 4.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
71c593906ee90e7ba4db39d08f9127deb6f9f12cebe93753641fb3069214db20
BLAKE2b-256 checksum
How to use checksums
e37a5cdcc2b799d7e6f769b09aae404bf15cf3ec3e1d6d611d36ae3e906d9b09
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.5 This release

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

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