Files
chanlun.rs/chanlun-py/build.rs
T
YuWuKunCheng ae57090d7f 1. Pickle 支持修复(__reduce__)
- 修复了 相对方向Py.__reduce__ 中 str() 返回 相对方向.向上 导致 getattr 失败的问题(拆分取 . 后变体名)
  - 重新编译后 __module__ 正确返回 chanlun._chanlun
  - 所有 4 个类型(相对方向、买卖点类型、分型结构、缺口)pickle 往返测试通过

  2. from_py_object 消除 163 个弃用警告

  - 给 14 个 #[derive(Clone)] 的 pyclass 添加了 from_py_object
  - #[pyclass] 中的正确写法:#[pyclass(name = "X", module = "chanlun._chanlun", from_py_object)]
  - cargo clean 重新编译后零 from_py_object 警告

  3. #[classattr] + __members__

  - 为 3 个枚举类型(相对方向、买卖点类型、分型结构)添加了 __members__ 类属性
  - __members__ 是 dict[str, 实例],行为与 Python Enum.__members__ 一致
  - 通过 pickle 反序列化的值也在 __members__.values() 中

  4. __richcmp__

  - 为 3 个枚举类型 + 缺口实现了 __richcmp__,替换手写 __eq__
  - 相对方向/分型结构:支持全部 6 种比较(基于判别值排序)
  - 买卖点类型:支持 Eq/Ne + 与字符串比较
  - 缺口:支持全部 6 种比较(按 (高, 低) 元组排序)

  5. 补充文档
2026-05-28 14:03:53 +08:00

69 lines
2.3 KiB
Rust

/// build.rs — 编译时版本一致性检查
///
/// 验证 Cargo.toml 和 pyproject.toml 的版本号是否一致。
///
/// Cargo.toml: version = "YY.MM.patch" (e.g., "26.5.57")
/// pyproject.toml: version = "YYMM.patch" (e.g., "2605.57")
/// 规则: YY = major, MM = minor, patch = patch
fn main() {
let cargo_manifest_dir =
std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
let cargo_path = std::path::PathBuf::from(&cargo_manifest_dir);
let cargo_version = read_version(&cargo_path.join("Cargo.toml"), "[package]");
let cargo_parts: Vec<&str> = cargo_version.split('.').collect();
assert_eq!(
cargo_parts.len(),
3,
"Cargo.toml version '{}' is not in YY.MM.patch format",
cargo_version
);
let pyproject_version = read_version(&cargo_path.join("pyproject.toml"), "[project]");
let py_parts: Vec<&str> = pyproject_version.split('.').collect();
assert_eq!(
py_parts.len(),
2,
"pyproject.toml version '{}' is not in YYMM.patch format",
pyproject_version
);
let expected_yymm = format!("{}{:0>2}", cargo_parts[0], cargo_parts[1]);
assert_eq!(
py_parts[0], expected_yymm,
"pyproject.toml version prefix '{}' != expected '{}' (from Cargo {})",
py_parts[0], expected_yymm, cargo_version
);
assert_eq!(
py_parts[1], cargo_parts[2],
"pyproject.toml patch '{}' != Cargo.toml patch '{}'",
py_parts[1], cargo_parts[2]
);
println!("cargo:rerun-if-changed=pyproject.toml");
println!("cargo:rerun-if-changed=Cargo.toml");
}
fn read_version(path: &std::path::Path, section: &str) -> String {
let content =
std::fs::read_to_string(path).unwrap_or_else(|e| panic!("Cannot read {:?}: {}", path, e));
let mut in_section = section.is_empty();
for line in content.lines() {
let trimmed = line.trim();
if trimmed.starts_with('[') {
in_section = trimmed == section;
continue;
}
if !in_section {
continue;
}
if trimmed.starts_with("version") {
if let Some(v) = trimmed.split('=').nth(1) {
return v.trim().trim_matches('"').trim().to_string();
}
}
}
panic!("Cannot parse version from {:?}", path);
}