CSM-Python-Arguments
CSM(Communicable State Machine)参数字符串的 Python 编解码实现。
CSM 中所有参数与返回值都以字符串承载,背后可以是任意 LabVIEW 数据类型。本项目提供与 LabVIEW 侧完全一致的编解码能力:既能把 Python 值编码成 CSM 参数字符串,也能把 LabVIEW 产生的参数字符串还原为 Python 值。
支持范围
| 编码方案 | 说明 |
|---|---|
SAFESTR |
安全字符串:把 CSM 关键字转义为 %Hex,避免破坏消息解析 |
ERRSTR |
LabVIEW 错误簇:<ErrStr>[Error: code] description |
HEXSTR |
任意数据:variant 内存映像的十六进制串 |
| CSM API String | 无标记的纯文本参数:全部基本类型、数组、簇与波形 |
数据类型覆盖:String、Path、Tag、Refnum、Boolean、Integer(I8…U64)、Float(SGL/DBL)、
Complex(CSG/CDB)、Timestamp、Enum、Array(多维)、Cluster(NamedTuple)、Waveform、Error,
以及经 HEXSTR 承载的其他类型(含嵌套 variant)。簇在 Python 侧一律以 NamedTuple 表示,
各类型与 Python 表示的对应关系见「数据类型对应」。
不在支持范围:扩展精度浮点 EXT(0x0B)、扩展精度复数 CXT(0x0E)与带物理单位的数值
(0x19..0x1E)。CSM API String 的 Float / Complex 只定义 SGL / DBL 与 CSG / CDB。这些类型码
可被类型表识别,编码与解码都拒绝,variant 层同样不实现。
两个类型可以编解码但无法与 LabVIEW 2026 经 HEXSTR 互操作:Refnum(0x70)与 uint64
枚举(0x18)。实测证据见 labview/README.md。
数据类型对应
LabVIEW 类型与 Python 表示的对应关系。同一份对应关系在 API String 与 HEXSTR 两层都成立,
类型码与二进制布局见 docs/variant-binary-format.md。
| LabVIEW 类型 | Python 表示 | Python 值示例 | API String 文本 |
|---|---|---|---|
Null(空 variant) |
None |
None |
无(只经 HEXSTR) |
Boolean |
bool |
True |
TRUE |
I8 / I16 / I32 / I64 |
int |
-128 |
-128 |
U8 / U16 / U32 / U64 |
int |
255 |
255 |
SGL / DBL |
float |
1.5 |
1.5 |
CSG / CDB |
complex |
1.5-2.5j |
1.5-2.5i |
String |
str |
'a,b;c' |
a%2Cb%3Bc |
Path |
str |
'C:\temp\a.txt' |
C:\temp\a.txt |
Pict |
str |
'AB' |
AB |
Refnum |
int(variant 中的引用号) |
3 |
设备名文本,如 VISA::INSTR |
Enum |
int(项序) |
1 |
项名文本,如 beta |
Timestamp |
datatypes.LVTimestamp |
LVTimestamp(1, 0) |
1904-01-01T00:00:01.000Z |
Array |
list |
[[1.0, 2.0], [3.0, 4.0]] |
[1,2;3,4] |
Cluster |
NamedTuple |
{'x': 1, 'y': 2} |
{x:1;y:2} |
Error |
datatypes.LVError(簇 {status, code, source}) |
LVError(True, -1, 'boom') |
{status:TRUE;code:-1;source:boom} |
Waveform |
datatypes.LVWaveform |
LVWaveform(t0=LVTimestamp(1, 0), dt=0.5, Y=[1.0]) |
{t0:1904-01-01T00:00:01.000Z;dt:500m;Y:[1];…} |
Variant |
bytes(内层完整 blob) |
EMPTY_VARIANT_BLOB |
无(只经 HEXSTR) |
from csm.arguments import HexStr, api_string, lv_variant
from csm.arguments.datatypes import LVError, LVTimestamp
error = LVError(True, -1, "boom")
# 簇以 NamedTuple、dict 或同字段个数的序列表示。HEXSTR 与 API String 共用同一份类型
api_string.convert_data_to_api_string_arguments(error)
# '{status:TRUE;code:-1;source:boom}'
HexStr.convert_data_to_hexstr(error)
# '<HEXSTR>2600800000000004000C40210673746174757300000B40030004...'
HexStr.convert_hexstr_to_data(HexStr.convert_data_to_hexstr(error))
# Cluster(status=True, code=-1, source='boom')
# API String 不带类型信息,解码要给出目标类型
api_string.convert_api_string_arguments_to_data(
"[1,2;3,4]", lv_variant.array_of(lv_variant.DBL, 2))
# [[1.0, 2.0], [3.0, 4.0]]
api_string.convert_api_string_arguments_to_data("beta", lv_variant.enum_of(["alpha", "beta"]))
# 1
# 时间戳:Python 侧是 LVTimestamp(秒 + 2^-64 秒小数),缺省文本为 RFC3339
api_string.convert_data_to_api_string_arguments(LVTimestamp(1, 0), lv_variant.TimestampType)
# '1904-01-01T00:00:01.000Z'
解析边界
HEXSTR 的载荷来自 LabVIEW,可能是截断的或被人为构造的。解析侧对每一次读取都校验范围、
长度与计数,越界、负长度、过大的计数、违反后序排列的记录引用、过深的嵌套一律抛
ArgumentFormatError(继承 ValueError),不会读到界外,也不会因为声明的计数过大而长时间
循环。详见 docs/variant-binary-format.md 的“解析边界”。
ERRSTR 解码与 CSM - Convert Argument to Error.vi 一致,不报错:头部 [Kind: code]
缺失或不合法时,整段文本作为 source、code 取 0、status 取 True。
编码边界
编码侧复用同一套上限与校验:嵌套超过 64 层、波形 attributes 或变体值不是完整合法的
variant blob、取值与声明类型不符(整数越界、簇字段个数不符等)都以 ArgumentFormatError
拒绝。因此“编码成功”隐含“同一类型可以解码”。详见 docs/python-api.md 的“输入校验”。
安装
pip install csm-arguments
源码安装:
git clone https://github.com/NEVSTOP-LAB/CSM-Python-Arguments.git
cd CSM-Python-Arguments
pip install -e .
最低支持 Python 3.8,运行时仅依赖标准库。
快速开始
from csm.arguments import ErrorStr, HexStr, SafeStr
from csm.arguments.datatypes import LVError
# SAFESTR:字符串含 CSM 关键字时自动转义并加标记
SafeStr.make_string_arguments_safe("a,b;c") # '<SafeStr>a%2Cb%3Bc'
SafeStr.revert_arguments_safe_string("<SafeStr>a%2Cb%3Bc") # 'a,b;c'
# ERRSTR:错误簇与可读参数互转
ErrorStr.convert_error_to_argument(LVError(True, -1, "文件未找到"))
# '<ErrStr>[Error: -1]文件未找到'
ErrorStr.convert_argument_to_error("<ErrStr>[Error: -1]文件未找到")
# LVError(status=True, code=-1, source='文件未找到')
# HEXSTR:任意 Python 值 <-> LabVIEW variant 十六进制串
HexStr.convert_data_to_hexstr([1, 2, 3])
# '<HEXSTR>2600800000000002000500030000...'
HexStr.convert_hexstr_to_data(HexStr.convert_data_to_hexstr([1, 2, 3]))
# [1, 2, 3]
按类型精确编解码:
from csm.arguments import HexStr, lv_variant
from csm.arguments.datatypes import LVError
value = LVError(True, -1, "src")
blob_argument = HexStr.convert_data_to_hexstr(value, lv_variant.infer(value))
value, lvtype, attributes = HexStr.convert_hexstr_to_data(blob_argument, with_type=True)
CSM API String(无类型标记的纯文本参数):
from csm.arguments import api_string, lv_variant
api_string.convert_data_to_api_string_arguments([1, 2, 3]) # '[1,2,3]'
api_string.convert_data_to_api_string_arguments(1.5, lv_variant.DBL) # '1.5'
api_string.convert_data_to_api_string_arguments(1e20, lv_variant.DBL) # '100E'
api_string.convert_api_string_arguments_to_data("0x1234", lv_variant.I32) # 4660
api_string.convert_api_string_arguments_to_data("1.23k", lv_variant.DBL) # 1230.0
api_string.convert_api_string_arguments_to_data(
"beta", lv_variant.enum_of(["alpha", "beta", "gamma"], lv_variant.TYPE_ENUM_U8))
# 1
与 CSM 编解码 API 的对应
编解码函数一律按 LabVIEW VI 命名,一一对应,没有别名:
| Python | LabVIEW |
|---|---|
SafeStr.make_string_arguments_safe |
CSM - Make String Arguments Safe.vi |
SafeStr.revert_arguments_safe_string |
CSM - Revert Arguments-Safe String.vi |
ErrorStr.convert_error_to_argument |
CSM - Convert Error to Argument.vi |
ErrorStr.convert_argument_to_error |
CSM - Convert Argument to Error.vi |
HexStr.convert_data_to_hexstr |
CSM - Convert Data to HexStr.vi |
HexStr.convert_hexstr_to_data |
CSM - Convert HexStr to Data.vi |
protocol.argument_type |
CSM - Argument Type.vi |
api_string.convert_data_to_api_string_arguments |
Data To API String Arguments.vi |
api_string.convert_api_string_arguments_to_data |
Convert API String Arguments to Data(variant).vi |
各类型模块的 data_to_api_string / api_string_to_data 是两个多态 VI 在该类型下的实例。
形参名同样取自 VI 端子(Argument String、Safe Argument String、Ignore Argument Type、
Force Convert、HEX String、Error、Argument、data、String)。VI 的 Type 端子
因与内置名 type 冲突,在 Python 侧记为 lvtype。VI 的 error in / error out 由异常承载。
文件布局
| 路径 | 职责 |
|---|---|
src/csm/arguments/ErrorStr.py |
错误簇参数(ERRSTR)编解码 |
src/csm/arguments/HexStr.py |
variant 二进制参数(HEXSTR)编解码 |
src/csm/arguments/SafeStr.py |
安全字符串(SAFESTR)编解码 |
src/csm/arguments/api_string.py |
CSM API String 文本编解码 |
src/csm/arguments/datatypes.py |
LabVIEW 值对象的 Python 表示 |
src/csm/arguments/errors.py |
ArgumentFormatError |
src/csm/arguments/lv_variant.py |
LabVIEW variant 二进制格式编解码 |
src/csm/arguments/protocol.py |
参数编码类型标记 |
tests/ |
pytest 测试,含 LabVIEW 实测样本回归基线 |
docs/ |
格式说明、接口文档与验证记录 |
.github/workflows/ |
测试矩阵与 PyPI / TestPyPI 发布工作流 |
labview/ |
LabVIEW 验证探针的生成脚本、输入规格与实测记录 |
文档索引
| 文档 | 内容 |
|---|---|
docs/argument-encoding.md |
编码方案与 CSM API String 文本格式 |
docs/variant-binary-format.md |
LabVIEW variant 二进制结构 |
docs/python-api.md |
Python 接口说明 |
docs/labview-verification.md |
LabVIEW 侧验证方法与结果 |
CONTRIBUTING.md |
环境、测试与扩展方式 |
许可
MIT,见 LICENSE。
Metadata
Release files for csm-arguments 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| csm_arguments-0.1.1.tar.gz | 82.5 kB | Without provenance | Details for csm_arguments-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| csm_arguments-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for csm_arguments-0.1.1-py3-none-any.whl |
Total release size: 148.6 kB
Release files / csm_arguments-0.1.1.tar.gz
| Download URL | csm_arguments-0.1.1.tar.gz |
|---|---|
| Size | 82.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
125d01631c078e01c4aad9e00893605f2b4860013153859e3b740a6bc365835a
|
|
BLAKE2b-256 checksum How to use checksums |
a2d79b678a253ea63327a596724f8561e15bf1b436e55b39b840ba3eb6a77619
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / csm_arguments-0.1.1-py3-none-any.whl
| Download URL | csm_arguments-0.1.1-py3-none-any.whl |
|---|---|
| Size | 66.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3c4f9283c0ba9adae4772e87049c9bf054fe71f77cd2f6af33ef5e00d313f3b5
|
|
BLAKE2b-256 checksum How to use checksums |
e5350d0e11304c874806d5afe945fb0a660f83b7cf1c12c8161f823ebcbe51c8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for csm-arguments 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.