feat: 添加 []byte ↔ bytes 支持(base64 透明编解码)

- Python 侧:_decode_bytes_args 根据函数注解自动解码入参,_bytes_encode 自动编码 bytes 返回值
- _cast 支持 bytes 类型(call_go[bytes] 返回值解码)
- 流式输出同步支持 chan []byte(每个 chunk 独立编解码)
- example/worker.py 新增 bytes_reverse / bytes_concat / bytes_chunks 示例
- example/main.go 新增对应演示用例
- README 补充类型表 []byte 行及完整使用章节
This commit is contained in:
2026-05-19 20:07:31 +08:00
parent e6a61cc1ee
commit 57775a33ec
4 changed files with 128 additions and 2 deletions

View File

@@ -36,6 +36,7 @@ gobridge - Python 端库,配合 Go 侧 gobridge 使用
run()
"""
import base64
import ctypes
import dataclasses
import inspect
@@ -91,15 +92,39 @@ def _cast(t: type, value: Any) -> Any:
"""将 Go 返回的 JSON 值转换为指定类型。
- dataclass用 dict 字段构造实例
- bytesbase64 str → bytes对应 Go []byte
- 其余类型JSON 已经是正确的 Python 原生类型,直接返回
"""
if value is None or t is type(None):
return value
if t is bytes and isinstance(value, str):
return base64.b64decode(value)
if dataclasses.is_dataclass(t) and not isinstance(value, t) and isinstance(value, dict):
return t(**value)
return value
def _bytes_encode(v: Any) -> Any:
"""bytes → base64 str使 json.dumps 可序列化(对应 Go []byte"""
if isinstance(v, bytes):
return base64.b64encode(v).decode()
return v
def _decode_bytes_args(fn, args: list) -> list:
"""根据函数类型注解将 base64 str 参数解码为 bytes对应 Go []byte 入参)。"""
try:
params = list(inspect.signature(fn).parameters.values())
for i, param in enumerate(params):
if i >= len(args):
break
if param.annotation is bytes and isinstance(args[i], str):
args[i] = base64.b64decode(args[i])
except Exception:
pass
return args
class _CallGoType:
"""实现 call_go 和 call_go[Type] 两种调用形式。
@@ -305,16 +330,17 @@ def _dispatch(mux: _ConnMux, msg: dict):
args[stream_arg_idx] = chunk_iter_instance
try:
args = _decode_bytes_args(fn, args)
result = fn(*args)
if inspect.isgenerator(result):
try:
for item in result:
mux.write({"id": msg_id, "type": "chunk", "data": item})
mux.write({"id": msg_id, "type": "chunk", "data": _bytes_encode(item)})
finally:
mux.write({"id": msg_id, "type": "end"})
else:
mux.write({"id": msg_id, "type": "result", "data": result})
mux.write({"id": msg_id, "type": "result", "data": _bytes_encode(result)})
except InterruptedError:
pass # ctx 取消,连接已被 Go 侧关闭,无需回写