Skip to content

Commit

Permalink
✨ Bondary Recompile Method
Browse files Browse the repository at this point in the history
  • Loading branch information
H2Sxxa committed Sep 2, 2024
1 parent 48b3b5f commit 152c56a
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 18 deletions.
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def generate(name):
return name + " hell world"


class StaticMap:
class Static:
FIELD = generate("hello")

# mixin
Expand All @@ -151,10 +151,13 @@ def mixin_a(token: Union[str, bytes, Any]):
return token.replace(b"hell world", b"bye")


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

print(StaticMap().FIELD) # hello bye
# 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
```
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "saleyo"
version = "1.3.0"
version = "1.3.1"
description = "Saleyo is a lightwight scalable Python AOP framework, easy to use and integrate."
authors = [{ name = "H2Sxxa", email = "[email protected]" }]
dependencies = []
Expand Down
39 changes: 35 additions & 4 deletions src/saleyo/base/compile_broadcast/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
from collections import OrderedDict
from dataclasses import dataclass
from importlib import reload
from os import unlink
from pathlib import Path
from types import ModuleType
from typing import Any, Callable, Dict, Optional, Tuple, Union
import sys

Expand Down Expand Up @@ -116,7 +120,7 @@ def broadcast(

class CompileBoundary:
"""
Module Inside will be force compile
Module Inside will force compile.
## Example
Expand All @@ -129,18 +133,45 @@ class CompileBoundary:
"""

origin: bool
no_cache: bool

def __init__(self) -> None:
def __init__(self, no_cache: bool = True) -> None:
self.origin = sys.dont_write_bytecode
self.no_cache = no_cache

def __enter__(self):
self.activate()
if self.no_cache:
self.activate()
return self

def __exit__(self, *_):
self.deactivate()
if self.no_cache:
self.deactivate()

def activate(self):
sys.dont_write_bytecode = True

def deactivate(self):
sys.dont_write_bytecode = self.origin

@staticmethod
def recompile_module(module: ModuleType):
"""
When the module has been loaded before, recompile it to modify
## Example
```python
import targetmodule
# Mixin Here...
with CompileBoundary(no_cache=False) as compile:
compile.recompile_module(targetmodule)
```
"""
if hasattr(module, "__cached__"):
file = Path(module.__cached__)
if file.exists():
unlink(module.__cached__)
reload(module)
4 changes: 2 additions & 2 deletions src/saleyo/decorator/compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


class CompileTime:
"""This decorator should be **dangerous**, it will affect the compile of .pyc. If you found it not work, please delete the target import cache"""
"""This decorator is **dangerous**, it will affect the compile of .pyc. If you found it not work, please consider delete the target import `__py_cache__` and then use a `CompileBoundary`"""

locator: Callable[[CompileInfo], bool]
token: Union[int, str]
Expand Down Expand Up @@ -56,7 +56,7 @@ def listener(info: CompileInfo):


class CompileToken(CompileTime):
"""Alternative version of CompileTime, just modify source."""
"""Alternative version of CompileTime, just modify source, but it is also **dangerous**"""

def __call__(
self, processor: Callable[[Union[str, bytes, Any]], Union[str, bytes, Any]]
Expand Down
6 changes: 3 additions & 3 deletions tests/reload/targetmodule.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
def generate(name):
return name + " static' tag"
return name + " static"


class StaticMap:
FIELD = generate("hello")
class Static:
FIELD = generate("hello")
10 changes: 6 additions & 4 deletions tests/reload/test.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
from typing import Any, Union
from saleyo.decorator.compile import CompileToken, CompileBoundary
import targetmodule


@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")
return token.replace(b"static", b"bye2")


with CompileBoundary():
from targetmodule import StaticMap
with CompileBoundary(no_cache=False) as compile:
compile.recompile_module(targetmodule)

print(StaticMap().FIELD) # hello bye

print(targetmodule.Static().FIELD) # hello bye

0 comments on commit 152c56a

Please sign in to comment.