[project] name = "mcm26b" version = "0.2.0" description = "CUMCM 2026 B题:无线电干扰源的快速自动定位与清除(协议基线、几何内核与策略骨架)" readme = "README.md" requires-python = ">=3.10" dependencies = [ "requests>=2.31", ] [dependency-groups] dev = [ "optuna>=5.0.0", "pytest>=8", # 独立评测机(自建模拟器):仅测试侧依赖,运行时代码零导入(懒加载 + 守卫测试) "mcm26b-referee", ] rl = [ "gymnasium>=1.1", "sb3-contrib==2.9.0", "stable-baselines3>=2.6", "torch==2.11.0", ] # uv 工作区:referee/ 是独立包(零第三方依赖、不依赖 mcm26b),双方仅通过 HTTP 协议耦合 [tool.uv.workspace] members = ["referee"] # RL 训练使用 CUDA 12.8 版 PyTorch(本机 RTX 4060;运行时依赖保持轻量)。 [[tool.uv.index]] name = "pytorch-cu128" url = "https://download.pytorch.org/whl/cu128" explicit = true [tool.uv.sources] mcm26b-referee = { workspace = true } # CUDA 12.8 版 PyTorch 仅限 Windows/Linux(RTX 4060 训练机); # macOS (Apple Silicon, MPS) 回落到 PyPI 官方轮子。 torch = [ { index = "pytorch-cu128", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, ] [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] packages = ["src/mcm26b"] [project.scripts] mcm26b = "mcm26b.cli:main" [tool.pytest.ini_options] testpaths = ["tests", "referee/tests"] # --------------------------------------------------------------------------- # pylint:全仓库静态检查口径 # # 目标:`python -m pylint src scripts project tests referee main.py` 拿 10.00/10。 # 原则:真实的逻辑 / 资源 / 命名 / 死代码问题一律改代码;下面 disable 的每一条 # 都对应项目刻意的设计选择或已确认的静态分析误报,并写明理由,不做"一键静音"。 # --------------------------------------------------------------------------- [tool.pylint.main] py-version = "3.10" jobs = 0 # 不写 ~/Library/Caches/pylint:CI 与受限沙箱里没有该目录,会刷警告 persistent = false recursive = true ignore = [".venv", ".uv-cache", "output"] [tool.pylint.format] max-line-length = 100 [tool.pylint.design] # 阈值按"实际最长函数 + 余量"设定,而不是关闭检查:超过即说明该拆了 max-args = 14 max-positional-arguments = 10 max-locals = 45 max-branches = 26 max-statements = 180 max-attributes = 32 max-nested-blocks = 6 max-returns = 12 max-module-lines = 4000 min-public-methods = 0 [tool.pylint.basic] # 这些是既有代码里的短名/别名(importorskip 后的模块句柄、几何单字母常量、 # 坐标系里的 x/y/z),让命名检查接受它们。 # 注意:good-names 不覆盖 redefined-builtin——stdlib 回调签名里的 `format` # 之类只能在对应 def 上写行内 disable(见 server.py / referee 的 log_message)。 good-names = [ "i", "j", "k", "n", "m", "x", "y", "z", "_", "ex", "id", "pytest", "numpy", "S", "ROOT", "FONT", "ET", ] # http.server 要求 do_GET/do_POST 这类方法名,不能改成 snake_case method-rgx = "[a-z_][a-z0-9_]{2,49}$|do_(GET|POST|PUT|DELETE|HEAD|PATCH|OPTIONS)$" [tool.pylint."messages control"] disable = [ # —— 项目刻意风格 —— "missing-module-docstring", # 内部小模块与 __main__ 不强制 "missing-class-docstring", "missing-function-docstring", "import-outside-toplevel", # torch/SB3/referee 等重依赖与可选依赖懒加载 "wrong-import-position", # 同上:importorskip 守卫后的延迟导入 "ungrouped-imports", # 同上:延迟导入无法与顶部导入分组 "broad-exception-caught", # 子进程 / IO / HTTP 边界防御式兜底,逐处注释 "protected-access", # 测试与 mixin 有意检查内部状态 "duplicate-code", # 脚本与测试夹具存在结构性相似,非复制粘贴缺陷 "redefined-outer-name", # pytest 要求测试参数与 fixture 同名 "attribute-defined-outside-init", # 轻量对象在 helper 里补字段 "multiple-statements", # 单行守卫 (if x: return) 是可读性选择 "use-dict-literal", # dict(...) 与 {...} 混用是既有风格 "abstract-method", # 无头训练环境不需要实现 gym.Env.render # —— 已确认的静态分析误报 —— "possibly-used-before-assignment", # pytest.importorskip 成功即赋值,skip 会抛异常 ]