A high-level library for manipulating Python Bytecode in an easy way.
Project description
PyMixin
PyMixin is a python library designed to help inject code in a compatible way. It is heavily inspired by the SpongePowered Mixin project.
Features
Redirect function calls
>>> from mixin import *
>>> from math import log, log10
>>>
>>> def test_function(n: int) -> int:
... return log(n)
...
>>> @redirect(method=test_function, at=At(value=AtValue.INVOKE, target=log))
... def real_input(n: int) -> int:
... # Call log10 instead of log
... return log10(n)
...
>>> test_function(10)
1.0
Change constants
>>> from mixin import *
>>> from random import randint
>>>
>>> def percent(n: int) -> float:
... return n / 100
...
>>> @modify_const(method=percent, at=At(value=AtValue.LOAD, target=100))
... def random_denominator():
... return randint(0, 100)
...
>>> percent(10)
0.2777777777777778
>>> percent(10)
0.35714285714285715
Inject callbacks
>>> from mixin import *
>>>
>>> def internal_message_handler(data: bytes):
... return # Dummy implementation
...
>>> @inject(method=internal_message_handler, at=At(value=AtValue.HEAD))
... def log_message(data: bytes, callback_info: CallbackInfo):
... print("Received data:", data)
...
>>> internal_message_handler(b"Hello world")
Received data: b'Hello world'
Cancel functions
>>> from mixin import *
>>>
>>> def process(body: str):
... if body == "Hello":
... print("World")
... else:
... print("Invalid body")
...
>>> @inject(method=process, at=At(value=AtValue.HEAD), cancellable=True)
... def cancel_if_bad(body: str, callback_info: CallbackInfo):
... if body != "Hello":
... callback_info.cancel()
...
>>> process("Hello")
World
>>> process("World")
>>>
Modify returned value
>>> from mixin import *
>>>
>>> def return_n_squared(n):
... return n * n
...
>>> @inject(method=return_n_squared, at=At(value=AtValue.RETURN), cancellable=True) # Warning: injects at EVERY return by default
... def return_n_cubed_instead(callback_info: CallbackInfo):
... n = (callback_info.return_value**0.5)
... callback_info.set_return(n**3)
...
>>> return_n_squared(10)
1000.0
Overwrite functions
>>> from mixin import *
>>>
>>> def spam_a():
... while True:
... print("a")
...
>>> @overwrite(method=spam_a)
... def replacement():
... print("b")
...
>>> spam_a()
b
A note on decorators
Often in python, a function is wrapped with a decorator. This means the value of a function is no longer the same.
To resolve this, we added mixin.unwrap, to get the original function back (assuming functools.wraps) was used.
>>> from mixin import *
>>> from functools import wraps
>>>
>>> def with_print(func):
... @wraps(func)
... def inner(*args, **kwargs):
... print("args", args, kwargs)
... return func(*args, **kwargs)
... return inner
...
>>> @with_print
... def test(n):
... return n*2
...
>>> @inject(method=unwrap(test), at=At(value=AtValue.HEAD))
... def log_n(n, callback_info):
... print("N:", n)
...
>>> test(10)
args (10,) {}
N: 10
20
Installing
To install PyMixin, you can just use pip:
pip install pymixin
License
PyMixin is licensed under MIT.
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 pymixin-1.1.1.tar.gz.
File metadata
- Download URL: pymixin-1.1.1.tar.gz
- Upload date:
- Size: 8.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.3.0 pkginfo/1.7.0 requests/2.26.0 setuptools/57.4.0 requests-toolbelt/0.9.1 tqdm/4.56.0 CPython/3.9.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5856837ce05d1a0012d4dd7cc15c17c37451b9ba7d512b573cb1758412846fd0
|
|
| MD5 |
e54c4c5c81d0edaa1fdf120e1d8484a3
|
|
| BLAKE2b-256 |
6666c0ad0135ee4d2798d219fc6dafc617838df9d3acb2e477b23bad22c0047a
|
File details
Details for the file pymixin-1.1.1-py3-none-any.whl.
File metadata
- Download URL: pymixin-1.1.1-py3-none-any.whl
- Upload date:
- Size: 8.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.3.0 pkginfo/1.7.0 requests/2.26.0 setuptools/57.4.0 requests-toolbelt/0.9.1 tqdm/4.56.0 CPython/3.9.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
86b6e3107b0d6dcf186ff4aa8c76c54bd187f54cb0bca31f010651ee2ea29620
|
|
| MD5 |
ba20026ef29fc0182def119a625370a4
|
|
| BLAKE2b-256 |
cf20d0e56094b5d6a9eb2236893717ee25481ac19b9f5a99beeb278a97d17a37
|