Decorator for tracing Python generator internals
Project description
Here’s a starter README.md for your genwatch package. Feel free to tweak wording, add badges, or expand the examples as you like.
# genwatch
Lightweight decorator and proxy for tracing Python generator internals
(`send`, `throw`, `close`, and `yield from` delegation) with structured logs.
---
## Features
- **Decorator** (`@genwatch.Reporter`) to wrap any generator function
- **Automatic forwarding** of `send()`, `throw()`, and `close()` calls
- Logs **enter/exit** of each `yield from` delegation
- Captures **generator attributes** (`gi_code`, `gi_frame`, `gi_running`, `gi_suspended`, `gi_yieldfrom`)
- Handles both **generator** and **iterator** delegates (`range`, lists, etc.)
- Early **TypeError** if decorating a non-generator function
---
## Installation
```bash
pip install genwatch
Or, if you’re installing from source:
git clone https://github.com/yourusername/genwatch.git
cd genwatch
pip install -e .[test]
Quickstart
import logging
from genwatch import Reporter
# Create a logger (optional – Reporter will default to a StreamHandler)
logger = logging.getLogger("myapp")
logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter("[%(asctime)s] %(message)s"))
logger.addHandler(handler)
@Reporter(logger=logger)
def countdown(n: int):
"""Yield numbers 0..n-1, then finish."""
for i in range(n):
yield i
# Drive the generator
gen = countdown(3)
for x in gen:
print("Got:", x)
# Logs will show the internal state at each yield.
Delegation example
@Reporter(logger=logger)
def subgen():
yield "a"
yield "b"
@Reporter(logger=logger)
def outer():
# Logs will show entry into `subgen`, its locals, and exit
yield from subgen()
yield "done"
for v in outer():
print(v)
API
genwatch.Reporter
Decorator for generator functions. Wraps a function so that:
- Calling the wrapped function returns an iterator that proxies through a
_ProxyReporter. - On each
next(),send(),throw(), andclose(), logs generator internals. - Requires Python 3.8+.
@Reporter
def mygen():
yield 1
yield 2
Raises TypeError if applied to a non-generator function.
Running Tests
Your tests live in the tests/ directory. To install test dependencies and run:
pip install -e .[test]
pytest
You’ll see a suite of passing tests, plus a few xfail demos highlighting current limitations.
Contributing
- Fork the repo
- Create a feature branch (
git checkout -b feature/xyz) - Write code, add tests, update docs
- Open a Pull Request
License
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.
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 genwatch-0.1.0.tar.gz.
File metadata
- Download URL: genwatch-0.1.0.tar.gz
- Upload date:
- Size: 16.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e4c45108957552f1ce5a4000a2bc74c9cc5538ee3c9452499d4cdfb1085ad00b
|
|
| MD5 |
d50d073a67471a09908301db5bd5b2f2
|
|
| BLAKE2b-256 |
0cee0768b827bbcf9833ce9a2c44a8230bd58feadfc3bcf6fe72a9607b51db1b
|
File details
Details for the file genwatch-0.1.0-py3-none-any.whl.
File metadata
- Download URL: genwatch-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
42c66f66dc332409e2f3bd96f1598dedb0dfde8751dee732d5201271b0d37cb8
|
|
| MD5 |
5a45c8ae54cdd4c979bf31d8a8c74e78
|
|
| BLAKE2b-256 |
0f4514002dc59a7ef36608af7ba8a542b62643a521b5ca26ef749fdf3b1bf60f
|