aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/infini/core.py4
-rw-r--r--src/infini/generator.py8
-rw-r--r--src/infini/injector.py40
-rw-r--r--src/infini/loader.py12
-rw-r--r--src/infini/register.py12
-rw-r--r--tests/test_core.py2
-rw-r--r--tests/test_generator.py22
-rw-r--r--tests/test_injector.py11
-rw-r--r--tests/test_loader.py2
-rw-r--r--tests/test_register.py4
10 files changed, 89 insertions, 28 deletions
diff --git a/src/infini/core.py b/src/infini/core.py
index 8fb46752..fe99f4b3 100644
--- a/src/infini/core.py
+++ b/src/infini/core.py
@@ -2,6 +2,7 @@ from infini.input import Input
from infini.interceptor import Interceptor
from infini.generator import TextGenerator
from infini.handler import Handler
+from infini.injector import Injector
from infini.output import Output
from infini.typing import Any, Generator, Union
from infini.exceptions import ValueError
@@ -12,6 +13,7 @@ class Core:
handler: Handler
generator: TextGenerator
interceptor: Interceptor
+ injector: Injector
def input(
self, input: Input
@@ -60,7 +62,7 @@ class Core:
yield output
def generate(self, output: Output) -> str:
- return self.generator.output(output)
+ return self.generator.output(output, self.injector)
def intercept(self, output_text: str) -> Generator[Union[str, Output], Any, None]:
return self.interceptor.output(output_text)
diff --git a/src/infini/generator.py b/src/infini/generator.py
index 53ca1a69..a8946949 100644
--- a/src/infini/generator.py
+++ b/src/infini/generator.py
@@ -1,6 +1,7 @@
from infini.output import Output
from infini.typing import Dict, Callable, Union
from infini.exceptions import UnknownEvent
+from infini.injector import Injector
from jinja2 import Template
@@ -12,10 +13,13 @@ class TextGenerator: # TODO 兼容多类型事件
self.events = {}
self.global_variables = {}
- def output(self, output: Output) -> str:
- assert output.type != "workflow", "Workflow 事件无法产出文本"
+ def output(self, output: Output, injector: Injector) -> str:
+ assert output.type == "text", "文本生成器应当传入类型为 'text' 的 Output 实例"
variables = self.global_variables.copy()
variables.update(output.variables)
+ for name, variable in variables.items():
+ if callable(variable):
+ variables[name] = injector.output(variable, output.variables)
return self.match(output).render(variables)
def match(self, output: Output) -> Template:
diff --git a/src/infini/injector.py b/src/infini/injector.py
new file mode 100644
index 00000000..b4c2bea4
--- /dev/null
+++ b/src/infini/injector.py
@@ -0,0 +1,40 @@
+from infini.typing import Callable, T, Optional, Dict, Any
+
+import inspect
+
+
+class Injector:
+ def __init__(self) -> None:
+ self.parameters: Dict[str, Any] = {}
+
+ def inject(
+ self, func: Callable[..., T], parameters: Optional[Dict[str, Any]] = None
+ ) -> Callable[[], T]:
+ signature = inspect.signature(func)
+ _parameters = {} if parameters is None else parameters
+ parameters = self.parameters.copy()
+ parameters.update(_parameters)
+ inject_params = {}
+ for param_name, param in signature.parameters.items():
+ default = None if param.default == inspect._empty else param.default
+ if param_name in parameters:
+ if not isinstance(parameters[param_name], param.annotation):
+ raise ValueError(
+ f"Parameter with name '{param_name}' has a mismatch type."
+ )
+ inject_params[param_name] = parameters[param_name]
+ else:
+ for parameter in parameters:
+ if isinstance(parameter, param.annotation):
+ inject_params[param_name] = parameter
+ break
+ else:
+ inject_params[param_name] = default
+ bound_args = signature.bind(**inject_params)
+ bound_args.apply_defaults()
+ return lambda: func(*bound_args.args, **bound_args.kwargs)
+
+ def output(
+ self, func: Callable[..., T], parameters: Optional[Dict[str, Any]] = None
+ ) -> T:
+ return self.inject(func, parameters)()
diff --git a/src/infini/loader.py b/src/infini/loader.py
index 4dbc392e..061ed8b9 100644
--- a/src/infini/loader.py
+++ b/src/infini/loader.py
@@ -2,6 +2,7 @@ from importlib.util import spec_from_file_location
from infini.core import Core
from infini.generator import TextGenerator
from infini.handler import Handler
+from infini.injector import Injector
from infini.interceptor import Interceptor
from infini.register import Register
from infini.typing import (
@@ -174,15 +175,18 @@ class Loader:
handler = Handler()
generator = TextGenerator()
interceptor = Interceptor()
+ injector = Injector()
self.inject_pre_interceptor(pre_interceptor)
self.inject_handler(handler)
self.inject_generator(generator)
self.inject_interceptor(interceptor)
+ self.inject_injector(injector)
core.pre_interceptor = pre_interceptor
core.handler = handler
core.generator = generator
core.interceptor = interceptor
+ core.injector = injector
def into_core(self) -> Core:
core = Core()
@@ -233,3 +237,11 @@ class Loader:
pre_interceptor = Interceptor()
self.inject_pre_interceptor(pre_interceptor)
return pre_interceptor
+
+ def inject_injector(self, injector: Injector):
+ injector.parameters = self.global_variables
+
+ def into_injector(self) -> Injector:
+ injector = Injector()
+ self.inject_injector(injector)
+ return injector
diff --git a/src/infini/register.py b/src/infini/register.py
index a2addc2b..0586ae7e 100644
--- a/src/infini/register.py
+++ b/src/infini/register.py
@@ -22,8 +22,8 @@ class Register:
def pre_interceptor(self, router: Union[Router, str], priority: int = 0):
def decorator(func):
@wraps(func)
- def wrapper(input: Input) -> Union[Input, Output]:
- return func(input)
+ def wrapper(*args, **kwargs) -> Union[Input, Output]:
+ return func(*args, **kwargs)
self.pre_interceptors.append(
{
@@ -39,8 +39,8 @@ class Register:
def handler(self, router: Union[Router, str], priority: int = 0):
def decorator(func):
@wraps(func)
- def wrapper(input: Input) -> Output:
- return func(input)
+ def wrapper(*args, **kwargs) -> Output:
+ return func(*args, **kwargs)
self.handlers.append(
{
@@ -73,8 +73,8 @@ class Register:
def interceptor(self, router: Union[Router, str], priority: int = 0):
def decorator(func):
@wraps(func)
- def wrapper(input: Input) -> Union[Input, Output]:
- return func(input)
+ def wrapper(*args, **kwargs) -> Union[Input, Output]:
+ return func(*args, **kwargs)
self.interceptors.append(
{
diff --git a/tests/test_core.py b/tests/test_core.py
index 11a8c57d..5f3f12f1 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -1,6 +1,7 @@
from infini.core import Core
from infini.generator import TextGenerator
from infini.handler import Handler
+from infini.injector import Injector
from infini.input import Input
from infini.interceptor import Interceptor
from infini.output import Output
@@ -60,6 +61,7 @@ def test_core():
core.interceptor = interceptor
core.pre_interceptor = interceptor
core.generator = generator
+ core.injector = Injector()
outputs = set()
for output in core.input(command_input):
diff --git a/tests/test_generator.py b/tests/test_generator.py
index 0eed5756..e796efc7 100644
--- a/tests/test_generator.py
+++ b/tests/test_generator.py
@@ -1,4 +1,5 @@
from infini.generator import TextGenerator
+from infini.injector import Injector
from infini.output import Output
@@ -8,7 +9,7 @@ def test_generator():
"test.event1": "Event1 文本",
}
generator.match(Output("text", "test.event1"))
- assert generator.output(Output("text", "test.event1")) == "Event1 文本"
+ assert generator.output(Output("text", "test.event1"), Injector()) == "Event1 文本"
def test_generator_with_var():
@@ -18,21 +19,8 @@ def test_generator_with_var():
}
assert (
- generator.output(Output("text", "test.event1", variables={"var": "变量测试"}))
+ generator.output(
+ Output("text", "test.event1", variables={"var": "变量测试"}), Injector()
+ )
== "Event1 文本: 变量测试"
)
-
-
-def test_generator_with_function():
- def add(a, b):
- return a + b
-
- generator = TextGenerator()
- generator.events = {
- "test.event": "{{ func(1, 2) }}",
- }
-
- assert (
- generator.output(Output("text", "test.event", variables={"func": add}))
- == "3"
- )
diff --git a/tests/test_injector.py b/tests/test_injector.py
new file mode 100644
index 00000000..0d320a2c
--- /dev/null
+++ b/tests/test_injector.py
@@ -0,0 +1,11 @@
+from infini.injector import Injector
+
+
+def test_injector():
+ def add(a: int, b: int = 0):
+ return a + b
+
+ injector = Injector()
+ injector.parameters = {"a": 12, "b": 20, "c": 0}
+ assert injector.inject(add)() == 32
+ assert injector.output(add) == 32
diff --git a/tests/test_loader.py b/tests/test_loader.py
index 439700e5..05716b60 100644
--- a/tests/test_loader.py
+++ b/tests/test_loader.py
@@ -19,7 +19,7 @@ def test_loader():
return Output("text", "block.snh", block=True)
register.regist_textevent("block.sxy", "不可直呼{{ sxy_id }}的ID")
- register.regist_textevent("block.snh", "不许撅{{ get_snh_id() }}")
+ register.regist_textevent("block.snh", "不许撅{{ get_snh_id }}")
register.regist_variable("sxy_id", "苏向夜")
diff --git a/tests/test_register.py b/tests/test_register.py
index 0ce8351b..ea857a15 100644
--- a/tests/test_register.py
+++ b/tests/test_register.py
@@ -1,6 +1,7 @@
from infini.core import Core
from infini.generator import TextGenerator
from infini.handler import Handler
+from infini.injector import Injector
from infini.input import Input
from infini.interceptor import Interceptor
from infini.output import Output
@@ -22,7 +23,7 @@ def test_register():
return Output("text", "block.snh", block=True)
register.regist_textevent("block.sxy", "不可直呼{{ sxy_id }}的ID")
- register.regist_textevent("block.snh", "不许撅{{ get_snh_id() }}")
+ register.regist_textevent("block.snh", "不许撅{{ get_snh_id }}")
register.regist_variable("sxy_id", "苏向夜")
@@ -49,6 +50,7 @@ def test_register():
core.handler = handler
core.generator = generator
core.interceptor = interceptor
+ core.injector = Injector()
for output in core.input(blocked_god_input):
assert output == "不可直呼苏向夜的ID"