Saleyo is a lightwight scalable Python AOP framework, easy to use and integrate.
Project description
Saleyo
Saleyo is a lightwight scalable Python AOP framework, easy to use and integrate.
Getting Start
pip install saleyo
Basic Tutorial
Declear a Mixin class
If you don't like decorators, you can pass arguments to operations and call the mixin method manually.
from saleyo import Mixin
class Foo:...
@Mixin(target = Foo)
class MixinFoo:...
Use MixinOperation
Here is a simple demo.
from typing import Any
from saleyo import Mixin, Accessor, OverWrite, Post, Pre, Intercept, InvokeEvent
class Foo:
__private = "private varible"
def demo(self):
pass
@Mixin(target = Foo)
class MixinFoo:
# Will add a varible named `__private` to Foo and it has the same address with `_Foo__private`
private: Accessor[str] = Accessor("__private")
# Will Add the `func` to `Foo`
@OverWrite
def func(self):
print("hello saleyo")
# Will intercept the demo method and redirect to `lambda: print("hello world")`
@Intercept.configure(target_name="demo")
@staticmethod
def intercept_demo(_: InvokeEvent):
return InvokeEvent(lambda: print("hello world"))
# Will call before `demo` call
@Pre.configure(target_name="demo")
def pre_demo(*arg):
print("pre hello world")
# Will call after `demo` call
@Post.configure(target_name="demo")
def post_demo(*arg):
print("post hello world")
foo: Any = (
Foo()
) # Add the typing hint to avoid the error message from some IDE plugins.
print(foo.__private) # Also `print(MixinFoo.private.value)`
foo.func()
foo.demo()
>>> private varible
>>> hello saleyo
>>> pre hello world
>>> hello world
>>> post hello world
Lazy Mixin - Define Mixin before importing module
Lazy Mixin will be triggered after importing
You dont need to care how to import target module, just define a locator!
# targetmod
class NeedMixin:
def hello(self):
print("hello world")
# mixin
# put mixin in a single file and import to use is better
from types import ModuleType
from typing import Any
from saleyo.broadcast.importmod import ImportBroadCaster
from saleyo.decorator.mixin import Mixin
from saleyo.operation.hook import Pre
broadcast = ImportBroadCaster.instance()
def locator(name: str, module: ModuleType):
if name == "targetmod" and module.__dict__.__contains__("NeedMixin"):
return module.NeedMixin
return None
@Mixin.lazy(locator)
class MixinTarget:
@Pre
@staticmethod
def hello(this: Any) -> None:
print("Pre Hook")
print(broadcast.listeners())
import targetmod # noqa: E402
print(broadcast.listeners())
targetmod.NeedMixin().hello()
>>> Pre Hook
>>> hello world
Operate Compile
# targetmodule
def generate(name):
return name + " hell world"
class Static:
FIELD = generate("hello")
# mixin
from typing import Any, Union
from saleyo.decorator.compile import CompileToken, CompileBoundary
@CompileToken(lambda info: "targetmodule.py" in str(info.filename))
def mixin_a(token: Union[str, bytes, Any]):
if not isinstance(token, bytes):
return
return token.replace(b"hell world", b"bye")
with CompileBoundary():
from targetmodule import Static
# If targetmodule import before Compile BroadCast initialize
# Use `CompileBoundary.recompile_module(...)`, it's compated with `no_cache=False`
print(targetmodule.Static().FIELD) # hello bye
>>> hello bye
Which Decorator should I use?
Custom ToolChain
ToolChain determines the ability to modify the class.
from saleyo import Mixin, GCToolChain, Arguments, Pre
@Mixin(target=str, toolchain=GCToolChain)
class MixinStr:
@Pre.configure(target_name="format")
def pre_format(self, *args) -> Arguments[...]:
print(f"input args: {args}")
return Arguments(self, "saleyo")
print("hello world {}".format("python"))
>>> input args: ('python',)
>>> hello world saleyo
Custom Mixin Operation
The default operations can't satify you? Try define a operation yourself!
from typing import Any
from saleyo import MixinOperation, ToolChain
from saleyo.base.typing import M
class MyOperation(MixinOperation[Any]):
def mixin(self, target: M, toolchain: ToolChain = ...) -> None:
...
Contribution
pip install pdm
pdm install
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 saleyo-1.3.4.tar.gz.
File metadata
- Download URL: saleyo-1.3.4.tar.gz
- Upload date:
- Size: 18.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: pdm/2.25.6.dev10+g05f152e8 CPython/3.12.3 Linux/6.11.0-1018-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9d975aeb9281761577869442b97566f6002ac8632e9801c83a8e6396eba973d7
|
|
| MD5 |
931780460acbf520670d11588eeffd1f
|
|
| BLAKE2b-256 |
d27132400eb69240fda5cc13728f87aed63db9b2100c640a44f8fa427d617771
|
File details
Details for the file saleyo-1.3.4-py3-none-any.whl.
File metadata
- Download URL: saleyo-1.3.4-py3-none-any.whl
- Upload date:
- Size: 23.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: pdm/2.25.6.dev10+g05f152e8 CPython/3.12.3 Linux/6.11.0-1018-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e0ce426c25e81e32d7df291c5364a0adb6fc5ac2306317a1a6279a81060417ed
|
|
| MD5 |
4cd4ca58fd66608f2d7d3a7df8fa7ac1
|
|
| BLAKE2b-256 |
52ee1ecd09e6197de88691ab3486de0b4c71253e1fb4f72120d3ab000394a0b7
|