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.
Metadata
Release files for pymixin 1.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pymixin-1.1.1.tar.gz | 8.1 kB | Without provenance | Details for pymixin-1.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pymixin-1.1.1-py3-none-any.whl | Python 3 | none | any | Details for pymixin-1.1.1-py3-none-any.whl |
Total release size: 16.3 kB
Release files / pymixin-1.1.1.tar.gz
| Download URL | pymixin-1.1.1.tar.gz |
|---|---|
| Size | 8.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5856837ce05d1a0012d4dd7cc15c17c37451b9ba7d512b573cb1758412846fd0
|
|
BLAKE2b-256 checksum How to use checksums |
6666c0ad0135ee4d2798d219fc6dafc617838df9d3acb2e477b23bad22c0047a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is 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
|
Release files / pymixin-1.1.1-py3-none-any.whl
| Download URL | pymixin-1.1.1-py3-none-any.whl |
|---|---|
| Size | 8.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
86b6e3107b0d6dcf186ff4aa8c76c54bd187f54cb0bca31f010651ee2ea29620
|
|
BLAKE2b-256 checksum How to use checksums |
cf20d0e56094b5d6a9eb2236893717ee25481ac19b9f5a99beeb278a97d17a37
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is 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
|
Security for pymixin 1.1.1
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.