Doramagic 项目包 · 项目说明书
nimic 项目
Nimic 是一个纯 Python 模块,通过使用 Python 的子集(领域特定语言)来编写 AOT 可编译代码,无需离开 Python 即可获得 C 级别的性能,基于内置的 ctypes 模块实现。
Project Overview and Module Architecture
Nimic 是一个纯 Python 模块,提供一套受限的 Python 子集(DSL):写出来的代码既能直接在 CPython 解释器中运行,又能通过转译得到等价的 Nim 源码,进而借助 Nim 编译器获得接近 C 的性能。整个运行时建立在标准库 ctypes 之上,无需任何 C 扩展或外部二进制。
继续阅读本节完整说明和来源证据。
项目目标与设计理念
Nimic 是一个纯 Python 模块,提供一套受限的 Python 子集(DSL):写出来的代码既能直接在 CPython 解释器中运行,又能通过转译得到等价的 Nim 源码,进而借助 Nim 编译器获得接近 C 的性能。整个运行时建立在标准库 ctypes 之上,无需任何 C 扩展或外部二进制。
核心设计原则是"一份源码,两套语义"——每一个 DSL 约定都同时承担两层含义:解释执行时的 Python 行为 + 转译为 Nim 后的语义。例如 with let: 在 Python 中只是一个无操作的上下文标记,转译后却成为真正的 let 作用域限定符;而 mut @ 注解在运行时被忽略,转译时则变成 Nim 的 var 参数。资料来源:README.md:31-58、README.md:65-78。
模块架构总览
仓库被组织成"用户代码 → 公共 API → 核心实现 → 支撑资源"四层。ntypes.py 把类型系统的全部符号连同 Nim 关键字/内建(const/let/var、sizeof、cast[T]、@、ref、ptr 等)合并成单一对外 API;__init__.py 中的 nimp() 则是脚本式入口,负责从源码中提取 # /// nimic 块并触发转译。资料来源:src/nimic/ntypes.py:36-56、src/nimic/__init__.py:22-37。
flowchart TB
subgraph User["用户代码层"]
EX["examples/*.py<br/>使用 nimic DSL 的脚本"]
end
subgraph Public["公共 API 层"]
NT["src/nimic/ntypes.py<br/>关键字、别名、re-export"]
INIT["src/nimic/__init__.py<br/>nimp() 入口"]
end
subgraph Core["核心实现层"]
NTS["src/nimic/ntypesystem.py<br/>ctypes 类型系统"]
TR["src/nimic/transpiler.py<br/>AST → Nim 源码"]
IN["src/nimic/inliner.py<br/>模板内联"]
end
subgraph Support["支撑资源"]
STD["std/ & system/<br/>Nim 标准库 Python 垫片"]
NIM["ncode/ & nimpy/<br/>Nim 端绑定"]
end
EX --> NT
EX --> INIT
NT --> NTS
INIT --> TR
INIT --> NTS
TR --> NTS
EX --> IN
TR --> Support
NT --> Support核心子模块职责
ntypesystem.py— 核心类型系统,自底向上分四层:内存层(Ntype、NTypeRegistry、BufferRegistry)→ 标量层(NScalar→NInteger/NFloat,含int8..int64、uint8..uint64、float16/32/64,以及算术提升determine_common_type)→ 结构层(Object/NTuple/NIntEnum/变体)→ 容器与修饰层(seq[T]、UncheckedArray[T]、@distinct、@converter、多分派)。注册时通过NMetaClass读取__annotations__,并把泛型特化缓存到_Object._n_specializations。资料来源:src/nimic/ntypesystem.py:7-40、src/nimic/ntypesystem.py:115-150。ntypes.py— 公共 API 与关键字层。重新导出ntypesystem全部符号;把const、let、var、block、export、alias、static实现为contextlib.nullcontext(),使 DSL 既不破坏 Python 语法,又能在 Nim 端保留语义。同时提供untyped、SomeInteger、SomeFloat、cast[T]、comptime()、defined()、fields()、countdown()等运行/编译期工具。资料来源:src/nimic/ntypes.py:36-56、src/nimic/ntypes.py:65-100。transpiler.py— Python → Nim 转译器。本质是 CPythonast.py的修改版,_Unparser被扩展为输出 Nim 语法;文件头注释中显式列出 30+ 条规则(缩进双空格、引号统一为双引号、slice [a:b]映射为[a..<b]、_替换为discard、class转type、{.pragma.}文档字符串转 Nim pragma、&/|/<</等运算符重命名为 Nim 关键字)。unparse()还会接收_n_registry,以解析用户自定义类型。资料来源:src/nimic/transpiler.py:27-58、src/nimic/transpiler.py:80-140。inliner.py— 模板内联器。@template装饰器在返回类型为untyped或文档字符串含{.dirty.}时把函数体 AST 注册到_n_templates;@template_expand通过_ParameterReplacer+_TemplateInliner把调用点处的形参名替换为实参 AST 节点。资料来源:src/nimic/inliner.py:14-31、src/nimic/inliner.py:38-72。__init__.py— 入口模块。stream()用正则(?m)^# /// (?P<type>[a-zA-Z0-9-]+)$...抽取文件中所有元数据块;nimp(obj, srcs, wdir)仅处理标记为nimic的块,调用inspect.getsource→transpiler.parse→transpiler.unparse后把生成的 Nim 源码写入srcs。资料来源:src/nimic/__init__.py:15-37。
数据流:从 DSL 源码到 Nim 代码
完整的转译流程由 nimp() 串联:
stream()扫描源码,按正则匹配出所有以# /// <type>起、# ///止的元数据块;非nimic的块(如pyproject风格的元数据)会被忽略。资料来源:src/nimic/__init__.py:15-20]。- 对类型为
nimic的块,nimp()通过inspect.getsource(obj)获取完整源码,交给transpiler.parse()构造 AST。资料来源:src/nimic/__init__.py:22-30]。 transpiler.unparse(aast, _n_registry)借助_n_registry中的 ctypes 类型映射,按文档化规则逐层改写:缩进 → 字符串/切片 → 类型声明 → 运算符重命名 → 控制流 → 多分派/泛型特化。资料来源:src/nimic/transpiler.py:36-58]。- 模板与多分派在解释期由
ntypesystem处理:注册时遍历__annotations__,按T_map把泛型参数替换为具体类型,并把特化类缓存到_Object._n_specializations。资料来源:src/nimic/ntypesystem.py:115-150。
实际样例 examples/preprocess.py 演示了完整链路:文件先 from nimic.ntypes import * 引入 DSL 类型,再用 # /// nimic 包裹待转译函数体;nimp() 收集生成的 Nim 源码到 srcs 字典,供后续 Nim 编译步骤消费。资料来源:examples/preprocess.py:1-30。
失败模式与注意事项
ptr[T]字段未赋值时由NilPtr("ptr[T]")占位以保留类型信息;业务代码若把字段写成普通None,_n_view仍为None,但__eq__会把它视作 nil,可能与autorename()的预期分支不一致。资料来源:src/nimic/ntypesystem.py:24-44。- 转译器依赖
inspect.getsource(cls)读取类源码以识别 Nimcase object(通过检测类体中是否存在match语句);来自 REPL、exec()或被深度装饰的类会触发OSError,需保证类定义在独立.py文件中。资料来源:src/nimic/ntypesystem.py:71-90。 @template仅在返回类型注解为untyped或文档字符串含{.dirty.}时才注册到_n_templates;普通函数即使加了装饰器也不会被内联。资料来源:src/nimic/inliner.py:26-37。
See Also
- Core Type System(
ntypesystem.py) - Public API & Keywords(
ntypes.py) - AST Transpiler Rules(
transpiler.py) - Template Inlining(
inliner.py)
来源:https://github.com/dima-quant/nimic / 项目说明书
Core Type System and DSL Conventions
nimic 是一个用纯 Python 实现的 Nim 风格 DSL,核心理念是"代码既是合法的 Python,又能转译为等价的 Nim 源码",借助 ctypes 模块获得 C 级别的内存布局与算术语义。核心类型系统与 DSL 约定是这一理念的两大支柱:前者用 Python 类与元类模拟 Nim 的类型语义、内存布局与多分派;后者用特殊装饰器、注解、上下文管理器与 docs...
继续阅读本节完整说明和来源证据。
概述
nimic 是一个用纯 Python 实现的 Nim 风格 DSL,核心理念是"代码既是合法的 Python,又能转译为等价的 Nim 源码",借助 ctypes 模块获得 C 级别的内存布局与算术语义。核心类型系统与 DSL 约定是这一理念的两大支柱:前者用 Python 类与元类模拟 Nim 的类型语义、内存布局与多分派;后者用特殊装饰器、注解、上下文管理器与 docstring 内的 Nim pragma 语法,让 Python 语法同时承担"运行时行为"与"转译语义"双重角色。资料来源:README.md:1-15
类型系统分层架构
ntypesystem.py 中的类型系统按从底层到高层组织为多个层次。Ntype 是基类,封装 ctypes 缓冲区与视图,提供值语义;NTypeRegistry 统一管理类型、ctypes 类型、变体与最大变体数;BufferRegistry 管理共享内存的 ctypes 缓冲区注册与释放。NScalar 派生出 NInteger 与 NFloat,覆盖定宽整数 int8..int64、uint8..uint64、nint 与 IEEE-754 浮点 float16/float32/float64,并通过 determine_common_type() 实现算术提升,同时为每种类型重载算术、比较、位运算与原地运算符。Object 借助类体内的 Python 类型注解生成 ctypes.Structure 字段,对应 Nim 的 object;NTuple 在此基础上通过 __iter__ 支持元组式解包;NIntEnum 自动注册到 DICT_OF_TYPES;当类体中存在 match/case 块时,Object 自动识别为 Nim 的 case object(辨别联合),通过解析源码 AST 构建变体布局。容器层包括 seq[T](基于 ctypes 数组加缓存实现的可增长序列)与 UncheckedArray[T](指针索引数组)。string 继承自 str,通过 ctypes 缓冲区提供 addr() 支持,并实现 &(拼接)、%(模板格式化)与 isEmpty。NilPtr 是保留类型信息的空指针哨兵,用于 autorename() 在分派解析时恢复类型名。资料来源:src/nimic/ntypesystem.py:1-50、README.md:17-32
| 层级 | 关键类 / 机制 | 用途 |
|---|---|---|
| 内存层 | Ntype、NTypeRegistry、BufferRegistry | 基于 ctypes 的缓冲区值语义与统一注册 |
| 标量层 | NScalar → NInteger / NFloat | 定宽整数与 IEEE-754 浮点,含算术提升 |
| 结构层 | Object、NTuple、NIntEnum | Nim object / tuple / 整型枚举 |
| 变体层 | Object + match kind: | Nim case object(辨别联合) |
| 容器层 | seq[T]、UncheckedArray[T] | 可增长序列与指针索引数组 |
| 分派层 | @dispatch、DispDict、NMetaClass | Nim 风格基于类型注解的多分派 |
| 修饰层 | @distinct、@converter | 类型区分与隐式类型转换 |
| 字符串层 | string | 兼容 Nim &、%、isEmpty 的 str 子类 |
DSL 约定与公共 API
ntypes.py 作为公共 API 重新导出 ntypesystem 中的全部类型与装饰器,并补充 Nim 关键字与内建函数的 Python 替身。const/let/var/block/export/alias 实现为 contextlib.nullcontext()——在 Python 中是无操作上下文,转译为 Nim 作用域限定符。ref/ptr/mut@ 提供引用类型语义;@ 运算符返回对象身份,转译为 Nim 的 ref/ptr/var 注解。NStrEnum 提供 succ/pred/ord/nrange/low/high 等枚举工具。castT、sizeof(x)、addr(x)、unsafe_addr(x) 来自 nsystem 模块,对应 Nim 的类型转换与内存地址操作;fields(obj) 与 fields(a, b) 支持字段迭代,countdown(a, b) 实现反向迭代;comptime(x)、defined(varname)、static 用于编译时计算。@template 与 @template_expand 装饰器从 inliner.py 重新导出,负责模板内联。SomeInteger/SomeFloat/BiggestInt/BiggestFloat 等类型别名对应 Nim 的同名概念。资料来源:src/nimic/ntypes.py:1-60、src/nimic/nsystem.py(经由 ntypes.py 导入)、README.md:33-42
DSL 约定层面,Python 语法被赋予双重含义:with let/var/const: 是变量声明的作用域限定符;mut @ 注解标记可变参数(对应 Nim 的 var);"""{.inline.}""" 这种 {.pragma.} docstring 用于透传 Nim 编译期 pragma(inline/borrow/noSideEffect);@dispatch 实现多分派;@distinct 创建无隐式转换的区分类型;@template 注册可在调用点内联的模板;@converter 定义隐式类型转换器。资料来源:README.md:51-66
转译与模板内联机制
transpiler.py 是修改自 CPython ast.py 的 AST→Nim 源码转译器,扩展了 _Unparser 访问者以输出 Nim 语法。它实现了 30 余条转换规则,涵盖缩进、类型定义、函数签名、运算符、导入与控制流,典型规则包括 rule:dropwith(去掉 const/let/var/export/block 前的 with 关键字)、rule:slice(将 Python 切片 [a:]/[a:b] 转为 Nim 的 [a..^1]/[a..<b])、rule:classdef(将 class 解释为 Nim 类型定义)、rule:typealias 与 rule:typedistinct(处理类型别名与 distinct 类型)以及 rule:discard/rule:pass(将 _ = 与 pass 替换为 Nim 的 discard)。资料来源:src/nimic/transpiler.py:1-40
inliner.py 提供 @template 与 @template_expand 装饰器,在 AST 层级对无类型模板做函数内联:当被装饰函数的返回类型注解为 untyped(或 docstring 含 {.dirty.})时,它把函数体解析为 AST 片段存入 _n_templates;_ParameterReplacer 把形参 Name 节点替换为实参节点,_TemplateInliner 在调用点把变换后的模板体拼接进去。nimpy/py_types.py 中的 Py_ssize_t 直接继承 NInteger 并手动注册到 DICT_OF_TYPES 与 DICT_OF_C_TYPES(映射到 ctypes.c_int64),同时定义 PyBUF_SIMPLE/PyBUF_WRITABLE/PyBUF_ND 等缓冲区协议标志常量。examples/preprocess.py 演示了完整用法:从 from nimic.ntypes import * 引入类型系统,使用 ptr[uint8]、ptr[float32]、array[3, float32]、nint 与 with let: 等约定编写可同时在 Python 运行并转译为 Nim 的图像预处理代码,调用了 nearest_neighbour_compute_source_index 等带类型注解的函数。资料来源:src/nimic/inliner.py:1-30、src/nimic/nimpy/py_types.py:1-16、examples/preprocess.py:1-20
参见
- README.md — 项目概览与模块地图
- src/nimic/transpiler.py — Python → Nim 转译规则完整列表
- src/nimic/inliner.py — 模板内联实现细节
- src/nimic/nimpy/ — 生成 Python 扩展库的 API
来源:https://github.com/dima-quant/nimic / 项目说明书
Transpiler Engine and Template Inlining
nimic 项目的核心目标是用 Python 的一个受限子集(DSL)编写可 AOT 编译、达到 C 级性能的代码。该 DSL 既是合法的 Python(可直接在解释器中运行),又可被转译为等价的 Nim 源码。承担这一双重性转换的正是 转译引擎(Transpiler Engine) 与 模板内联机制(Template Inlining)。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
1. 概述与定位
nimic 项目的核心目标是用 Python 的一个受限子集(DSL)编写可 AOT 编译、达到 C 级性能的代码。该 DSL 既是合法的 Python(可直接在解释器中运行),又可被转译为等价的 Nim 源码。承担这一双重性转换的正是 转译引擎(Transpiler Engine) 与 模板内联机制(Template Inlining)。
资料来源:README.md
- 转译引擎:基于 CPython
ast.py修改而来,将_Unparser访问器扩展为输出 Nim 语法,实现 30 余条变换规则。资料来源:src/nimic/transpiler.py - 模板内联:通过
@template/@template_expand装饰器,在抽象语法树(AST)层完成未类型化模板的函数内联,把形参名替换为调用实参。资料来源:src/nimic/inliner.py
两者协同工作:inliner.py 先在 Python 端完成"源代码到源代码"的 AST 重写,transpiler.py 再把最终 AST 展开为 Nim 文本。
2. 转译引擎(transpiler.py)
2.1 核心结构
transpiler.py 并非从零实现的解析器,而是对 CPython 标准库 ast.py 的修改版。模块顶部保留 parse()、literal_eval() 等公共函数,主体逻辑放在扩展后的 _Unparser 访问器中。
2.2 变换规则分类
transpiler.py 内嵌的 docstring 列出了完整的规则族。下列为最关键的几类:
| 类别 | 规则示例 | 作用 |
|---|---|---|
| 格式化 | rule:doublespace、rule:quote、rule:slice、rule:discard、rule:pass | 缩进、字符串、切片、_ = … → discard、pass → discard |
| 作用域 | rule:dropwith、rule:writeexport | 去掉 with let/var/const: 中的 with,让 export 不带括号 |
| 类型系统 | rule:classdef、rule:classdefseq、rule:typealias、rule:typedistinct | class → type,class X(Y) → type X* = Y,@distinct class X(Y) → type X* = distinct Y |
| 控制流 | rule:match、rule:case、rule:block | Python 的 match/case 与 _block() 翻译为 Nim 的 case 与 block: |
| 编译期 | rule:comptime、rule:templateinline | if comptime(...) → when ...,with template_inline: → 模板内联点 |
资料来源:src/nimic/transpiler.py、nimic_translation_rules.md
2.3 入口与调度
src/nimic/__init__.py 中的 ntranspile(args) 是面向用户的入口函数。它接受一个模块或文件路径,把该模块作为 AST 源,通过 transpiler.unparse(aast, _n_registry) 输出 Nim 源码字符串,并递归地把其 import 的 nimic 子模块一并展开。
# 伪代码示意
nim_src, modules_names = transpiler.unparse(aast, _n_registry)
srcs[obj.__name__] = nim_src
for module_name in modules_names:
nimp(sys.modules[module_name], srcs, wdir)
3. 模板内联(inliner.py)
3.1 装饰器语义
@template 会检测函数是否声明返回 untyped,或 docstring 中含 {.dirty.} 标记;满足条件则把它以 AST 片段形式登记到模块级字典 _n_templates 中。
@template
def toUV(v):
"""{.inline.}"""
return v.x & v.y
@template_expand 则装饰 *调用方* 函数,使用 ast.NodeTransformer 遍历其函数体,匹配 _n_templates 中的已注册模板,并用 _ParameterReplacer 把形参节点替换为实参节点。
资料来源:src/nimic/inliner.py
3.2 AST 节点替换流程
flowchart LR
A[被 @template 装饰的函数] --> B[inspect.getsource + ast.parse]
B --> C[_n_templates 注册表]
C --> D[被 @template_expand 装饰的调用方]
D --> E[_TemplateInliner 遍历调用方 AST]
E --> F[检测到模板调用节点]
F --> G[_ParameterReplacer 形参→实参]
G --> H[返回展开后的 AST 片段]
H --> I[transpiler.unparse 输出 Nim]资料来源:src/nimic/inliner.py、src/nimic/transpiler.py
注意:typed 模板仍需 return 语句,仅作为普通 Python 函数参与转译;只有 untyped / {.dirty.} 模板才进入内联通道。资料来源:src/nimic/inliner.py
4. DSL 约定与典型用法
ntypes.py 把 template、template_expand 重新导出,使 DSL 风格统一。下表给出常见转换对照(节选):
| Nim 写法 | Nimic 写法 | 触发规则 |
|---|---|---|
var x: int | with var: x = 0 | rule:dropwith |
type Vec3 = object | class Vec3(Object): | rule:classdef |
type Time = distinct float64 | @distinct<br>class Time(float64): | rule:typedistinct |
template foo(): untyped | @template<br>def foo() -> untyped: | rule:templateinline |
when x < 5: | if comptime(x < 5): | rule:comptime |
资料来源:src/nimic/ntypes.py、nimic_translation_rules.md、README.md
ntypesystem.py 还负责在 Python 运行时模拟 Nim 的内存模型、值类型语义和多分派,使 DSL 在解释执行与 Nim 编译执行时表现一致。资料来源:src/nimic/ntypesystem.py
5. 常见失败模式
- 未在调用方使用
@template_expand:untyped 模板不会在 Python 端被展开,转译后的 Nim 也找不到对应实现。资料来源:src/nimic/inliner.py - 类型注解缺失:
converter、dispatch等装饰器依赖__annotations__推断源/目标类型;缺少注解将导致注册失败。资料来源:src/nimic/ntypesystem.py - 混合 Python 语法:
@distinct必须紧贴class定义之上,且父类必须是ntypesystem中的合法类型;非 DSL 兼容语法会被_Unparser原样输出,引发 Nim 编译错误。资料来源:src/nimic/transpiler.py
See Also
- 类型系统与多分派:src/nimic/ntypesystem.py
- 公共 API 与关键字:src/nimic/ntypes.py
- 完整翻译规则表:nimic_translation_rules.md
- 项目入口与转译调度:src/nimic/__init__.py
- 预处理示例:examples/preprocess.py
资料来源:README.md
Standard Library Shims, nimpy API, and Examples
nimic 是一个纯 Python 模块,目标是让用户用 Python 语法的子集(DSL)写出既能在 Python 中直接运行、又能被转译为等价的 Nim 源码、从而获得 C 级性能的程序。为了弥合 Nim 与 Python 之间的生态差异,nimic 在三个层面提供 shim(垫片):
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概览
nimic 是一个纯 Python 模块,目标是让用户用 Python 语法的子集(DSL)写出既能在 Python 中直接运行、又能被转译为等价的 Nim 源码、从而获得 C 级性能的程序。为了弥合 Nim 与 Python 之间的生态差异,nimic 在三个层面提供 shim(垫片):
nimpy/:桥接 CPython C API 的模块,让 nimic 代码可以读取numpy.ndarray等带缓冲区协议的对象。std/:Nim 标准库的 Python 兼容实现(math、options、os、paths、strformat等)。system/:Nimsystem模块的 Python shim(ansi_c等)。
这些 shim 与 ntypesystem 中的类型系统共同构成 nimic 的运行基础,transpiler 则在转译阶段把它们还原为对 Nim 原生模块的引用。
资料来源:README.md:30-50
nimpy API
nimpy 是 nimic 中负责 Nim ↔ Python 互操作的薄包装层。模块入口只做再导出,避免命名空间污染:
from nimic.nimpy.py_types import *
from nimic.nimpy.raw_buffers import *
PyObject = object
资料来源:src/nimic/nimpy/__init__.py:1-6
核心组件
| 组件 | 来源 | 作用 |
|---|---|---|
Py_ssize_t | py_types.py | 平台相关的有符号大小类型,继承自 NInteger,映射到 ctypes.c_int64 |
PyBUF_SIMPLE / PyBUF_WRITABLE / PyBUF_ND | py_types.py | CPython 缓冲区协议标志常量(0x0000 / 0x0001 / 0x0008) |
RawPyBuffer | raw_buffers.py | Nim RawPyBuffer 的 Python 替身,包装 Py_buffer 结构,含 buf 与 shape 字段 |
getBuffer | raw_buffers.py | 顶层函数,转译后等价于 Nim 的 UFCS obj.getBuffer(buf, flags) |
Py_ssize_t 手动注册到 DICT_OF_TYPES 与 DICT_OF_C_TYPES 中,因为 NInteger 的直接子类会跳过自动注册:
class Py_ssize_t(NInteger):
_n_bits, _n_signed, _n_rank = 64, True, 8
DICT_OF_TYPES["Py_ssize_t"] = Py_ssize_t
DICT_OF_C_TYPES["Py_ssize_t"] = ctypes.c_int64
资料来源:src/nimic/nimpy/py_types.py:6-21
RawPyBuffer 用 nimic 注解语法声明字段:
class RawPyBuffer(Object):
buf: pointer
shape: pointer
转译后等价于 Nim 中的对象类型,调用方可通过 cast[ptr[UncheckedArray[Py_ssize_t]]](buf.shape) 读取维度信息。
资料来源:src/nimic/nimpy/raw_buffers.py:18-25
getBuffer 在 Python 端通过 ctypes 直接读取 numpy 数组的地址并构造形状数组,在 Nim 端则由 nimpy 自身的 UFCS 实现接管:
def getBuffer(obj, buf, flags=0):
if hasattr(obj, 'ctypes') and hasattr(obj, 'shape'):
data_addr = obj.ctypes.data
ndim = obj.ndim
ShapeArray = ctypes.c_ssize_t * ndim
# ...
资料来源:src/nimic/nimpy/raw_buffers.py:31-40
标准库与 system 模块 Shims
std/ 与 system/ 目录的 shim 与 nimpy/ 同构,但规模更大、覆盖更广。它们的存在保证如下导入模式同时在 Python 与 Nim 端可用:
from nimic.std.math import *
from nimic.std.os import *
from nimic.std.options import *
system/ansi_c 暴露 C ABI 访问能力(sizeof、cast、addr 等),通过 ctypes 实现,被 ntypes.py 中的 castT、sizeof(x)、addr(x) 等函数复用。transpiler 会将 from nimic.std.math import * 翻译为 Nim 的 import math,反之亦然。
资料来源:README.md:42-50、src/nimic/transpiler.py(rule scope 列表)
示例:图像预处理管道
examples/preprocess.py 演示了 nimpy 的典型用法:把 HWC 的 uint8 图像缩放为 CHW 的 float32 张量。该文件以 nimic 元注释开头,并在 transpile 之前由 import_from_path 加载:
# /// nimic
#
# ///
from nimic.nimpy import *
from nimic.nimpy.raw_buffers import RawPyBuffer, getBuffer
from nimic.nimpy.py_types import Py_ssize_t, PyBUF_SIMPLE, PyBUF_ND, PyBUF_WRITABLE
核心函数 nearest_neighbour_compute_source_index 实现最近邻缩放的源坐标映射:
def nearest_neighbour_compute_source_index(scale: float64, out_index: nint, input_size: nint) -> nint:
result = min(nint(floor(float64(out_index) * scale)), input_size - 1)
return result
hwc2chw_resize_simple 则接受原始指针、尺寸与均值/方差数组,把逐像素操作放在 with let: 作用域中,并使用 mut @ 注解标记可变参数。该示例是 Raman Labs 博文 中 Nim 实现的 1:1 移植。
资料来源:examples/preprocess.py:1-24
examples/test_preprocess.py 进一步给出端到端用法:构造一个 4×8×3 的 np.uint8 测试帧,调用 preprocessPipeline_nim 验证输出形状与 reverse_channels 行为:
frame = np.arange(0, 4 * 8 * 3, dtype=np.uint8).reshape((4, 8, 3))
output = preprocess(frame, output_shape=(2, 4), reverse_channels=False)
资料来源:examples/test_preprocess.py:18-25
See Also
- 类型系统与 Transpiler 规则
- Nimic 翻译规则速查
- 项目总览
资料来源:README.md:30-50
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
假设不成立时,用户拿不到承诺的能力。
新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
风险会影响是否适合普通用户安装。
用户无法判断遇到问题后是否有人维护。
Pitfall Log / 踩坑日志
项目:dima-quant/nimic
摘要:发现 6 个潜在踩坑项,其中 0 个为 high/blocking;最高优先级:能力坑 - 能力判断依赖假设。
1. 能力坑 · 能力判断依赖假设
- 严重度:medium
- 证据强度:source_linked
- 发现:README/documentation is current enough for a first validation pass.
- 对用户的影响:假设不成立时,用户拿不到承诺的能力。
- 证据:capability.assumptions | https://news.ycombinator.com/item?id=48646239 | README/documentation is current enough for a first validation pass.
2. 维护坑 · 维护活跃度未知
- 严重度:medium
- 证据强度:source_linked
- 发现:未记录 last_activity_observed。
- 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
- 证据:evidence.maintainer_signals | https://news.ycombinator.com/item?id=48646239 | last_activity_observed missing
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 证据:downstream_validation.risk_items | https://news.ycombinator.com/item?id=48646239 | no_demo; severity=medium
4. 安全/权限坑 · 存在评分风险
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:风险会影响是否适合普通用户安装。
- 证据:risks.scoring_risks | https://news.ycombinator.com/item?id=48646239 | no_demo; severity=medium
5. 维护坑 · issue/PR 响应质量未知
- 严重度:low
- 证据强度:source_linked
- 发现:issue_or_pr_quality=unknown。
- 对用户的影响:用户无法判断遇到问题后是否有人维护。
- 证据:evidence.maintainer_signals | https://news.ycombinator.com/item?id=48646239 | issue_or_pr_quality=unknown
6. 维护坑 · 发布节奏不明确
- 严重度:low
- 证据强度:source_linked
- 发现:release_recency=unknown。
- 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
- 证据:evidence.maintainer_signals | https://news.ycombinator.com/item?id=48646239 | release_recency=unknown
来源:Doramagic 发现、验证与编译记录