Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/orsinium-labs/aop
Aspect oriented programming for Python. Patch everything!
https://github.com/orsinium-labs/aop
advice aop aspectj aspects import python python3
Last synced: about 2 months ago
JSON representation
Aspect oriented programming for Python. Patch everything!
- Host: GitHub
- URL: https://github.com/orsinium-labs/aop
- Owner: orsinium-labs
- Created: 2018-08-15T14:27:42.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2019-01-07T08:53:26.000Z (over 5 years ago)
- Last Synced: 2024-07-04T17:20:54.930Z (2 months ago)
- Topics: advice, aop, aspectj, aspects, import, python, python3
- Language: Python
- Homepage:
- Size: 72.3 KB
- Stars: 13
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# ![AOP](./assets/logo.png)
> Badges? We ain’t got no badges! We don’t need no badges! I don’t have to show you any stinking badges!
> - [The Treasure of the Sierra Madre](https://www.youtube.com/watch?v=wHxgQopPMRE)[Aspect-oriented programming](https://en.wikipedia.org/wiki/Aspect-oriented_programming)
Features:
1. Patch any module: your project, stdlib, built-ins.
1. Patch any object: functions, class instances.
1. Pure Python implementation: run it on CPython or PyPy.TODO:
1. Patch already imported objects
1. Patch `__init__` and `__new__`.
1. Test PyPy## Example
```python
import aopdef multiply(context):
print(context.aspect, context.args, context.kwargs)
yield
context.result *= 100aop.register(
handler=multiply,
modules=aop.match(equals='math'),
targets=aop.match(regexp='(sin|cos)')
)
```Ok, let's check:
```python
import math
math.cos(0)
# prints: cos (0,) {}
# returns: 100.0
```## Usage
### Register
Register new advice:
```python
aop.register(
handler=some_handler,
modules=aop.match(equals='math'),
targets=aop.match(regexp='(sin|cos)')
)
```Parameters for `aop.register`:
* `handler` -- advice for joinpoint processing.
* `paths` -- expression for path to module.
* `modules` -- expression for module name.
* `targets` -- expression for object name.
* `methods` -- expression for called object's method. It's `__call__` for functions.### Match
Available kwargs for `aop.match`:
* `regexp` -- object name fully match to regular expression.
* `startswith` -- object name starts with specified string.
* `endswith` -- object name ends with specified string.
* `contains` -- object contains specified string.
* `equals` -- object name equal to specified string.### Handler and context
Handler looks like:
```python
def multiply(context):
... # before aspect call
yield
... # after aspect call
```Context's properties:
* `aspect` -- name of target.
* `method` -- name of called method or `__call__` for functions.
* `module` -- name of module where aspect defined.
* `path` -- path to module where aspect defined.
* `args` -- tuple of passed positional args
* `kwargs` -- dict of passed keyword args
* `result` -- target's method response### Enable and disable
Register all advices or just enable patching before all other imports in project:
```python
import aop
aop.enable()
... # all other imports
```Also it's recommend finally enable patching after register last advice:
```python
aop.register(...)
aop.register(...)
aop.enable(final=True)
```If you want to disable patching:
```python
aop.disable()
```### Inspect
Inspect object:
```python
aop.inspect(math.isclose, print=True)
```## Patch import system automatically
Now this package can't patch modules that imported before `aop.enable()` or `aop.register(...)`:
```bash
$ python3 special_cases/2_after.py
...
AssertionError: not patched
```Although you can run your script via aop runner:
```bash
$ python3 -m aop special_cases/2_after.py
cos (0,) {}
```