metamessage 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- metamessage-0.1.0/MANIFEST.in +5 -0
- metamessage-0.1.0/PKG-INFO +354 -0
- metamessage-0.1.0/README.md +329 -0
- metamessage-0.1.0/examples/python/basic_encode_decode.py +50 -0
- metamessage-0.1.0/examples/python/dict_and_list.py +56 -0
- metamessage-0.1.0/examples/python/jsonc_roundtrip.py +70 -0
- metamessage-0.1.0/examples/python/mm_decorator.py +96 -0
- metamessage-0.1.0/examples/python/nested_structures.py +65 -0
- metamessage-0.1.0/examples/python/value_to_node_api.py +92 -0
- metamessage-0.1.0/metamessage/__init__.py +16 -0
- metamessage-0.1.0/metamessage/core/__init__.py +11 -0
- metamessage-0.1.0/metamessage/core/decoder.py +661 -0
- metamessage-0.1.0/metamessage/core/encoder.py +793 -0
- metamessage-0.1.0/metamessage/core/value_to_node.py +994 -0
- metamessage-0.1.0/metamessage/ir/__init__.py +9 -0
- metamessage-0.1.0/metamessage/ir/tag.py +851 -0
- metamessage-0.1.0/metamessage/ir/types.py +89 -0
- metamessage-0.1.0/metamessage/ir/validator.py +878 -0
- metamessage-0.1.0/metamessage/jsonc/__init__.py +11 -0
- metamessage-0.1.0/metamessage/jsonc/jsonc.py +604 -0
- metamessage-0.1.0/metamessage/py.typed +0 -0
- metamessage-0.1.0/metamessage.egg-info/PKG-INFO +354 -0
- metamessage-0.1.0/metamessage.egg-info/SOURCES.txt +29 -0
- metamessage-0.1.0/metamessage.egg-info/dependency_links.txt +1 -0
- metamessage-0.1.0/metamessage.egg-info/top_level.txt +1 -0
- metamessage-0.1.0/pyproject.toml +38 -0
- metamessage-0.1.0/setup.cfg +4 -0
- metamessage-0.1.0/tests/test_decoder.py +189 -0
- metamessage-0.1.0/tests/test_encoder.py +273 -0
- metamessage-0.1.0/tests/test_jsonc.py +195 -0
- metamessage-0.1.0/tests/test_value_to_node.py +320 -0
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: metamessage
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: High-performance binary message encoding library with schema tag support
|
|
5
|
+
Author: MetaMessage Contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/metamessage/metamessage
|
|
8
|
+
Project-URL: Repository, https://github.com/metamessage/metamessage
|
|
9
|
+
Keywords: serialization,binary,encoding,metamessage,schema
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
22
|
+
Classifier: Topic :: System :: Archiving :: Packaging
|
|
23
|
+
Requires-Python: >=3.7
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# MetaMessage
|
|
27
|
+
|
|
28
|
+
MetaMessage - 高性能二进制消息编码库,支持模式标记(schema tags)、JSONC 注释语法,以及 Python 装饰器驱动的序列化。
|
|
29
|
+
|
|
30
|
+
## 功能特性
|
|
31
|
+
|
|
32
|
+
- **二进制编码/解码** — 将 Python 值高效编码为紧凑二进制格式
|
|
33
|
+
- **`@mm` 装饰器** — 类似 Go 结构体标签的 Python 装饰器语法
|
|
34
|
+
- **JSONC 支持** — 解析带 `// mm:` 注释的 JSON 格式
|
|
35
|
+
- **Node 中间表示** — 通过 `value_to_node` / `node_to_value` 操作节点树
|
|
36
|
+
- **类型自动推断** — 根据 Python 类型注解自动推断 MetaMessage 类型
|
|
37
|
+
- **嵌套结构** — 支持字典、列表、类实例的递归转换
|
|
38
|
+
|
|
39
|
+
## 安装
|
|
40
|
+
|
|
41
|
+
### pip 安装
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install metamessage
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 版本要求
|
|
48
|
+
|
|
49
|
+
- Python 3.7 或更高版本
|
|
50
|
+
|
|
51
|
+
## 快速开始
|
|
52
|
+
|
|
53
|
+
### 基础编码/解码
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from metamessage import encode_from_value, decode_to_value
|
|
57
|
+
|
|
58
|
+
# 编码 Python 值 → 二进制
|
|
59
|
+
binary = encode_from_value({"name": "Alice", "age": 30})
|
|
60
|
+
print(f"Encoded: {len(binary)} bytes")
|
|
61
|
+
|
|
62
|
+
# 解码二进制 → Python 值
|
|
63
|
+
result = decode_to_value(binary)
|
|
64
|
+
print(result) # {'name': 'Alice', 'age': 30}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 字符串/数字/布尔值
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from metamessage import encode_from_value, decode_to_value
|
|
71
|
+
|
|
72
|
+
for val in ["hello", 42, 3.14, True, b"bytes"]:
|
|
73
|
+
binary = encode_from_value(val)
|
|
74
|
+
result = decode_to_value(binary)
|
|
75
|
+
print(f"{val!r} → {result!r}")
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## @mm 装饰器
|
|
79
|
+
|
|
80
|
+
`@mm` 装饰器为 Python 类添加 MetaMessage 模式信息,类似 Go 的结构体标签。
|
|
81
|
+
|
|
82
|
+
`mm` 支持两种用法:
|
|
83
|
+
- **类级装饰器**:`@mm(desc="...")` 放在 `class` 定义上方
|
|
84
|
+
- **字段级标记**:`field: type = mm(desc="...")` 作为字段默认值(推荐)
|
|
85
|
+
|
|
86
|
+
### 类级 + 字段级装饰器(推荐)
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
from metamessage import mm, ValueType, encode_from_value, decode_to_value
|
|
90
|
+
|
|
91
|
+
@mm(desc="User information")
|
|
92
|
+
class User:
|
|
93
|
+
id: int = mm(desc="User ID")
|
|
94
|
+
name: str = mm(desc="User name")
|
|
95
|
+
age: int = mm(desc="User age")
|
|
96
|
+
|
|
97
|
+
def __init__(self, id: int = 0, name: str = "", age: int = 0):
|
|
98
|
+
self.id = id
|
|
99
|
+
self.name = name
|
|
100
|
+
self.age = age
|
|
101
|
+
|
|
102
|
+
user = User(id=1, name="Alice", age=30)
|
|
103
|
+
binary = encode_from_value(user)
|
|
104
|
+
# binary -> {'id': 1, 'name': 'Alice', 'age': 30}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 带类型和约束
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
@mm(desc="Product")
|
|
111
|
+
class Product:
|
|
112
|
+
id: int = mm(desc="Product ID", type=ValueType.Int64, min=1)
|
|
113
|
+
name: str = mm(desc="Name", min=1, max=100)
|
|
114
|
+
price: float = mm(desc="Price", min=0.0, max=999999.99)
|
|
115
|
+
|
|
116
|
+
def __init__(self, id: int = 0, name: str = "", price: float = 0.0):
|
|
117
|
+
self.id = id
|
|
118
|
+
self.name = name
|
|
119
|
+
self.price = price
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 仅类级装饰器
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
@mm(desc="User information")
|
|
126
|
+
class User:
|
|
127
|
+
id: int
|
|
128
|
+
name: str
|
|
129
|
+
age: int
|
|
130
|
+
|
|
131
|
+
def __init__(self, id: int = 0, name: str = "", age: int = 0):
|
|
132
|
+
self.id = id
|
|
133
|
+
self.name = name
|
|
134
|
+
self.age = age
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### 字符串标签语法
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
@mm("desc=Product; type=i64")
|
|
141
|
+
class Product:
|
|
142
|
+
id: int
|
|
143
|
+
name: str
|
|
144
|
+
price: float
|
|
145
|
+
|
|
146
|
+
def __init__(self, id: int = 0, name: str = "", price: float = 0.0):
|
|
147
|
+
self.id = id
|
|
148
|
+
self.name = name
|
|
149
|
+
self.price = price
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Node 中间表示
|
|
153
|
+
|
|
154
|
+
MetaMessage 使用 Node 树作为中间表示(IR):
|
|
155
|
+
|
|
156
|
+
| 节点类型 | Python 类 | 描述 |
|
|
157
|
+
|---------|----------|------|
|
|
158
|
+
| `Val` | 值节点 | 存储标量值(字符串、数字、布尔等) |
|
|
159
|
+
| `Obj` | 对象节点 | 键值对集合(对应 dict / 类实例) |
|
|
160
|
+
| `Arr` | 数组节点 | 有序元素列表 |
|
|
161
|
+
|
|
162
|
+
### value_to_node / node_to_value
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
from metamessage import value_to_node, node_to_value
|
|
166
|
+
|
|
167
|
+
# Python 值 → Node 树
|
|
168
|
+
node = value_to_node({"x": 10, "y": 20})
|
|
169
|
+
|
|
170
|
+
# Node 树 → Python 值
|
|
171
|
+
result = node_to_value(node, dict)
|
|
172
|
+
print(result) # {'x': 10, 'y': 20}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### 手动构建 Node
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
from metamessage import Tag, ValueType, Obj, Arr, Val, Field, Encoder, Decoder
|
|
179
|
+
|
|
180
|
+
obj = Obj(
|
|
181
|
+
fields=[
|
|
182
|
+
Field(key="name", value=Val(data="John", text="John",
|
|
183
|
+
tag=Tag(type=ValueType.String))),
|
|
184
|
+
Field(key="age", value=Val(data=30, text="30",
|
|
185
|
+
tag=Tag(type=ValueType.Int))),
|
|
186
|
+
],
|
|
187
|
+
tag=Tag(name="person")
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
encoder = Encoder()
|
|
191
|
+
binary = encoder.encode(obj)
|
|
192
|
+
decoder = Decoder(binary)
|
|
193
|
+
result = decoder.decode()
|
|
194
|
+
print(result) # {'name': 'John', 'age': 30}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## JSONC 支持
|
|
198
|
+
|
|
199
|
+
JSONC 是带 `// mm:` 注释的 JSON 格式,用于声明模式标记:
|
|
200
|
+
|
|
201
|
+
### 解析 JSONC
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
from metamessage import parse_jsonc, to_jsonc
|
|
205
|
+
|
|
206
|
+
jsonc = """{
|
|
207
|
+
// mm: type=str; desc=姓名
|
|
208
|
+
"name": "Alice",
|
|
209
|
+
// mm: type=i; desc=年龄
|
|
210
|
+
"age": 30
|
|
211
|
+
}"""
|
|
212
|
+
|
|
213
|
+
node = parse_jsonc(jsonc)
|
|
214
|
+
for field in node.fields:
|
|
215
|
+
print(f"{field.key}: type={field.value.tag.type}, desc={field.value.tag.desc}")
|
|
216
|
+
|
|
217
|
+
# 转回 JSONC 字符串
|
|
218
|
+
output = to_jsonc(node)
|
|
219
|
+
print(output)
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### JSONC -> 二进制 -> 解码
|
|
223
|
+
|
|
224
|
+
```python
|
|
225
|
+
from metamessage import parse_jsonc, encode_from_value, decode_to_value
|
|
226
|
+
|
|
227
|
+
# 1. 解析 JSONC 获取 Node
|
|
228
|
+
node = parse_jsonc(jsonc_source)
|
|
229
|
+
|
|
230
|
+
# 2. 直接编码字典
|
|
231
|
+
binary = encode_from_value({"name": "Alice", "age": 30})
|
|
232
|
+
|
|
233
|
+
# 3. 解码
|
|
234
|
+
result = decode_to_value(binary)
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## 完整示例
|
|
238
|
+
|
|
239
|
+
查看 `examples/python/` 目录下的示例代码:
|
|
240
|
+
|
|
241
|
+
| 文件 | 说明 |
|
|
242
|
+
|------|------|
|
|
243
|
+
| `basic_encode_decode.py` | 基本编码/解码 |
|
|
244
|
+
| `dict_and_list.py` | 字典和列表操作 |
|
|
245
|
+
| `nested_structures.py` | 嵌套结构 |
|
|
246
|
+
| `mm_decorator.py` | @mm 装饰器使用 |
|
|
247
|
+
| `jsonc_roundtrip.py` | JSONC 完整流程 |
|
|
248
|
+
| `value_to_node_api.py` | Node API 使用 |
|
|
249
|
+
|
|
250
|
+
运行示例:
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
# 在 mm-py 目录下
|
|
254
|
+
PYTHONPATH=. python3 examples/python/basic_encode_decode.py
|
|
255
|
+
PYTHONPATH=. python3 examples/python/dict_and_list.py
|
|
256
|
+
PYTHONPATH=. python3 examples/python/nested_structures.py
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Tag 参数说明
|
|
260
|
+
|
|
261
|
+
### 基本参数
|
|
262
|
+
|
|
263
|
+
| 参数 | 类型 | 说明 |
|
|
264
|
+
|------|------|------|
|
|
265
|
+
| `type` | `ValueType` | 数据类型 |
|
|
266
|
+
| `desc` | `str` | 描述 |
|
|
267
|
+
| `nullable` | `bool` | 是否可空 |
|
|
268
|
+
| `allow_empty` | `bool` | 是否允许空值 |
|
|
269
|
+
| `default` | `str` | 默认值 |
|
|
270
|
+
| `raw` | `bool` | 是否原始模式 |
|
|
271
|
+
| `example` | `bool` | 是否为示例 |
|
|
272
|
+
| `unique` | `bool` | 是否唯一 |
|
|
273
|
+
|
|
274
|
+
### 约束参数
|
|
275
|
+
|
|
276
|
+
| 参数 | 适用类型 | 说明 |
|
|
277
|
+
|------|---------|------|
|
|
278
|
+
| `min` | int/float/bytes/string | 最小值/长度 |
|
|
279
|
+
| `max` | int/float/bytes/string | 最大值/长度 |
|
|
280
|
+
| `size` | array/bytes/string | 固定大小 |
|
|
281
|
+
| `pattern` | string | 正则表达式 |
|
|
282
|
+
| `enum` | enum | 枚举值列表(`"a\|b\|c"`) |
|
|
283
|
+
| `version` | uuid/ip | 版本号 |
|
|
284
|
+
| `mime` | bytes | MIME 类型 |
|
|
285
|
+
| `location` | datetime | 时区偏移(-12 ~ +14) |
|
|
286
|
+
|
|
287
|
+
### 子元素参数
|
|
288
|
+
|
|
289
|
+
| 参数 | 说明 |
|
|
290
|
+
|------|------|
|
|
291
|
+
| `child_type` | 子元素类型 |
|
|
292
|
+
| `child_desc` | 子元素描述 |
|
|
293
|
+
| `child_raw` | 子元素原始模式 |
|
|
294
|
+
| `child_nullable` | 子元素可空 |
|
|
295
|
+
| `child_allow_empty` | 子元素允许空值 |
|
|
296
|
+
| `child_unique` | 子元素唯一 |
|
|
297
|
+
| `child_default` | 子元素默认值 |
|
|
298
|
+
| `child_min` | 子元素最小值 |
|
|
299
|
+
| `child_max` | 子元素最大值 |
|
|
300
|
+
| `child_size` | 子元素大小 |
|
|
301
|
+
| `child_enum` | 子元素枚举 |
|
|
302
|
+
| `child_pattern` | 子元素模式 |
|
|
303
|
+
| `child_version` | 子元素版本 |
|
|
304
|
+
| `child_mime` | 子元素 MIME |
|
|
305
|
+
|
|
306
|
+
## API 参考
|
|
307
|
+
|
|
308
|
+
### 高层 API
|
|
309
|
+
|
|
310
|
+
| 函数 | 签名 | 说明 |
|
|
311
|
+
|------|------|------|
|
|
312
|
+
| `encode_from_value` | `(value: Any) -> bytes` | Python 值 → 二进制 |
|
|
313
|
+
| `decode_to_value` | `(data: bytes, target_type=Any) -> Any` | 二进制 → Python 值 |
|
|
314
|
+
| `value_to_node` | `(value: Any, tag=None, depth=0, path="") -> Node` | Python 值 → Node 树 |
|
|
315
|
+
| `node_to_value` | `(node: Node, target_type) -> Any` | Node 树 → Python 值 |
|
|
316
|
+
|
|
317
|
+
### 核心类
|
|
318
|
+
|
|
319
|
+
| 类 | 说明 |
|
|
320
|
+
|------|------|
|
|
321
|
+
| `Encoder` | 编码器:`Encoder().encode(node) -> bytes` |
|
|
322
|
+
| `Decoder` | 解码器:`Decoder(data).decode() -> Any` |
|
|
323
|
+
| `Tag` | 模式标记:类型、约束、描述等 |
|
|
324
|
+
| `ValueType` | 类型枚举:`String`, `Int`, `Float64`, `Bool` 等 |
|
|
325
|
+
|
|
326
|
+
### JSONC API
|
|
327
|
+
|
|
328
|
+
| 函数 | 签名 | 说明 |
|
|
329
|
+
|------|------|------|
|
|
330
|
+
| `parse_jsonc` | `(source: str) -> Node` | 解析 JSONC 字符串为 Node |
|
|
331
|
+
| `to_jsonc` | `(node: Node) -> str` | 将 Node 转回 JSONC 字符串 |
|
|
332
|
+
|
|
333
|
+
### 装饰器
|
|
334
|
+
|
|
335
|
+
| 装饰器 | 说明 |
|
|
336
|
+
|--------|------|
|
|
337
|
+
| `@mm(...)` | 类级标记装饰器 |
|
|
338
|
+
|
|
339
|
+
## 测试
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
# 运行主测试套件
|
|
343
|
+
python3 metamessage_test.py
|
|
344
|
+
|
|
345
|
+
# 运行分类测试
|
|
346
|
+
python3 tests/test_encoder.py
|
|
347
|
+
python3 tests/test_decoder.py
|
|
348
|
+
python3 tests/test_jsonc.py
|
|
349
|
+
python3 tests/test_value_to_node.py
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
## 许可
|
|
353
|
+
|
|
354
|
+
MIT
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
# MetaMessage
|
|
2
|
+
|
|
3
|
+
MetaMessage - 高性能二进制消息编码库,支持模式标记(schema tags)、JSONC 注释语法,以及 Python 装饰器驱动的序列化。
|
|
4
|
+
|
|
5
|
+
## 功能特性
|
|
6
|
+
|
|
7
|
+
- **二进制编码/解码** — 将 Python 值高效编码为紧凑二进制格式
|
|
8
|
+
- **`@mm` 装饰器** — 类似 Go 结构体标签的 Python 装饰器语法
|
|
9
|
+
- **JSONC 支持** — 解析带 `// mm:` 注释的 JSON 格式
|
|
10
|
+
- **Node 中间表示** — 通过 `value_to_node` / `node_to_value` 操作节点树
|
|
11
|
+
- **类型自动推断** — 根据 Python 类型注解自动推断 MetaMessage 类型
|
|
12
|
+
- **嵌套结构** — 支持字典、列表、类实例的递归转换
|
|
13
|
+
|
|
14
|
+
## 安装
|
|
15
|
+
|
|
16
|
+
### pip 安装
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install metamessage
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### 版本要求
|
|
23
|
+
|
|
24
|
+
- Python 3.7 或更高版本
|
|
25
|
+
|
|
26
|
+
## 快速开始
|
|
27
|
+
|
|
28
|
+
### 基础编码/解码
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
from metamessage import encode_from_value, decode_to_value
|
|
32
|
+
|
|
33
|
+
# 编码 Python 值 → 二进制
|
|
34
|
+
binary = encode_from_value({"name": "Alice", "age": 30})
|
|
35
|
+
print(f"Encoded: {len(binary)} bytes")
|
|
36
|
+
|
|
37
|
+
# 解码二进制 → Python 值
|
|
38
|
+
result = decode_to_value(binary)
|
|
39
|
+
print(result) # {'name': 'Alice', 'age': 30}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 字符串/数字/布尔值
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from metamessage import encode_from_value, decode_to_value
|
|
46
|
+
|
|
47
|
+
for val in ["hello", 42, 3.14, True, b"bytes"]:
|
|
48
|
+
binary = encode_from_value(val)
|
|
49
|
+
result = decode_to_value(binary)
|
|
50
|
+
print(f"{val!r} → {result!r}")
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## @mm 装饰器
|
|
54
|
+
|
|
55
|
+
`@mm` 装饰器为 Python 类添加 MetaMessage 模式信息,类似 Go 的结构体标签。
|
|
56
|
+
|
|
57
|
+
`mm` 支持两种用法:
|
|
58
|
+
- **类级装饰器**:`@mm(desc="...")` 放在 `class` 定义上方
|
|
59
|
+
- **字段级标记**:`field: type = mm(desc="...")` 作为字段默认值(推荐)
|
|
60
|
+
|
|
61
|
+
### 类级 + 字段级装饰器(推荐)
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from metamessage import mm, ValueType, encode_from_value, decode_to_value
|
|
65
|
+
|
|
66
|
+
@mm(desc="User information")
|
|
67
|
+
class User:
|
|
68
|
+
id: int = mm(desc="User ID")
|
|
69
|
+
name: str = mm(desc="User name")
|
|
70
|
+
age: int = mm(desc="User age")
|
|
71
|
+
|
|
72
|
+
def __init__(self, id: int = 0, name: str = "", age: int = 0):
|
|
73
|
+
self.id = id
|
|
74
|
+
self.name = name
|
|
75
|
+
self.age = age
|
|
76
|
+
|
|
77
|
+
user = User(id=1, name="Alice", age=30)
|
|
78
|
+
binary = encode_from_value(user)
|
|
79
|
+
# binary -> {'id': 1, 'name': 'Alice', 'age': 30}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 带类型和约束
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
@mm(desc="Product")
|
|
86
|
+
class Product:
|
|
87
|
+
id: int = mm(desc="Product ID", type=ValueType.Int64, min=1)
|
|
88
|
+
name: str = mm(desc="Name", min=1, max=100)
|
|
89
|
+
price: float = mm(desc="Price", min=0.0, max=999999.99)
|
|
90
|
+
|
|
91
|
+
def __init__(self, id: int = 0, name: str = "", price: float = 0.0):
|
|
92
|
+
self.id = id
|
|
93
|
+
self.name = name
|
|
94
|
+
self.price = price
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 仅类级装饰器
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
@mm(desc="User information")
|
|
101
|
+
class User:
|
|
102
|
+
id: int
|
|
103
|
+
name: str
|
|
104
|
+
age: int
|
|
105
|
+
|
|
106
|
+
def __init__(self, id: int = 0, name: str = "", age: int = 0):
|
|
107
|
+
self.id = id
|
|
108
|
+
self.name = name
|
|
109
|
+
self.age = age
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 字符串标签语法
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
@mm("desc=Product; type=i64")
|
|
116
|
+
class Product:
|
|
117
|
+
id: int
|
|
118
|
+
name: str
|
|
119
|
+
price: float
|
|
120
|
+
|
|
121
|
+
def __init__(self, id: int = 0, name: str = "", price: float = 0.0):
|
|
122
|
+
self.id = id
|
|
123
|
+
self.name = name
|
|
124
|
+
self.price = price
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Node 中间表示
|
|
128
|
+
|
|
129
|
+
MetaMessage 使用 Node 树作为中间表示(IR):
|
|
130
|
+
|
|
131
|
+
| 节点类型 | Python 类 | 描述 |
|
|
132
|
+
|---------|----------|------|
|
|
133
|
+
| `Val` | 值节点 | 存储标量值(字符串、数字、布尔等) |
|
|
134
|
+
| `Obj` | 对象节点 | 键值对集合(对应 dict / 类实例) |
|
|
135
|
+
| `Arr` | 数组节点 | 有序元素列表 |
|
|
136
|
+
|
|
137
|
+
### value_to_node / node_to_value
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
from metamessage import value_to_node, node_to_value
|
|
141
|
+
|
|
142
|
+
# Python 值 → Node 树
|
|
143
|
+
node = value_to_node({"x": 10, "y": 20})
|
|
144
|
+
|
|
145
|
+
# Node 树 → Python 值
|
|
146
|
+
result = node_to_value(node, dict)
|
|
147
|
+
print(result) # {'x': 10, 'y': 20}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### 手动构建 Node
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
from metamessage import Tag, ValueType, Obj, Arr, Val, Field, Encoder, Decoder
|
|
154
|
+
|
|
155
|
+
obj = Obj(
|
|
156
|
+
fields=[
|
|
157
|
+
Field(key="name", value=Val(data="John", text="John",
|
|
158
|
+
tag=Tag(type=ValueType.String))),
|
|
159
|
+
Field(key="age", value=Val(data=30, text="30",
|
|
160
|
+
tag=Tag(type=ValueType.Int))),
|
|
161
|
+
],
|
|
162
|
+
tag=Tag(name="person")
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
encoder = Encoder()
|
|
166
|
+
binary = encoder.encode(obj)
|
|
167
|
+
decoder = Decoder(binary)
|
|
168
|
+
result = decoder.decode()
|
|
169
|
+
print(result) # {'name': 'John', 'age': 30}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## JSONC 支持
|
|
173
|
+
|
|
174
|
+
JSONC 是带 `// mm:` 注释的 JSON 格式,用于声明模式标记:
|
|
175
|
+
|
|
176
|
+
### 解析 JSONC
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
from metamessage import parse_jsonc, to_jsonc
|
|
180
|
+
|
|
181
|
+
jsonc = """{
|
|
182
|
+
// mm: type=str; desc=姓名
|
|
183
|
+
"name": "Alice",
|
|
184
|
+
// mm: type=i; desc=年龄
|
|
185
|
+
"age": 30
|
|
186
|
+
}"""
|
|
187
|
+
|
|
188
|
+
node = parse_jsonc(jsonc)
|
|
189
|
+
for field in node.fields:
|
|
190
|
+
print(f"{field.key}: type={field.value.tag.type}, desc={field.value.tag.desc}")
|
|
191
|
+
|
|
192
|
+
# 转回 JSONC 字符串
|
|
193
|
+
output = to_jsonc(node)
|
|
194
|
+
print(output)
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### JSONC -> 二进制 -> 解码
|
|
198
|
+
|
|
199
|
+
```python
|
|
200
|
+
from metamessage import parse_jsonc, encode_from_value, decode_to_value
|
|
201
|
+
|
|
202
|
+
# 1. 解析 JSONC 获取 Node
|
|
203
|
+
node = parse_jsonc(jsonc_source)
|
|
204
|
+
|
|
205
|
+
# 2. 直接编码字典
|
|
206
|
+
binary = encode_from_value({"name": "Alice", "age": 30})
|
|
207
|
+
|
|
208
|
+
# 3. 解码
|
|
209
|
+
result = decode_to_value(binary)
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## 完整示例
|
|
213
|
+
|
|
214
|
+
查看 `examples/python/` 目录下的示例代码:
|
|
215
|
+
|
|
216
|
+
| 文件 | 说明 |
|
|
217
|
+
|------|------|
|
|
218
|
+
| `basic_encode_decode.py` | 基本编码/解码 |
|
|
219
|
+
| `dict_and_list.py` | 字典和列表操作 |
|
|
220
|
+
| `nested_structures.py` | 嵌套结构 |
|
|
221
|
+
| `mm_decorator.py` | @mm 装饰器使用 |
|
|
222
|
+
| `jsonc_roundtrip.py` | JSONC 完整流程 |
|
|
223
|
+
| `value_to_node_api.py` | Node API 使用 |
|
|
224
|
+
|
|
225
|
+
运行示例:
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
# 在 mm-py 目录下
|
|
229
|
+
PYTHONPATH=. python3 examples/python/basic_encode_decode.py
|
|
230
|
+
PYTHONPATH=. python3 examples/python/dict_and_list.py
|
|
231
|
+
PYTHONPATH=. python3 examples/python/nested_structures.py
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Tag 参数说明
|
|
235
|
+
|
|
236
|
+
### 基本参数
|
|
237
|
+
|
|
238
|
+
| 参数 | 类型 | 说明 |
|
|
239
|
+
|------|------|------|
|
|
240
|
+
| `type` | `ValueType` | 数据类型 |
|
|
241
|
+
| `desc` | `str` | 描述 |
|
|
242
|
+
| `nullable` | `bool` | 是否可空 |
|
|
243
|
+
| `allow_empty` | `bool` | 是否允许空值 |
|
|
244
|
+
| `default` | `str` | 默认值 |
|
|
245
|
+
| `raw` | `bool` | 是否原始模式 |
|
|
246
|
+
| `example` | `bool` | 是否为示例 |
|
|
247
|
+
| `unique` | `bool` | 是否唯一 |
|
|
248
|
+
|
|
249
|
+
### 约束参数
|
|
250
|
+
|
|
251
|
+
| 参数 | 适用类型 | 说明 |
|
|
252
|
+
|------|---------|------|
|
|
253
|
+
| `min` | int/float/bytes/string | 最小值/长度 |
|
|
254
|
+
| `max` | int/float/bytes/string | 最大值/长度 |
|
|
255
|
+
| `size` | array/bytes/string | 固定大小 |
|
|
256
|
+
| `pattern` | string | 正则表达式 |
|
|
257
|
+
| `enum` | enum | 枚举值列表(`"a\|b\|c"`) |
|
|
258
|
+
| `version` | uuid/ip | 版本号 |
|
|
259
|
+
| `mime` | bytes | MIME 类型 |
|
|
260
|
+
| `location` | datetime | 时区偏移(-12 ~ +14) |
|
|
261
|
+
|
|
262
|
+
### 子元素参数
|
|
263
|
+
|
|
264
|
+
| 参数 | 说明 |
|
|
265
|
+
|------|------|
|
|
266
|
+
| `child_type` | 子元素类型 |
|
|
267
|
+
| `child_desc` | 子元素描述 |
|
|
268
|
+
| `child_raw` | 子元素原始模式 |
|
|
269
|
+
| `child_nullable` | 子元素可空 |
|
|
270
|
+
| `child_allow_empty` | 子元素允许空值 |
|
|
271
|
+
| `child_unique` | 子元素唯一 |
|
|
272
|
+
| `child_default` | 子元素默认值 |
|
|
273
|
+
| `child_min` | 子元素最小值 |
|
|
274
|
+
| `child_max` | 子元素最大值 |
|
|
275
|
+
| `child_size` | 子元素大小 |
|
|
276
|
+
| `child_enum` | 子元素枚举 |
|
|
277
|
+
| `child_pattern` | 子元素模式 |
|
|
278
|
+
| `child_version` | 子元素版本 |
|
|
279
|
+
| `child_mime` | 子元素 MIME |
|
|
280
|
+
|
|
281
|
+
## API 参考
|
|
282
|
+
|
|
283
|
+
### 高层 API
|
|
284
|
+
|
|
285
|
+
| 函数 | 签名 | 说明 |
|
|
286
|
+
|------|------|------|
|
|
287
|
+
| `encode_from_value` | `(value: Any) -> bytes` | Python 值 → 二进制 |
|
|
288
|
+
| `decode_to_value` | `(data: bytes, target_type=Any) -> Any` | 二进制 → Python 值 |
|
|
289
|
+
| `value_to_node` | `(value: Any, tag=None, depth=0, path="") -> Node` | Python 值 → Node 树 |
|
|
290
|
+
| `node_to_value` | `(node: Node, target_type) -> Any` | Node 树 → Python 值 |
|
|
291
|
+
|
|
292
|
+
### 核心类
|
|
293
|
+
|
|
294
|
+
| 类 | 说明 |
|
|
295
|
+
|------|------|
|
|
296
|
+
| `Encoder` | 编码器:`Encoder().encode(node) -> bytes` |
|
|
297
|
+
| `Decoder` | 解码器:`Decoder(data).decode() -> Any` |
|
|
298
|
+
| `Tag` | 模式标记:类型、约束、描述等 |
|
|
299
|
+
| `ValueType` | 类型枚举:`String`, `Int`, `Float64`, `Bool` 等 |
|
|
300
|
+
|
|
301
|
+
### JSONC API
|
|
302
|
+
|
|
303
|
+
| 函数 | 签名 | 说明 |
|
|
304
|
+
|------|------|------|
|
|
305
|
+
| `parse_jsonc` | `(source: str) -> Node` | 解析 JSONC 字符串为 Node |
|
|
306
|
+
| `to_jsonc` | `(node: Node) -> str` | 将 Node 转回 JSONC 字符串 |
|
|
307
|
+
|
|
308
|
+
### 装饰器
|
|
309
|
+
|
|
310
|
+
| 装饰器 | 说明 |
|
|
311
|
+
|--------|------|
|
|
312
|
+
| `@mm(...)` | 类级标记装饰器 |
|
|
313
|
+
|
|
314
|
+
## 测试
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
# 运行主测试套件
|
|
318
|
+
python3 metamessage_test.py
|
|
319
|
+
|
|
320
|
+
# 运行分类测试
|
|
321
|
+
python3 tests/test_encoder.py
|
|
322
|
+
python3 tests/test_decoder.py
|
|
323
|
+
python3 tests/test_jsonc.py
|
|
324
|
+
python3 tests/test_value_to_node.py
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## 许可
|
|
328
|
+
|
|
329
|
+
MIT
|