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:
...
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
saleyo-1.3.3.tar.gz
(17.6 kB
view details)
Built Distribution
saleyo-1.3.3-py3-none-any.whl
(23.2 kB
view details)
File details
Details for the file saleyo-1.3.3.tar.gz
.
File metadata
- Download URL: saleyo-1.3.3.tar.gz
- Upload date:
- Size: 17.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: pdm/2.18.3.dev2+g0ed53b6 CPython/3.10.12 Linux/6.5.0-1025-azure
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | de613102ad5dd343b09b72f5332d123f338eafdfc1f9942e626991c3b654ab96 |
|
MD5 | d35393ef5afbcf3d5e0d4c359206f489 |
|
BLAKE2b-256 | d454218e6187e4245bf0ab7785260e7ba065c16612b713ce176082356c53022b |
File details
Details for the file saleyo-1.3.3-py3-none-any.whl
.
File metadata
- Download URL: saleyo-1.3.3-py3-none-any.whl
- Upload date:
- Size: 23.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: pdm/2.18.3.dev2+g0ed53b6 CPython/3.10.12 Linux/6.5.0-1025-azure
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 47b477b3e2395c7084ed93e692d03d25e7ca5a51c0baac43500c3d9e1a9eea1d |
|
MD5 | ea41b2402b47105b0deb60c490d17d8b |
|
BLAKE2b-256 | 50e9f4e0a33343d4c59fde42176c8a75a79050c90751d3ce07987a361d1bc7ab |