AutoCython-zhang 2.3.1
自动Cython，使用Cython批量编译.py文件为.pyd文件！
Requires Python: >=3.9
Keywords: cython, compile, pyd, pyc, python, autopyd

# AutoCython V2

**自动 Cython：一键将 Python 文件批量编译为 `PYD / SO` 二进制文件，内置 AST 七重混淆引擎**


## ✨ 特性

- 单文件 / 目录批量编译
- 跨平台支持（Windows / Linux / macOS）
- AST 七重混淆引擎（可复现）
- Rich 实时进度 UI，中英文自动切换
- 编译后可选删除源码
- 自动 strip 符号表（Linux / macOS）

## 📦 安装

```bash
pip install -U AutoCython-zhang
```

要求 Python ≥ 3.9。

## ⚙️ 依赖环境

### C/C++ 编译器

| 平台 | 编译器 |
|------|--------|
| Windows | Visual Studio（MSVC） |
| Linux | gcc & g++ |
| macOS | clang（Xcode Command Line Tools） |

**重要提示**：编译器架构必须与 Python 解释器一致（64 位 Python 需 64 位编译器）

> 其他编译器配置请参考 [Cython](https://github.com/cython/cython) 项目

## 🚀 使用指南

### 命令行参数

| 参数 | 说明 | 默认值 |
|------|------|--------|
| `-f, --file` | 编译单个文件 | — |
| `-p, --path` | 编译目录下所有 `.py` 文件 | — |
| `-c, --conc` | 并发编译线程数 | 2 |
| `-d, --del` | 编译后删除源代码 | False |
| `--seed` | 混淆随机种子（可复现构建） | None |
| `-v, --version` | 显示版本号 | — |
| `-h, --help` | 显示帮助信息 | — |

> `-f` 和 `-p` 互斥，不可同时使用。

### 命令行示例

```bash
# 编译单个文件
AutoCython -f test.py

# 编译整个目录
AutoCython -p /path/to/project

# 编译后删除源代码
AutoCython -d -f test.py
AutoCython -d -p /path/to/project

# 4 线程并发编译
AutoCython -c 4 -p /path/to/project

# 指定混淆随机种子（可复现构建）
AutoCython --seed 2025 -f test.py
```

### 手动排除文件不编译

在文件 **前两行任意一行** 包含以下标记即可跳过编译：

```python
# AutoCython No Compile
```

> 兼容旧版拼写 `# AucoCython No Compile`

### 自动排除规则

以下文件和目录会被自动跳过：

- `__init__.py` 文件
- `__pycache__`、`venv`、`.venv`、`build`、`dist`、`node_modules`、`.git`、`.eggs` 目录
- `*.egg-info` 目录

## 🔐 AST 混淆引擎

编译前自动执行七重 AST 变换（按执行顺序），大幅提升逆向难度：

| 序号 | 变换 | 说明 | 安全跳过条件 |
|------|------|------|-------------|
| 1 | Docstring 移除 | 清除 module / class / function 的文档字符串 | 无 |
| 2 | Annotation 移除 | 清除函数参数、返回值、变量的类型注解 | 无 |
| 3 | 局部变量重命名 | 基于 hash 的标识符替换，保护闭包变量 | 含 `globals()`/`locals()`/`eval()`/`exec()`/`vars()` 调用 |
| 4 | 控制流平坦化 | 函数体转换为 `while True` + 状态机调度 | async 函数、yield/yield from、nonlocal/global 声明、comprehension、函数体 < 3 条语句、含不安全调用 |
| 5 | 虚假分支插入 | 30% 概率插入永真/永假不透明谓词 | 含不安全调用 |
| 6 | 字符串加密 | 字符串常量替换为 XOR 解密表达式 | 长度 ≤ 1 的字符串、f-string、`match/case` pattern 常量 |
| 7 | 常量折叠混淆 | 整数常量拆分为算术表达式 | 0、1、负数、> 10000 的整数、布尔值、`match/case` pattern 常量 |

> `ast.unparse()` 天然丢弃所有注释，无需额外处理。

使用 `--seed` 参数可固定随机种子，实现可复现混淆。

## 📚 Python API

```python
from AutoCython import compile  # CLI 入口
from AutoCython.compile import compile_to_binary, get_platform_extension
from AutoCython.obfuscate import obfuscate_source
from AutoCython.run_tasks import run_tasks
from AutoCython.tools import find_python_files, get_system_language
```

### `compile_to_binary(file_path, del_source=False, obfuscate=True, obfuscate_seed=None)`

将单个 `.py` 文件编译为二进制扩展（`.pyd` / `.so`）。当 `obfuscate=True` 且混淆失败时，会抛出 `RuntimeError`，避免静默回退到原始源码。

```python
from AutoCython.compile import compile_to_binary

output = compile_to_binary("example.py")
print(output)  # example.cpython-312-x86_64-linux-gnu.so
```

### `obfuscate_source(source_code, seed=None)`

对源码执行七重 AST 混淆变换，返回混淆后的源码字符串。

```python
from AutoCython.obfuscate import obfuscate_source

code = open("example.py").read()
obfuscated = obfuscate_source(code, seed=42)
```

### `run_tasks(task_list, max_workers=2, language=None, raise_on_failure=False)`

并发执行任务列表，实时显示 Rich 进度 UI。`task_list` 中每个元素为四元组 `(函数, 显示名称, 位置参数元组, 关键字参数字典)`。

```python
from AutoCython.run_tasks import run_tasks

tasks = [
    (func, display_name, (arg1, arg2), {}),
]
summary = run_tasks(tasks, max_workers=4)
# summary = {"total": N, "succeeded": N, "failed": N, "elapsed": float, "tasks": [...]}
```

### `find_python_files(path)`

递归查找目录下所有可编译的 `.py` 文件（排除 `__init__.py` 和标记文件）。

```python
from AutoCython.tools import find_python_files

files = find_python_files("/path/to/project")
```

## 🧪 测试

```bash
# 运行全部测试
pytest

# 只运行单元测试
pytest -m unit

# 只运行集成测试 (kd_dist)
pytest -m integ

# 排除集成测试（快速验证）
pytest -m "not integ"
```

### kd-dist 集成测试

kd-dist 集成测试框架用于验证真实项目的编译兼容性和行为等价性。

```bash
# 指定真实项目根目录（未设置则自动探测）
export KD_DIST_ROOT=/path/to/kd-dist

# 开启严格文件计数阈值校验（默认关闭）
export KD_DIST_STRICT_COUNTS=1

# 输出 kd-dist 分层测试 JSON 报告
export KD_DIST_REPORT_PATH=.pytest_cache/kd_dist_report.json
```

| 测试标记 | 说明 |
|----------|------|
| `kd_compile_plain` | 纯编译矩阵测试 |
| `kd_compile_obfuscate` | 混淆编译矩阵测试 |
| `kd_behavior` | 行为等价性验证 |

配置文件：
- `tests/kd_dist/manifest.json` — import policy 与行为等价用例
- `tests/kd_dist/known_failures.json` — 已知 Cython 不兼容文件（xfail 治理）

## 📁 项目结构

```
AutoCython/
├── AutoCython/
│   ├── __init__.py          # 版本导入 + main() 入口
│   ├── _version.py          # 版本号定义
│   ├── AutoCython.py        # CLI 编译入口
│   ├── compile.py           # Cython 编译核心逻辑
│   ├── obfuscate.py         # AST 七重混淆引擎
│   ├── run_tasks.py         # 并发任务执行 + Rich UI
│   └── tools.py             # 工具函数（参数解析、文件查找、国际化）
├── tests/
│   ├── test_autocython.py   # CLI 入口测试
│   ├── test_compile.py      # 编译模块测试
│   ├── test_obfuscate.py    # 混淆模块测试
│   ├── test_run_tasks.py    # 并发任务测试
│   ├── test_tools.py        # 工具函数测试
│   └── kd_dist/             # kd-dist 集成测试框架
├── pyproject.toml           # 项目配置
├── requirements.txt         # 依赖清单
├── LICENSE                  # MIT 许可证
└── README.md
```

## ⚠️ 常见问题

| 问题 | 原因 | 解决方案 |
|------|------|----------|
| 编译失败 | 源码含 Cython 不支持的语法 | 查阅 [Cython Wiki](https://github.com/cython/cython/wiki) |
| 文件名不支持 | 含连字符等特殊字符 | 自动转下划线，或手动重命名 |
| 编译超时 | 单文件编译超过 300 秒 | 拆分大文件或检查死循环 |
| 混淆后运行异常 | 触发了不安全变换 | 使用 `# AutoCython No Compile` 排除该文件 |

## 📅 更新记录

### V2 版本

| 版本 | 日期 | 说明 |
|------|------|------|
| V2.3.0 | 2025 | 混淆测试集成 known failure 机制，更新构建和项目配置 |
| V2.1.0 | 2025-06-23 | 禁用激进性能优化选项，显示系统信息 |
| V2.0.0 | 2025-06-09 | 完全重构代码，使用新 UI |

### V1 版本

1. 20220613 — 新增 Linux 支持，需配置 gcc & g++
2. 20221123 — 支持文件头标记排除编译
3. 20230306 — 支持指定命令行头（如 `Python310`）以兼容非 Windows 编译
4. 20230324 — 文档更新
5. 20240506 — 修复编译失败时遗漏复原 `__init__.py` 的问题

## 📄 许可证

[MIT License](LICENSE)