Skip to main content

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 - Mixin a Object before importing its 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 saleyo.base.import_broadcast import list_import_listeners
from saleyo.decorator.mixin import Mixin
from saleyo.operation.hook import Pre


def locater(name: str, module: ModuleType):
    if name == "targetmod":
        if module.__dict__.__contains__("NeedMixin"):
            return module.NeedMixin
    return None # Dont Mixin this module


@Mixin.lazy(locater)
class MixinTarget:
    @Pre
    def hello(self):
        print("Pre Hook")


print(list_import_listeners()) # {hashkey: Callable}
import targetmod as targetmod  # noqa: E402

print(list_import_listeners()) # {} auto dispose after setting

targetmod.NeedMixin().hello()

>>> Pre Hook
>>> hello world

Operate Compile

# targetmodule
def generate(name):
    return name + " hell world"


class StaticMap:
    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"static' tag", b"bye")


with CompileBoundary(): # Force to compile
    from targetmodule import StaticMap

print(StaticMap().FIELD)  # hello bye


>>> hello hello world

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 Operation

The default operations can't satify you? Why not 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


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.0.tar.gz (14.6 kB view details)

Uploaded Source

Built Distribution

saleyo-1.3.0-py3-none-any.whl (19.0 kB view details)

Uploaded Python 3

File details

Details for the file saleyo-1.3.0.tar.gz.

File metadata

  • Download URL: saleyo-1.3.0.tar.gz
  • Upload date:
  • Size: 14.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: pdm/2.18.2.dev7+ge80a81c CPython/3.10.12 Linux/6.5.0-1025-azure

File hashes

Hashes for saleyo-1.3.0.tar.gz
Algorithm Hash digest
SHA256 6923dcb3bfbacf3d56d8af53ac39356ff506c72a054d4df596cda4d62fbcdfae
MD5 5ef33042926d9aa9d4507797f5179727
BLAKE2b-256 c46de32cb7eec88e351a4dad891cf9eb459a36cbcb17188538d4769f37bf7c8f

See more details on using hashes here.

File details

Details for the file saleyo-1.3.0-py3-none-any.whl.

File metadata

  • Download URL: saleyo-1.3.0-py3-none-any.whl
  • Upload date:
  • Size: 19.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: pdm/2.18.2.dev7+ge80a81c CPython/3.10.12 Linux/6.5.0-1025-azure

File hashes

Hashes for saleyo-1.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 31a32934b468180b019ee1a11562061e8342cea21d905671b872ffea6f21e079
MD5 b234ca7c1156208366141e17b98d4415
BLAKE2b-256 ca9c5c39cc7ce277329f7266f0d09170685484e7202324bf9b88138fde908705

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page