Lightweight method proxy/wrapper helper with pre, post, and exception hooks.
Project description
AutoWrapper
AutoWrapper is a small Python helper for building wrapper/proxy objects around another object's methods.
It lets a wrapper class expose selected methods from a target object and optionally route method calls through pre/post/exception hooks. This is useful for lightweight instrumentation such as logging, tracing, metrics, access checks, or debugging wrappers.
Current status
This project is still small and intentionally direct: one implementation module, AutoWrapper.py, a lowercase compatibility import module, packaging metadata, and a unittest test suite.
Implemented behavior:
- Wrap methods from a target object onto a wrapper instance.
- Call target-bound methods so target instance state is preserved.
- Support optional hints for selecting which methods to proxy and wrap.
- Support no-hints mode, which proxies and wraps all public discovered methods.
- Discover inherited instance methods, static methods, and class methods.
- Skip private/dunder methods by default, with explicit hint opt-in.
- Preserve useful method metadata for wrapped methods via
functools.wraps(). - Provide pre, post, and exception hooks with method context.
- Reject proxied method names that would overwrite wrapper attributes or methods.
- Provide typed public methods and prefer the snake_case
get_methods_to_wrap()discovery API while preservinggetMethods2Wrap()compatibility.
Basic usage
from autowrapper import AutoWrapper
class Example:
def __init__(self):
self.count = 0
def increment(self, amount=1):
self.count += amount
return self.count
class WrappedExample(AutoWrapper):
def __init__(self, target):
self.events = []
self.build_wrapper(
target,
hints={"increment": {"proxy": True, "wrap": True}},
)
def _pre_method_hook(self, method_name, method, args, kwargs):
self.events.append(("pre", method_name, args, kwargs))
def _post_method_hook(self, method_name, method, args, kwargs, result):
self.events.append(("post", method_name, result))
def _exception_method_hook(self, method_name, method, args, kwargs, exc):
self.events.append(("exception", method_name, exc))
target = Example()
wrapper = WrappedExample(target)
assert wrapper.increment(amount=2) == 2
assert target.count == 2
assert wrapper.events == [
("pre", "increment", (), {"amount": 2}),
("post", "increment", 2),
]
Scope: object methods, not standalone functions
AutoWrapper is intentionally scoped to wrapping methods discovered from a target object. It supports instance methods, inherited methods, static methods, and class methods on that target object's class.
Standalone/free functions are out of scope for now. If you need to wrap a free function, use a normal decorator directly or place the function behind a small object method before using AutoWrapper.
Method discovery API
The preferred public discovery helper is:
AutoWrapper.get_methods_to_wrap(TargetClass, hints=None)
The original spelling remains available for compatibility:
AutoWrapper.getMethods2Wrap(TargetClass, hints=None)
Hint semantics
build_wrapper(target, hints=...) accepts a dictionary keyed by method name.
Supported keys:
proxy: expose this method on the wrapper instance.wrap: route the proxied method through the hook methods.
Behavior:
hints is None: proxy and wrap every public discovered instance, static, and class method.proxy: True: expose the method on the wrapper.proxyabsent or false: do not expose the method, even ifwrap: True.wrap: True: call_pre_method_hook()before the target method and_post_method_hook()after it succeeds.wrapabsent or false: expose the target-bound method directly without hooks.- Methods absent from a supplied
hintsdictionary are not proxied. - Static methods and class methods are supported and can be proxied/wrapped like instance methods.
- Private methods whose names begin with
_are skipped by default, but can be explicitly proxied with hints. - Proxied method names that collide with existing wrapper attributes or methods raise
AttributeError.
Hook signatures
Override these methods in your wrapper subclass when you need behavior around wrapped calls:
def _pre_method_hook(self, method_name, method, args, kwargs):
pass
def _post_method_hook(self, method_name, method, args, kwargs, result):
pass
def _exception_method_hook(self, method_name, method, args, kwargs, exc):
pass
Exceptions raised by wrapped target methods call _exception_method_hook() and then propagate unchanged.
Installation
Once published to PyPI, install with:
python -m pip install blakemere-autowrapper
For local development from a clean checkout:
python -m pip install -e .
The PyPI distribution name is blakemere-autowrapper. The preferred import path is lowercase:
from autowrapper import AutoWrapper
The original import path remains available for compatibility:
from AutoWrapper import AutoWrapper
Running tests
This project currently uses the Python standard-library unittest framework, so no test dependency installation is required.
From a clean checkout, run:
python -m unittest discover -s tests -v
You can also run the inline example in the implementation module:
python AutoWrapper.py
Repository layout
AutoWrapper.py # implementation and tiny inline example
autowrapper.py # lowercase import compatibility module
pyproject.toml # packaging metadata
__init__.py # placeholder package marker
tests/test_autowrapper.py # unittest coverage
BACKLOG.md # project improvement backlog
Packaging note
pyproject.toml packages both modules:
autowrapper: preferred lowercase import path.AutoWrapper: original compatibility import path.
License
MIT. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file blakemere_autowrapper-0.1.1.tar.gz.
File metadata
- Download URL: blakemere_autowrapper-0.1.1.tar.gz
- Upload date:
- Size: 7.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fa680e3d27610d16291ee2800657b3006ff1deb6da90d22554002e7bcdd65b8d
|
|
| MD5 |
bca35197ed1359077ef3b9738519d604
|
|
| BLAKE2b-256 |
a646b7287818521c6beb2683e480cd4a2226a4ba65fc5c46cbfb9d320c5b7d5a
|
Provenance
The following attestation bundles were made for blakemere_autowrapper-0.1.1.tar.gz:
Publisher:
publish-pypi.yml on RusDavies/blakemere-autowrapper
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
blakemere_autowrapper-0.1.1.tar.gz -
Subject digest:
fa680e3d27610d16291ee2800657b3006ff1deb6da90d22554002e7bcdd65b8d - Sigstore transparency entry: 1713548339
- Sigstore integration time:
-
Permalink:
RusDavies/blakemere-autowrapper@9abb1afdb76c19c8bef88f4e330e847cc69c24bb -
Branch / Tag:
refs/heads/main - Owner: https://github.com/RusDavies
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@9abb1afdb76c19c8bef88f4e330e847cc69c24bb -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file blakemere_autowrapper-0.1.1-py3-none-any.whl.
File metadata
- Download URL: blakemere_autowrapper-0.1.1-py3-none-any.whl
- Upload date:
- Size: 7.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
55f515489adf1a802d61c624eb423bd9994b8d86b5835394c53cfccf0ef79735
|
|
| MD5 |
a24cf1b0a9aefcc54f56e7514fe8fac3
|
|
| BLAKE2b-256 |
2ef8ddeacc5948b2ca354bca10dff4c542cc2b65f6ff261feb3d6963d1e4ab47
|
Provenance
The following attestation bundles were made for blakemere_autowrapper-0.1.1-py3-none-any.whl:
Publisher:
publish-pypi.yml on RusDavies/blakemere-autowrapper
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
blakemere_autowrapper-0.1.1-py3-none-any.whl -
Subject digest:
55f515489adf1a802d61c624eb423bd9994b8d86b5835394c53cfccf0ef79735 - Sigstore transparency entry: 1713548464
- Sigstore integration time:
-
Permalink:
RusDavies/blakemere-autowrapper@9abb1afdb76c19c8bef88f4e330e847cc69c24bb -
Branch / Tag:
refs/heads/main - Owner: https://github.com/RusDavies
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@9abb1afdb76c19c8bef88f4e330e847cc69c24bb -
Trigger Event:
workflow_dispatch
-
Statement type: