当同一算子同时被普通 import 测试和 importlib.util.spec_from_file_location 测试消费时,select_tests.py 仅返回普通 import 的测试路径,未执行通过标准 file-spec API 实际加载该算子的测试。现有 README 约定无法确定依赖时保守执行全仓 L0;此处仍返回成功的 incremental 结果。
Linux aarch64(DevEnvC_rN2D6);Python 3.11.4;pytest 8.3.2;Ruff 0.14.14。基线 71ddf7aaed0e013e08adffc02c55e084469f9cc0,修复源 9885cb55c4ba206eb3b7b3fc586dbff658e078d0。纯 stdlib/Host CI 选择逻辑,没有导入项目 NPU 算子;未声称 SDK 编译、NPU kernel 或完整算子 pytest 套通过。
在仓库根目录运行以下完整脚本(需要已有 pytest):
import os import subprocess import sys import tempfile from pathlib import Path selector = Path('.gitcode/scripts/select_tests.py').resolve() files = {'src/cann_ops_tilelang/__init__.py': '', 'src/cann_ops_tilelang/ops/__init__.py': '', 'src/cann_ops_tilelang/ops/foo.py': 'def foo():\n return 42\n', 'tests/test_static.py': 'from cann_ops_tilelang.ops.foo import foo\n\ndef test_static():\n assert foo() == 42\n', 'tests/test_file_loader.py': 'import importlib.util\nfrom pathlib import Path\n\ndef test_file_loader():\n path = Path(__file__).resolve().parents[1] / "src/cann_ops_tilelang/ops/foo.py"\n spec = importlib.util.spec_from_file_location("cann_ops_tilelang.ops.foo", path)\n module = importlib.util.module_from_spec(spec)\n spec.loader.exec_module(module)\n assert module.foo() == 42\n', 'changed.txt': 'src/cann_ops_tilelang/ops/foo.py\n', 'full.conf': 'pyproject.toml\n'} with tempfile.TemporaryDirectory(prefix='tilelang-file-spec-repro-') as temporary: root = Path(temporary) for relative, text in files.items(): path = root / relative path.parent.mkdir(parents=True, exist_ok=True) path.write_text(text) subprocess.run( [sys.executable, str(selector), '--root', str(root), '--changed-files', str(root / 'changed.txt'), '--full-test-triggers', str(root / 'full.conf')], check=True, ) environment = os.environ.copy() environment['PYTHONPATH'] = str(root / 'src') subprocess.run( [sys.executable, '-m', 'pytest', str(root / 'tests'), '--noconftest', '--import-mode=importlib', '-q'], cwd=root, env=environment, check=True, )
两个 pytest 测试都真实消费 foo.py。选择器应保守输出 full / tests,或准确列出两个实际消费者,不能只返回 tests/test_static.py。修复对 file-spec 工厂的标准引用、导入别名和函数赋值别名保守回退;普通 named imports、外部 JSON 导入和 find_spec 外部查询维持精确增量选择。
原版完整 CLI 输出 incremental + tests/test_static.py,而实际 pytest 为 2 passed。冻结 8-case 矩阵:5 个 file-spec 正向 B=0/5、W/K=5/5;3 个精准选择控制 B/W/K=3/3;每阶段8个 fixture 各自真实 pytest2/2,共16次测试执行。原37个原生方法全部保留并通过;同 final 新测试在 B 的39方法运行仅出现预期5个正向 subcase 失败,W/K39方法全部通过。B/W/K 在全物化223 tracked文件阶段执行全仓 ruff check .、ruff format --check . 及正常 declared precommit,通过;W首次正常 precommit 因 Ruff 自动格式化 exit1 原记录保留,后续正常 hooks为0。Git/LFS fsck通过,仓库无LFS路径。
两旧文件修改、零新增公共文件,原 MIT 及 ops-tilelang contributors 版权头逐字节保留。PR48 引入原增量选择器及 named dynamic-import 处理,PR41 引入 full-scope 配置;其完整改动和两类评审评论未报告本次 file-spec 漏选。未宣称覆盖 SourceFileLoader、runpy 或所有 Python 动态加载机制。该仓无OAT hook,未安装或改造OAT/XML;无完整产品/NPU CI通过声明。
/assign @Ethan_Zou
问题描述 / Describe the current behavior
当同一算子同时被普通 import 测试和 importlib.util.spec_from_file_location 测试消费时,select_tests.py 仅返回普通 import 的测试路径,未执行通过标准 file-spec API 实际加载该算子的测试。现有 README 约定无法确定依赖时保守执行全仓 L0;此处仍返回成功的 incremental 结果。
环境信息 / Environment Information
Linux aarch64(DevEnvC_rN2D6);Python 3.11.4;pytest 8.3.2;Ruff 0.14.14。基线 71ddf7aaed0e013e08adffc02c55e084469f9cc0,修复源 9885cb55c4ba206eb3b7b3fc586dbff658e078d0。纯 stdlib/Host CI 选择逻辑,没有导入项目 NPU 算子;未声称 SDK 编译、NPU kernel 或完整算子 pytest 套通过。
重现步骤 / Steps to reproduce
在仓库根目录运行以下完整脚本(需要已有 pytest):
import os import subprocess import sys import tempfile from pathlib import Path selector = Path('.gitcode/scripts/select_tests.py').resolve() files = {'src/cann_ops_tilelang/__init__.py': '', 'src/cann_ops_tilelang/ops/__init__.py': '', 'src/cann_ops_tilelang/ops/foo.py': 'def foo():\n return 42\n', 'tests/test_static.py': 'from cann_ops_tilelang.ops.foo import foo\n\ndef test_static():\n assert foo() == 42\n', 'tests/test_file_loader.py': 'import importlib.util\nfrom pathlib import Path\n\ndef test_file_loader():\n path = Path(__file__).resolve().parents[1] / "src/cann_ops_tilelang/ops/foo.py"\n spec = importlib.util.spec_from_file_location("cann_ops_tilelang.ops.foo", path)\n module = importlib.util.module_from_spec(spec)\n spec.loader.exec_module(module)\n assert module.foo() == 42\n', 'changed.txt': 'src/cann_ops_tilelang/ops/foo.py\n', 'full.conf': 'pyproject.toml\n'} with tempfile.TemporaryDirectory(prefix='tilelang-file-spec-repro-') as temporary: root = Path(temporary) for relative, text in files.items(): path = root / relative path.parent.mkdir(parents=True, exist_ok=True) path.write_text(text) subprocess.run( [sys.executable, str(selector), '--root', str(root), '--changed-files', str(root / 'changed.txt'), '--full-test-triggers', str(root / 'full.conf')], check=True, ) environment = os.environ.copy() environment['PYTHONPATH'] = str(root / 'src') subprocess.run( [sys.executable, '-m', 'pytest', str(root / 'tests'), '--noconftest', '--import-mode=importlib', '-q'], cwd=root, env=environment, check=True, )预期结果 / Expected behavior
两个 pytest 测试都真实消费 foo.py。选择器应保守输出 full / tests,或准确列出两个实际消费者,不能只返回 tests/test_static.py。修复对 file-spec 工厂的标准引用、导入别名和函数赋值别名保守回退;普通 named imports、外部 JSON 导入和 find_spec 外部查询维持精确增量选择。
日志/截图 / Log/Screenshot
原版完整 CLI 输出 incremental + tests/test_static.py,而实际 pytest 为 2 passed。冻结 8-case 矩阵:5 个 file-spec 正向 B=0/5、W/K=5/5;3 个精准选择控制 B/W/K=3/3;每阶段8个 fixture 各自真实 pytest2/2,共16次测试执行。原37个原生方法全部保留并通过;同 final 新测试在 B 的39方法运行仅出现预期5个正向 subcase 失败,W/K39方法全部通过。B/W/K 在全物化223 tracked文件阶段执行全仓 ruff check .、ruff format --check . 及正常 declared precommit,通过;W首次正常 precommit 因 Ruff 自动格式化 exit1 原记录保留,后续正常 hooks为0。Git/LFS fsck通过,仓库无LFS路径。
备注 / Additional Notes
两旧文件修改、零新增公共文件,原 MIT 及 ops-tilelang contributors 版权头逐字节保留。PR48 引入原增量选择器及 named dynamic-import 处理,PR41 引入 full-scope 配置;其完整改动和两类评审评论未报告本次 file-spec 漏选。未宣称覆盖 SourceFileLoader、runpy 或所有 Python 动态加载机制。该仓无OAT hook,未安装或改造OAT/XML;无完整产品/NPU CI通过声明。