this derivation will be built: /nix/store/s5yfiyv3br3dvxp1b7nizjnagfm5s00k-mcptoon-0.7.17.drv building '/nix/store/s5yfiyv3br3dvxp1b7nizjnagfm5s00k-mcptoon-0.7.17.drv' mcptoon-0.7.17> Sourcing python-remove-tests-dir-hook mcptoon-0.7.17> Sourcing python-catch-conflicts-hook.sh mcptoon-0.7.17> Sourcing python-remove-bin-bytecode-hook.sh mcptoon-0.7.17> Sourcing pypa-build-hook mcptoon-0.7.17> Using pypaBuildPhase mcptoon-0.7.17> Sourcing python-runtime-deps-check-hook mcptoon-0.7.17> Using pythonRuntimeDepsCheckHook mcptoon-0.7.17> Sourcing pypa-install-hook mcptoon-0.7.17> Using pypaInstallPhase mcptoon-0.7.17> Sourcing python-imports-check-hook.sh mcptoon-0.7.17> Using pythonImportsCheckPhase mcptoon-0.7.17> Sourcing python-namespaces-hook mcptoon-0.7.17> Sourcing python-catch-conflicts-hook.sh mcptoon-0.7.17> Sourcing pytest-check-hook mcptoon-0.7.17> Using pytestCheckPhase mcptoon-0.7.17> Running phase: unpackPhase mcptoon-0.7.17> unpacking source archive /nix/store/92q287ar3njqi8x54ib1ap60df8m9720-source mcptoon-0.7.17> source root is source mcptoon-0.7.17> setting SOURCE_DATE_EPOCH to timestamp 315619200 of file "source/tests/test_watch.py" mcptoon-0.7.17> Running phase: patchPhase mcptoon-0.7.17> Running phase: updateAutotoolsGnuConfigScriptsPhase mcptoon-0.7.17> Running phase: configurePhase mcptoon-0.7.17> no configure script, doing nothing mcptoon-0.7.17> Running phase: buildPhase mcptoon-0.7.17> Executing pypaBuildPhase mcptoon-0.7.17> Creating a wheel... mcptoon-0.7.17> pypa build flags: --no-isolation --outdir dist/ --wheel mcptoon-0.7.17> * Getting build dependencies for wheel... mcptoon-0.7.17> /nix/store/gyficbimx12q5975523ps3kjzz8ys4pq-python3.14-setuptools-83.0.0/lib/python3.14/site-packages/setuptools/config/_apply_pyprojecttoml.py:82: SetuptoolsDeprecationWarning: `project.license` as a TOML table is deprecated mcptoon-0.7.17> !! mcptoon-0.7.17> mcptoon-0.7.17> ******************************************************************************** mcptoon-0.7.17> Please use a simple string containing a SPDX expression for `project.license`. You can also use `project.license-files`. (Both options available on setuptools>=77.0.0). mcptoon-0.7.17> mcptoon-0.7.17> By 2027-Feb-18, you need to update your project and remove deprecated calls mcptoon-0.7.17> or your builds will no longer be supported. mcptoon-0.7.17> mcptoon-0.7.17> See https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license for details. mcptoon-0.7.17> ******************************************************************************** mcptoon-0.7.17> mcptoon-0.7.17> !! mcptoon-0.7.17> corresp(dist, value, root_dir) mcptoon-0.7.17> /nix/store/gyficbimx12q5975523ps3kjzz8ys4pq-python3.14-setuptools-83.0.0/lib/python3.14/site-packages/setuptools/config/_apply_pyprojecttoml.py:61: SetuptoolsDeprecationWarning: License classifiers are deprecated. mcptoon-0.7.17> !! mcptoon-0.7.17> mcptoon-0.7.17> ******************************************************************************** mcptoon-0.7.17> Please consider removing the following classifiers in favor of a SPDX license expression: mcptoon-0.7.17> mcptoon-0.7.17> License :: OSI Approved :: Apache Software License mcptoon-0.7.17> mcptoon-0.7.17> See https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license for details. mcptoon-0.7.17> ******************************************************************************** mcptoon-0.7.17> mcptoon-0.7.17> !! mcptoon-0.7.17> dist._finalize_license_expression() mcptoon-0.7.17> /nix/store/gyficbimx12q5975523ps3kjzz8ys4pq-python3.14-setuptools-83.0.0/lib/python3.14/site-packages/setuptools/dist.py:765: SetuptoolsDeprecationWarning: License classifiers are deprecated. mcptoon-0.7.17> !! mcptoon-0.7.17> mcptoon-0.7.17> ******************************************************************************** mcptoon-0.7.17> Please consider removing the following classifiers in favor of a SPDX license expression: mcptoon-0.7.17> mcptoon-0.7.17> License :: OSI Approved :: Apache Software License mcptoon-0.7.17> mcptoon-0.7.17> See https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license for details. mcptoon-0.7.17> ******************************************************************************** mcptoon-0.7.17> mcptoon-0.7.17> !! mcptoon-0.7.17> self._finalize_license_expression() mcptoon-0.7.17> running egg_info mcptoon-0.7.17> creating src/mcptoon.egg-info mcptoon-0.7.17> writing src/mcptoon.egg-info/PKG-INFO mcptoon-0.7.17> writing dependency_links to src/mcptoon.egg-info/dependency_links.txt mcptoon-0.7.17> writing entry points to src/mcptoon.egg-info/entry_points.txt mcptoon-0.7.17> writing requirements to src/mcptoon.egg-info/requires.txt mcptoon-0.7.17> writing top-level names to src/mcptoon.egg-info/top_level.txt mcptoon-0.7.17> writing manifest file 'src/mcptoon.egg-info/SOURCES.txt' mcptoon-0.7.17> reading manifest file 'src/mcptoon.egg-info/SOURCES.txt' mcptoon-0.7.17> adding license file 'LICENSE' mcptoon-0.7.17> adding license file 'NOTICE' mcptoon-0.7.17> writing manifest file 'src/mcptoon.egg-info/SOURCES.txt' mcptoon-0.7.17> * Building wheel... mcptoon-0.7.17> /nix/store/gyficbimx12q5975523ps3kjzz8ys4pq-python3.14-setuptools-83.0.0/lib/python3.14/site-packages/setuptools/config/_apply_pyprojecttoml.py:82: SetuptoolsDeprecationWarning: `project.license` as a TOML table is deprecated mcptoon-0.7.17> !! mcptoon-0.7.17> mcptoon-0.7.17> ******************************************************************************** mcptoon-0.7.17> Please use a simple string containing a SPDX expression for `project.license`. You can also use `project.license-files`. (Both options available on setuptools>=77.0.0). mcptoon-0.7.17> mcptoon-0.7.17> By 2027-Feb-18, you need to update your project and remove deprecated calls mcptoon-0.7.17> or your builds will no longer be supported. mcptoon-0.7.17> mcptoon-0.7.17> See https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license for details. mcptoon-0.7.17> ******************************************************************************** mcptoon-0.7.17> mcptoon-0.7.17> !! mcptoon-0.7.17> corresp(dist, value, root_dir) mcptoon-0.7.17> /nix/store/gyficbimx12q5975523ps3kjzz8ys4pq-python3.14-setuptools-83.0.0/lib/python3.14/site-packages/setuptools/config/_apply_pyprojecttoml.py:61: SetuptoolsDeprecationWarning: License classifiers are deprecated. mcptoon-0.7.17> !! mcptoon-0.7.17> mcptoon-0.7.17> ******************************************************************************** mcptoon-0.7.17> Please consider removing the following classifiers in favor of a SPDX license expression: mcptoon-0.7.17> mcptoon-0.7.17> License :: OSI Approved :: Apache Software License mcptoon-0.7.17> mcptoon-0.7.17> See https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license for details. mcptoon-0.7.17> ******************************************************************************** mcptoon-0.7.17> mcptoon-0.7.17> !! mcptoon-0.7.17> dist._finalize_license_expression() mcptoon-0.7.17> /nix/store/gyficbimx12q5975523ps3kjzz8ys4pq-python3.14-setuptools-83.0.0/lib/python3.14/site-packages/setuptools/dist.py:765: SetuptoolsDeprecationWarning: License classifiers are deprecated. mcptoon-0.7.17> !! mcptoon-0.7.17> mcptoon-0.7.17> ******************************************************************************** mcptoon-0.7.17> Please consider removing the following classifiers in favor of a SPDX license expression: mcptoon-0.7.17> mcptoon-0.7.17> License :: OSI Approved :: Apache Software License mcptoon-0.7.17> mcptoon-0.7.17> See https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license for details. mcptoon-0.7.17> ******************************************************************************** mcptoon-0.7.17> mcptoon-0.7.17> !! mcptoon-0.7.17> self._finalize_license_expression() mcptoon-0.7.17> running bdist_wheel mcptoon-0.7.17> running build mcptoon-0.7.17> running build_py mcptoon-0.7.17> creating build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/__main__.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/usage.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/errors.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/demo_server.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/sync.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/discover.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/serve.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/output.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/plugin.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/demo.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/toon_vendored.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/skills.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/client.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/manifest.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/config.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/__init__.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/installer.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/cache.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/router.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/bench.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/native_tools.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/watch.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/schema_simplifier.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/health.py -> build/lib/mcptoon mcptoon-0.7.17> copying src/mcptoon/cli.py -> build/lib/mcptoon mcptoon-0.7.17> running egg_info mcptoon-0.7.17> writing src/mcptoon.egg-info/PKG-INFO mcptoon-0.7.17> writing dependency_links to src/mcptoon.egg-info/dependency_links.txt mcptoon-0.7.17> writing entry points to src/mcptoon.egg-info/entry_points.txt mcptoon-0.7.17> writing requirements to src/mcptoon.egg-info/requires.txt mcptoon-0.7.17> writing top-level names to src/mcptoon.egg-info/top_level.txt mcptoon-0.7.17> reading manifest file 'src/mcptoon.egg-info/SOURCES.txt' mcptoon-0.7.17> adding license file 'LICENSE' mcptoon-0.7.17> adding license file 'NOTICE' mcptoon-0.7.17> writing manifest file 'src/mcptoon.egg-info/SOURCES.txt' mcptoon-0.7.17> installing to build/bdist.linux-x86_64/wheel mcptoon-0.7.17> running install mcptoon-0.7.17> running install_lib mcptoon-0.7.17> creating build/bdist.linux-x86_64/wheel mcptoon-0.7.17> creating build/bdist.linux-x86_64/wheel/mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/__init__.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/demo_server.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/config.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/cli.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/sync.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/router.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/native_tools.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/serve.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/health.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/demo.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/toon_vendored.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/usage.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/installer.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/output.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/plugin.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/__main__.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/schema_simplifier.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/errors.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/discover.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/watch.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/bench.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/skills.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/manifest.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/client.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> copying build/lib/mcptoon/cache.py -> build/bdist.linux-x86_64/wheel/./mcptoon mcptoon-0.7.17> running install_egg_info mcptoon-0.7.17> Copying src/mcptoon.egg-info to build/bdist.linux-x86_64/wheel/./mcptoon-0.7.17-py3.14.egg-info mcptoon-0.7.17> running install_scripts mcptoon-0.7.17> creating build/bdist.linux-x86_64/wheel/mcptoon-0.7.17.dist-info/WHEEL mcptoon-0.7.17> creating '/build/source/dist/.tmp-za7rm42m/mcptoon-0.7.17-py3-none-any.whl' and adding 'build/bdist.linux-x86_64/wheel' to it mcptoon-0.7.17> adding 'mcptoon/__init__.py' mcptoon-0.7.17> adding 'mcptoon/__main__.py' mcptoon-0.7.17> adding 'mcptoon/bench.py' mcptoon-0.7.17> adding 'mcptoon/cache.py' mcptoon-0.7.17> adding 'mcptoon/cli.py' mcptoon-0.7.17> adding 'mcptoon/client.py' mcptoon-0.7.17> adding 'mcptoon/config.py' mcptoon-0.7.17> adding 'mcptoon/demo.py' mcptoon-0.7.17> adding 'mcptoon/demo_server.py' mcptoon-0.7.17> adding 'mcptoon/discover.py' mcptoon-0.7.17> adding 'mcptoon/errors.py' mcptoon-0.7.17> adding 'mcptoon/health.py' mcptoon-0.7.17> adding 'mcptoon/installer.py' mcptoon-0.7.17> adding 'mcptoon/manifest.py' mcptoon-0.7.17> adding 'mcptoon/native_tools.py' mcptoon-0.7.17> adding 'mcptoon/output.py' mcptoon-0.7.17> adding 'mcptoon/plugin.py' mcptoon-0.7.17> adding 'mcptoon/router.py' mcptoon-0.7.17> adding 'mcptoon/schema_simplifier.py' mcptoon-0.7.17> adding 'mcptoon/serve.py' mcptoon-0.7.17> adding 'mcptoon/skills.py' mcptoon-0.7.17> adding 'mcptoon/sync.py' mcptoon-0.7.17> adding 'mcptoon/toon_vendored.py' mcptoon-0.7.17> adding 'mcptoon/usage.py' mcptoon-0.7.17> adding 'mcptoon/watch.py' mcptoon-0.7.17> adding 'mcptoon-0.7.17.dist-info/licenses/LICENSE' mcptoon-0.7.17> adding 'mcptoon-0.7.17.dist-info/licenses/NOTICE' mcptoon-0.7.17> adding 'mcptoon-0.7.17.dist-info/METADATA' mcptoon-0.7.17> adding 'mcptoon-0.7.17.dist-info/WHEEL' mcptoon-0.7.17> adding 'mcptoon-0.7.17.dist-info/entry_points.txt' mcptoon-0.7.17> adding 'mcptoon-0.7.17.dist-info/top_level.txt' mcptoon-0.7.17> adding 'mcptoon-0.7.17.dist-info/RECORD' mcptoon-0.7.17> removing build/bdist.linux-x86_64/wheel mcptoon-0.7.17> Successfully built mcptoon-0.7.17-py3-none-any.whl mcptoon-0.7.17> Finished creating a wheel... mcptoon-0.7.17> Finished executing pypaBuildPhase mcptoon-0.7.17> Running phase: pythonRuntimeDepsCheckHook mcptoon-0.7.17> Executing pythonRuntimeDepsCheck mcptoon-0.7.17> Checking runtime dependencies for mcptoon-0.7.17-py3-none-any.whl mcptoon-0.7.17> Finished executing pythonRuntimeDepsCheck mcptoon-0.7.17> Running phase: installPhase mcptoon-0.7.17> Executing pypaInstallPhase mcptoon-0.7.17> Successfully installed mcptoon-0.7.17-py3-none-any.whl mcptoon-0.7.17> Finished executing pypaInstallPhase mcptoon-0.7.17> Running phase: pythonOutputDistPhase mcptoon-0.7.17> Executing pythonOutputDistPhase mcptoon-0.7.17> Finished executing pythonOutputDistPhase mcptoon-0.7.17> Running phase: fixupPhase mcptoon-0.7.17> shrinking RPATHs of ELF executables and libraries in /nix/store/wfil1bf753n2g832mxmwx5qcjfyk9w0v-mcptoon-0.7.17 mcptoon-0.7.17> checking for references to /build/ in /nix/store/wfil1bf753n2g832mxmwx5qcjfyk9w0v-mcptoon-0.7.17... mcptoon-0.7.17> patching script interpreter paths in /nix/store/wfil1bf753n2g832mxmwx5qcjfyk9w0v-mcptoon-0.7.17 mcptoon-0.7.17> stripping (with command strip and flags -S -p) in /nix/store/wfil1bf753n2g832mxmwx5qcjfyk9w0v-mcptoon-0.7.17/lib /nix/store/wfil1bf753n2g832mxmwx5qcjfyk9w0v-mcptoon-0.7.17/bin mcptoon-0.7.17> shrinking RPATHs of ELF executables and libraries in /nix/store/7nrcv55v6z2xwqjmzhlqw48yd16icds6-mcptoon-0.7.17-dist mcptoon-0.7.17> checking for references to /build/ in /nix/store/7nrcv55v6z2xwqjmzhlqw48yd16icds6-mcptoon-0.7.17-dist... mcptoon-0.7.17> patching script interpreter paths in /nix/store/7nrcv55v6z2xwqjmzhlqw48yd16icds6-mcptoon-0.7.17-dist mcptoon-0.7.17> Rewriting #!/nix/store/d64q19q1xjdwfhqx6czvrjgrhq0n3lcc-python3-3.14.7/bin/python3.14 to #!/nix/store/d64q19q1xjdwfhqx6czvrjgrhq0n3lcc-python3-3.14.7 mcptoon-0.7.17> wrapping `/nix/store/wfil1bf753n2g832mxmwx5qcjfyk9w0v-mcptoon-0.7.17/bin/mcptoon'... mcptoon-0.7.17> Executing pythonRemoveTestsDir mcptoon-0.7.17> Finished executing pythonRemoveTestsDir mcptoon-0.7.17> Running phase: installCheckPhase mcptoon-0.7.17> no Makefile or custom installCheckPhase, doing nothing mcptoon-0.7.17> Running phase: pythonCatchConflictsPhase mcptoon-0.7.17> Running phase: pythonRemoveBinBytecodePhase mcptoon-0.7.17> Running phase: pythonImportsCheckPhase mcptoon-0.7.17> Executing pythonImportsCheckPhase mcptoon-0.7.17> Check whether the following modules can be imported: mcptoon mcptoon-0.7.17> Running phase: pytestCheckPhase mcptoon-0.7.17> Executing pytestCheckPhase mcptoon-0.7.17> pytest flags: -m pytest mcptoon-0.7.17> ============================= test session starts ============================== mcptoon-0.7.17> platform linux -- Python 3.14.7, pytest-9.1.1, pluggy-1.6.0 mcptoon-0.7.17> rootdir: /build/source mcptoon-0.7.17> configfile: pyproject.toml mcptoon-0.7.17> testpaths: tests mcptoon-0.7.17> collected 1050 items mcptoon-0.7.17> mcptoon-0.7.17> tests/test_bench.py ............. [ 1%] mcptoon-0.7.17> tests/test_cache.py .... [ 1%] mcptoon-0.7.17> tests/test_calculator.py .......................... [ 4%] mcptoon-0.7.17> tests/test_claude_plugin_package.py ............. [ 5%] mcptoon-0.7.17> tests/test_cli_flags.py ........... [ 6%] mcptoon-0.7.17> tests/test_client.py .............................. [ 9%] mcptoon-0.7.17> tests/test_command_coverage.py .... [ 9%] mcptoon-0.7.17> tests/test_completion.py ........ [ 10%] mcptoon-0.7.17> tests/test_config.py ........ [ 11%] mcptoon-0.7.17> tests/test_dead_server_diagnostics.py ... [ 11%] mcptoon-0.7.17> tests/test_demo.py ..................... [ 13%] mcptoon-0.7.17> tests/test_demo_dead_package.py ........ [ 14%] mcptoon-0.7.17> tests/test_demo_server.py .............................................. [ 18%] mcptoon-0.7.17> ..... [ 19%] mcptoon-0.7.17> tests/test_discover.py ................................ [ 22%] mcptoon-0.7.17> tests/test_doctor_star_hint.py ..... [ 22%] mcptoon-0.7.17> tests/test_envelope.py ........ [ 23%] mcptoon-0.7.17> tests/test_fallback_json.py ...... [ 23%] mcptoon-0.7.17> tests/test_footprint_claims.py ............ [ 25%] mcptoon-0.7.17> tests/test_gemini_manifest.py ...... [ 25%] mcptoon-0.7.17> tests/test_health.py ............. [ 26%] mcptoon-0.7.17> tests/test_help_shortcircuit.py ......... [ 27%] mcptoon-0.7.17> tests/test_llms_txt.py ...... [ 28%] mcptoon-0.7.17> tests/test_native_tools.py ........................... [ 30%] mcptoon-0.7.17> tests/test_output.py ................................................... [ 35%] mcptoon-0.7.17> ........................................................................ [ 42%] mcptoon-0.7.17> ................ [ 44%] mcptoon-0.7.17> tests/test_plugin_install.py .......... [ 45%] mcptoon-0.7.17> tests/test_plugin_scan.py ............................... [ 48%] mcptoon-0.7.17> tests/test_policy_overrides.py ................ [ 49%] mcptoon-0.7.17> tests/test_readme_links.py ... [ 49%] mcptoon-0.7.17> tests/test_registry_sync.py ............ [ 50%] mcptoon-0.7.17> tests/test_router.py ............................................ [ 55%] mcptoon-0.7.17> tests/test_search.py ................................ [ 58%] mcptoon-0.7.17> tests/test_serve.py .................................................... [ 63%] mcptoon-0.7.17> ... [ 63%] mcptoon-0.7.17> tests/test_serve_perf.py .......... [ 64%] mcptoon-0.7.17> tests/test_serve_prompts.py ........ [ 65%] mcptoon-0.7.17> tests/test_skills.py ................................................... [ 70%] mcptoon-0.7.17> ................................FFF....... [ 74%] mcptoon-0.7.17> tests/test_stats_toggle.py ......... [ 74%] mcptoon-0.7.17> tests/test_sync.py ................ [ 76%] mcptoon-0.7.17> tests/test_tier_claims_consistent.py .... [ 76%] mcptoon-0.7.17> tests/test_toml_config.py .......................... [ 79%] mcptoon-0.7.17> tests/test_toon_cross_validate.py ............................... [ 82%] mcptoon-0.7.17> tests/test_v02_features.py .................................... [ 85%] mcptoon-0.7.17> tests/test_v04_features.py ................ [ 87%] mcptoon-0.7.17> tests/test_v05_features.py ...................... [ 89%] mcptoon-0.7.17> tests/test_v072_delight.py ..........s.. [ 90%] mcptoon-0.7.17> tests/test_v073_http_security.py .............................. [ 93%] mcptoon-0.7.17> tests/test_v074_stdio_timeout.py ............ [ 94%] mcptoon-0.7.17> tests/test_v076_stateless_serve.py ................... [ 96%] mcptoon-0.7.17> tests/test_v07_spec2026.py ..................... [ 98%] mcptoon-0.7.17> tests/test_watch.py .................. [100%] mcptoon-0.7.17> mcptoon-0.7.17> =================================== FAILURES =================================== mcptoon-0.7.17> _____ TombstoneTests.test_removal_uses_the_shared_graveyard_when_given_one _____ mcptoon-0.7.17> mcptoon-0.7.17> self = mcptoon-0.7.17> mcptoon-0.7.17> def setUp(self): mcptoon-0.7.17> self.tmp = tempfile.TemporaryDirectory() mcptoon-0.7.17> self.base = Path(self.tmp.name) mcptoon-0.7.17> self.repo = self.base / "repo" mcptoon-0.7.17> (self.repo / "skills" / "alpha").mkdir(parents=True) mcptoon-0.7.17> (self.repo / "skills" / "alpha" / "SKILL.md").write_text( mcptoon-0.7.17> "---\nname: alpha\ndescription: d\n---\n", encoding="utf-8") mcptoon-0.7.17> (self.repo / "unrelated.txt").write_text("keep me\n", encoding="utf-8") mcptoon-0.7.17> > self._git("init") mcptoon-0.7.17> mcptoon-0.7.17> tests/test_skills.py:940: mcptoon-0.7.17> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ mcptoon-0.7.17> tests/test_skills.py:951: in _git mcptoon-0.7.17> return subprocess.run(["git", *args], cwd=str(self.repo), mcptoon-0.7.17> /nix/store/d64q19q1xjdwfhqx6czvrjgrhq0n3lcc-python3-3.14.7/lib/python3.14/subprocess.py:555: in run mcptoon-0.7.17> with Popen(*popenargs, **kwargs) as process: mcptoon-0.7.17> ^^^^^^^^^^^^^^^^^^^^^^^^^^^ mcptoon-0.7.17> /nix/store/d64q19q1xjdwfhqx6czvrjgrhq0n3lcc-python3-3.14.7/lib/python3.14/subprocess.py:1039: in __init__ mcptoon-0.7.17> self._execute_child(args, executable, preexec_fn, close_fds, mcptoon-0.7.17> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ mcptoon-0.7.17> mcptoon-0.7.17> self = , args = ['git', 'init'] mcptoon-0.7.17> executable = b'git', preexec_fn = None, close_fds = True, pass_fds = () mcptoon-0.7.17> cwd = '/build/tmpqv_q5v69/repo', env = None, startupinfo = None mcptoon-0.7.17> creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 mcptoon-0.7.17> c2pwrite = 12, errread = 13, errwrite = 14, restore_signals = True, gid = None mcptoon-0.7.17> gids = None, uid = None, umask = -1, start_new_session = False mcptoon-0.7.17> process_group = -1 mcptoon-0.7.17> mcptoon-0.7.17> def _execute_child(self, args, executable, preexec_fn, close_fds, mcptoon-0.7.17> pass_fds, cwd, env, mcptoon-0.7.17> startupinfo, creationflags, shell, mcptoon-0.7.17> p2cread, p2cwrite, mcptoon-0.7.17> c2pread, c2pwrite, mcptoon-0.7.17> errread, errwrite, mcptoon-0.7.17> restore_signals, mcptoon-0.7.17> gid, gids, uid, umask, mcptoon-0.7.17> start_new_session, process_group): mcptoon-0.7.17> """Execute program (POSIX version)""" mcptoon-0.7.17> mcptoon-0.7.17> if isinstance(args, (str, bytes)): mcptoon-0.7.17> args = [args] mcptoon-0.7.17> elif isinstance(args, os.PathLike): mcptoon-0.7.17> if shell: mcptoon-0.7.17> raise TypeError('path-like args is not allowed when ' mcptoon-0.7.17> 'shell is true') mcptoon-0.7.17> args = [args] mcptoon-0.7.17> else: mcptoon-0.7.17> args = list(args) mcptoon-0.7.17> mcptoon-0.7.17> if shell: mcptoon-0.7.17> # On Android the default shell is at '/system/bin/sh'. mcptoon-0.7.17> unix_shell = ('/system/bin/sh' if mcptoon-0.7.17> hasattr(sys, 'getandroidapilevel') else '/nix/store/svx59425zxp552p2b8gm11qj5r09b56i-bash-5.3p15/bin/sh') mcptoon-0.7.17> args = [unix_shell, "-c"] + args mcptoon-0.7.17> if executable: mcptoon-0.7.17> args[0] = executable mcptoon-0.7.17> mcptoon-0.7.17> if executable is None: mcptoon-0.7.17> executable = args[0] mcptoon-0.7.17> mcptoon-0.7.17> sys.audit("subprocess.Popen", executable, args, cwd, env) mcptoon-0.7.17> mcptoon-0.7.17> if (_USE_POSIX_SPAWN mcptoon-0.7.17> and os.path.dirname(executable) mcptoon-0.7.17> and preexec_fn is None mcptoon-0.7.17> and (not close_fds or _HAVE_POSIX_SPAWN_CLOSEFROM) mcptoon-0.7.17> and not pass_fds mcptoon-0.7.17> and cwd is None mcptoon-0.7.17> and (p2cread == -1 or p2cread > 2) mcptoon-0.7.17> and (c2pwrite == -1 or c2pwrite > 2) mcptoon-0.7.17> and (errwrite == -1 or errwrite > 2) mcptoon-0.7.17> and not start_new_session mcptoon-0.7.17> and process_group == -1 mcptoon-0.7.17> and gid is None mcptoon-0.7.17> and gids is None mcptoon-0.7.17> and uid is None mcptoon-0.7.17> and umask < 0): mcptoon-0.7.17> self._posix_spawn(args, executable, env, restore_signals, close_fds, mcptoon-0.7.17> p2cread, p2cwrite, mcptoon-0.7.17> c2pread, c2pwrite, mcptoon-0.7.17> errread, errwrite) mcptoon-0.7.17> return mcptoon-0.7.17> mcptoon-0.7.17> orig_executable = executable mcptoon-0.7.17> mcptoon-0.7.17> # For transferring possible exec failure from child to parent. mcptoon-0.7.17> # Data format: "exception name:hex errno:description" mcptoon-0.7.17> # Pickle is not used; it is complex and involves memory allocation. mcptoon-0.7.17> errpipe_read, errpipe_write = os.pipe() mcptoon-0.7.17> # errpipe_write must not be in the standard io 0, 1, or 2 fd range. mcptoon-0.7.17> low_fds_to_close = [] mcptoon-0.7.17> while errpipe_write < 3: mcptoon-0.7.17> low_fds_to_close.append(errpipe_write) mcptoon-0.7.17> errpipe_write = os.dup(errpipe_write) mcptoon-0.7.17> for low_fd in low_fds_to_close: mcptoon-0.7.17> os.close(low_fd) mcptoon-0.7.17> try: mcptoon-0.7.17> try: mcptoon-0.7.17> # We must avoid complex work that could involve mcptoon-0.7.17> # malloc or free in the child process to avoid mcptoon-0.7.17> # potential deadlocks, thus we do all this here. mcptoon-0.7.17> # and pass it to fork_exec() mcptoon-0.7.17> mcptoon-0.7.17> if env is not None: mcptoon-0.7.17> env_list = [] mcptoon-0.7.17> for k, v in env.items(): mcptoon-0.7.17> k = os.fsencode(k) mcptoon-0.7.17> if b'=' in k: mcptoon-0.7.17> raise ValueError("illegal environment variable name") mcptoon-0.7.17> env_list.append(k + b'=' + os.fsencode(v)) mcptoon-0.7.17> else: mcptoon-0.7.17> env_list = None # Use execv instead of execve. mcptoon-0.7.17> executable = os.fsencode(executable) mcptoon-0.7.17> if os.path.dirname(executable): mcptoon-0.7.17> executable_list = (executable,) mcptoon-0.7.17> else: mcptoon-0.7.17> # This matches the behavior of os._execvpe(). mcptoon-0.7.17> executable_list = tuple( mcptoon-0.7.17> os.path.join(os.fsencode(dir), executable) mcptoon-0.7.17> for dir in os.get_exec_path(env)) mcptoon-0.7.17> fds_to_keep = set(pass_fds) mcptoon-0.7.17> fds_to_keep.add(errpipe_write) mcptoon-0.7.17> self.pid = _fork_exec( mcptoon-0.7.17> args, executable_list, mcptoon-0.7.17> close_fds, tuple(sorted(map(int, fds_to_keep))), mcptoon-0.7.17> cwd, env_list, mcptoon-0.7.17> p2cread, p2cwrite, c2pread, c2pwrite, mcptoon-0.7.17> errread, errwrite, mcptoon-0.7.17> errpipe_read, errpipe_write, mcptoon-0.7.17> restore_signals, start_new_session, mcptoon-0.7.17> process_group, gid, gids, uid, umask, mcptoon-0.7.17> preexec_fn) mcptoon-0.7.17> self._child_created = True mcptoon-0.7.17> finally: mcptoon-0.7.17> # be sure the FD is closed no matter what mcptoon-0.7.17> os.close(errpipe_write) mcptoon-0.7.17> mcptoon-0.7.17> self._close_pipe_fds(p2cread, p2cwrite, mcptoon-0.7.17> c2pread, c2pwrite, mcptoon-0.7.17> errread, errwrite) mcptoon-0.7.17> mcptoon-0.7.17> # Wait for exec to fail or succeed; possibly raising an mcptoon-0.7.17> # exception (limited in size) mcptoon-0.7.17> errpipe_data = bytearray() mcptoon-0.7.17> while True: mcptoon-0.7.17> part = os.read(errpipe_read, 50000) mcptoon-0.7.17> errpipe_data += part mcptoon-0.7.17> if not part or len(errpipe_data) > 50000: mcptoon-0.7.17> break mcptoon-0.7.17> finally: mcptoon-0.7.17> # be sure the FD is closed no matter what mcptoon-0.7.17> os.close(errpipe_read) mcptoon-0.7.17> mcptoon-0.7.17> if errpipe_data: mcptoon-0.7.17> try: mcptoon-0.7.17> pid, sts = os.waitpid(self.pid, 0) mcptoon-0.7.17> if pid == self.pid: mcptoon-0.7.17> self._handle_exitstatus(sts) mcptoon-0.7.17> else: mcptoon-0.7.17> self.returncode = sys.maxsize mcptoon-0.7.17> except ChildProcessError: mcptoon-0.7.17> pass mcptoon-0.7.17> mcptoon-0.7.17> try: mcptoon-0.7.17> exception_name, hex_errno, err_msg = ( mcptoon-0.7.17> errpipe_data.split(b':', 2)) mcptoon-0.7.17> # The encoding here should match the encoding mcptoon-0.7.17> # written in by the subprocess implementations mcptoon-0.7.17> # like _posixsubprocess mcptoon-0.7.17> err_msg = err_msg.decode() mcptoon-0.7.17> except ValueError: mcptoon-0.7.17> exception_name = b'SubprocessError' mcptoon-0.7.17> hex_errno = b'0' mcptoon-0.7.17> err_msg = 'Bad exception data from child: {!r}'.format( mcptoon-0.7.17> bytes(errpipe_data)) mcptoon-0.7.17> child_exception_type = getattr( mcptoon-0.7.17> builtins, exception_name.decode('ascii'), mcptoon-0.7.17> SubprocessError) mcptoon-0.7.17> if issubclass(child_exception_type, OSError) and hex_errno: mcptoon-0.7.17> errno_num = int(hex_errno, 16) mcptoon-0.7.17> if err_msg == "noexec:chdir": mcptoon-0.7.17> err_msg = "" mcptoon-0.7.17> # The error must be from chdir(cwd). mcptoon-0.7.17> err_filename = cwd mcptoon-0.7.17> elif err_msg == "noexec": mcptoon-0.7.17> err_msg = "" mcptoon-0.7.17> err_filename = None mcptoon-0.7.17> else: mcptoon-0.7.17> err_filename = orig_executable mcptoon-0.7.17> if errno_num != 0: mcptoon-0.7.17> err_msg = os.strerror(errno_num) mcptoon-0.7.17> if err_filename is not None: mcptoon-0.7.17> > raise child_exception_type(errno_num, err_msg, err_filename) mcptoon-0.7.17> E FileNotFoundError: [Errno 2] No such file or directory: 'git' mcptoon-0.7.17> mcptoon-0.7.17> /nix/store/d64q19q1xjdwfhqx6czvrjgrhq0n3lcc-python3-3.14.7/lib/python3.14/subprocess.py:1990: FileNotFoundError mcptoon-0.7.17> __________ TombstoneTests.test_removal_without_a_repo_still_archives ___________ mcptoon-0.7.17> mcptoon-0.7.17> self = mcptoon-0.7.17> mcptoon-0.7.17> def setUp(self): mcptoon-0.7.17> self.tmp = tempfile.TemporaryDirectory() mcptoon-0.7.17> self.base = Path(self.tmp.name) mcptoon-0.7.17> self.repo = self.base / "repo" mcptoon-0.7.17> (self.repo / "skills" / "alpha").mkdir(parents=True) mcptoon-0.7.17> (self.repo / "skills" / "alpha" / "SKILL.md").write_text( mcptoon-0.7.17> "---\nname: alpha\ndescription: d\n---\n", encoding="utf-8") mcptoon-0.7.17> (self.repo / "unrelated.txt").write_text("keep me\n", encoding="utf-8") mcptoon-0.7.17> > self._git("init") mcptoon-0.7.17> mcptoon-0.7.17> tests/test_skills.py:940: mcptoon-0.7.17> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ mcptoon-0.7.17> tests/test_skills.py:951: in _git mcptoon-0.7.17> return subprocess.run(["git", *args], cwd=str(self.repo), mcptoon-0.7.17> /nix/store/d64q19q1xjdwfhqx6czvrjgrhq0n3lcc-python3-3.14.7/lib/python3.14/subprocess.py:555: in run mcptoon-0.7.17> with Popen(*popenargs, **kwargs) as process: mcptoon-0.7.17> ^^^^^^^^^^^^^^^^^^^^^^^^^^^ mcptoon-0.7.17> /nix/store/d64q19q1xjdwfhqx6czvrjgrhq0n3lcc-python3-3.14.7/lib/python3.14/subprocess.py:1039: in __init__ mcptoon-0.7.17> self._execute_child(args, executable, preexec_fn, close_fds, mcptoon-0.7.17> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ mcptoon-0.7.17> mcptoon-0.7.17> self = , args = ['git', 'init'] mcptoon-0.7.17> executable = b'git', preexec_fn = None, close_fds = True, pass_fds = () mcptoon-0.7.17> cwd = '/build/tmp1742pfpt/repo', env = None, startupinfo = None mcptoon-0.7.17> creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 mcptoon-0.7.17> c2pwrite = 12, errread = 13, errwrite = 14, restore_signals = True, gid = None mcptoon-0.7.17> gids = None, uid = None, umask = -1, start_new_session = False mcptoon-0.7.17> process_group = -1 mcptoon-0.7.17> mcptoon-0.7.17> def _execute_child(self, args, executable, preexec_fn, close_fds, mcptoon-0.7.17> pass_fds, cwd, env, mcptoon-0.7.17> startupinfo, creationflags, shell, mcptoon-0.7.17> p2cread, p2cwrite, mcptoon-0.7.17> c2pread, c2pwrite, mcptoon-0.7.17> errread, errwrite, mcptoon-0.7.17> restore_signals, mcptoon-0.7.17> gid, gids, uid, umask, mcptoon-0.7.17> start_new_session, process_group): mcptoon-0.7.17> """Execute program (POSIX version)""" mcptoon-0.7.17> mcptoon-0.7.17> if isinstance(args, (str, bytes)): mcptoon-0.7.17> args = [args] mcptoon-0.7.17> elif isinstance(args, os.PathLike): mcptoon-0.7.17> if shell: mcptoon-0.7.17> raise TypeError('path-like args is not allowed when ' mcptoon-0.7.17> 'shell is true') mcptoon-0.7.17> args = [args] mcptoon-0.7.17> else: mcptoon-0.7.17> args = list(args) mcptoon-0.7.17> mcptoon-0.7.17> if shell: mcptoon-0.7.17> # On Android the default shell is at '/system/bin/sh'. mcptoon-0.7.17> unix_shell = ('/system/bin/sh' if mcptoon-0.7.17> hasattr(sys, 'getandroidapilevel') else '/nix/store/svx59425zxp552p2b8gm11qj5r09b56i-bash-5.3p15/bin/sh') mcptoon-0.7.17> args = [unix_shell, "-c"] + args mcptoon-0.7.17> if executable: mcptoon-0.7.17> args[0] = executable mcptoon-0.7.17> mcptoon-0.7.17> if executable is None: mcptoon-0.7.17> executable = args[0] mcptoon-0.7.17> mcptoon-0.7.17> sys.audit("subprocess.Popen", executable, args, cwd, env) mcptoon-0.7.17> mcptoon-0.7.17> if (_USE_POSIX_SPAWN mcptoon-0.7.17> and os.path.dirname(executable) mcptoon-0.7.17> and preexec_fn is None mcptoon-0.7.17> and (not close_fds or _HAVE_POSIX_SPAWN_CLOSEFROM) mcptoon-0.7.17> and not pass_fds mcptoon-0.7.17> and cwd is None mcptoon-0.7.17> and (p2cread == -1 or p2cread > 2) mcptoon-0.7.17> and (c2pwrite == -1 or c2pwrite > 2) mcptoon-0.7.17> and (errwrite == -1 or errwrite > 2) mcptoon-0.7.17> and not start_new_session mcptoon-0.7.17> and process_group == -1 mcptoon-0.7.17> and gid is None mcptoon-0.7.17> and gids is None mcptoon-0.7.17> and uid is None mcptoon-0.7.17> and umask < 0): mcptoon-0.7.17> self._posix_spawn(args, executable, env, restore_signals, close_fds, mcptoon-0.7.17> p2cread, p2cwrite, mcptoon-0.7.17> c2pread, c2pwrite, mcptoon-0.7.17> errread, errwrite) mcptoon-0.7.17> return mcptoon-0.7.17> mcptoon-0.7.17> orig_executable = executable mcptoon-0.7.17> mcptoon-0.7.17> # For transferring possible exec failure from child to parent. mcptoon-0.7.17> # Data format: "exception name:hex errno:description" mcptoon-0.7.17> # Pickle is not used; it is complex and involves memory allocation. mcptoon-0.7.17> errpipe_read, errpipe_write = os.pipe() mcptoon-0.7.17> # errpipe_write must not be in the standard io 0, 1, or 2 fd range. mcptoon-0.7.17> low_fds_to_close = [] mcptoon-0.7.17> while errpipe_write < 3: mcptoon-0.7.17> low_fds_to_close.append(errpipe_write) mcptoon-0.7.17> errpipe_write = os.dup(errpipe_write) mcptoon-0.7.17> for low_fd in low_fds_to_close: mcptoon-0.7.17> os.close(low_fd) mcptoon-0.7.17> try: mcptoon-0.7.17> try: mcptoon-0.7.17> # We must avoid complex work that could involve mcptoon-0.7.17> # malloc or free in the child process to avoid mcptoon-0.7.17> # potential deadlocks, thus we do all this here. mcptoon-0.7.17> # and pass it to fork_exec() mcptoon-0.7.17> mcptoon-0.7.17> if env is not None: mcptoon-0.7.17> env_list = [] mcptoon-0.7.17> for k, v in env.items(): mcptoon-0.7.17> k = os.fsencode(k) mcptoon-0.7.17> if b'=' in k: mcptoon-0.7.17> raise ValueError("illegal environment variable name") mcptoon-0.7.17> env_list.append(k + b'=' + os.fsencode(v)) mcptoon-0.7.17> else: mcptoon-0.7.17> env_list = None # Use execv instead of execve. mcptoon-0.7.17> executable = os.fsencode(executable) mcptoon-0.7.17> if os.path.dirname(executable): mcptoon-0.7.17> executable_list = (executable,) mcptoon-0.7.17> else: mcptoon-0.7.17> # This matches the behavior of os._execvpe(). mcptoon-0.7.17> executable_list = tuple( mcptoon-0.7.17> os.path.join(os.fsencode(dir), executable) mcptoon-0.7.17> for dir in os.get_exec_path(env)) mcptoon-0.7.17> fds_to_keep = set(pass_fds) mcptoon-0.7.17> fds_to_keep.add(errpipe_write) mcptoon-0.7.17> self.pid = _fork_exec( mcptoon-0.7.17> args, executable_list, mcptoon-0.7.17> close_fds, tuple(sorted(map(int, fds_to_keep))), mcptoon-0.7.17> cwd, env_list, mcptoon-0.7.17> p2cread, p2cwrite, c2pread, c2pwrite, mcptoon-0.7.17> errread, errwrite, mcptoon-0.7.17> errpipe_read, errpipe_write, mcptoon-0.7.17> restore_signals, start_new_session, mcptoon-0.7.17> process_group, gid, gids, uid, umask, mcptoon-0.7.17> preexec_fn) mcptoon-0.7.17> self._child_created = True mcptoon-0.7.17> finally: mcptoon-0.7.17> # be sure the FD is closed no matter what mcptoon-0.7.17> os.close(errpipe_write) mcptoon-0.7.17> mcptoon-0.7.17> self._close_pipe_fds(p2cread, p2cwrite, mcptoon-0.7.17> c2pread, c2pwrite, mcptoon-0.7.17> errread, errwrite) mcptoon-0.7.17> mcptoon-0.7.17> # Wait for exec to fail or succeed; possibly raising an mcptoon-0.7.17> # exception (limited in size) mcptoon-0.7.17> errpipe_data = bytearray() mcptoon-0.7.17> while True: mcptoon-0.7.17> part = os.read(errpipe_read, 50000) mcptoon-0.7.17> errpipe_data += part mcptoon-0.7.17> if not part or len(errpipe_data) > 50000: mcptoon-0.7.17> break mcptoon-0.7.17> finally: mcptoon-0.7.17> # be sure the FD is closed no matter what mcptoon-0.7.17> os.close(errpipe_read) mcptoon-0.7.17> mcptoon-0.7.17> if errpipe_data: mcptoon-0.7.17> try: mcptoon-0.7.17> pid, sts = os.waitpid(self.pid, 0) mcptoon-0.7.17> if pid == self.pid: mcptoon-0.7.17> self._handle_exitstatus(sts) mcptoon-0.7.17> else: mcptoon-0.7.17> self.returncode = sys.maxsize mcptoon-0.7.17> except ChildProcessError: mcptoon-0.7.17> pass mcptoon-0.7.17> mcptoon-0.7.17> try: mcptoon-0.7.17> exception_name, hex_errno, err_msg = ( mcptoon-0.7.17> errpipe_data.split(b':', 2)) mcptoon-0.7.17> # The encoding here should match the encoding mcptoon-0.7.17> # written in by the subprocess implementations mcptoon-0.7.17> # like _posixsubprocess mcptoon-0.7.17> err_msg = err_msg.decode() mcptoon-0.7.17> except ValueError: mcptoon-0.7.17> exception_name = b'SubprocessError' mcptoon-0.7.17> hex_errno = b'0' mcptoon-0.7.17> err_msg = 'Bad exception data from child: {!r}'.format( mcptoon-0.7.17> bytes(errpipe_data)) mcptoon-0.7.17> child_exception_type = getattr( mcptoon-0.7.17> builtins, exception_name.decode('ascii'), mcptoon-0.7.17> SubprocessError) mcptoon-0.7.17> if issubclass(child_exception_type, OSError) and hex_errno: mcptoon-0.7.17> errno_num = int(hex_errno, 16) mcptoon-0.7.17> if err_msg == "noexec:chdir": mcptoon-0.7.17> err_msg = "" mcptoon-0.7.17> # The error must be from chdir(cwd). mcptoon-0.7.17> err_filename = cwd mcptoon-0.7.17> elif err_msg == "noexec": mcptoon-0.7.17> err_msg = "" mcptoon-0.7.17> err_filename = None mcptoon-0.7.17> else: mcptoon-0.7.17> err_filename = orig_executable mcptoon-0.7.17> if errno_num != 0: mcptoon-0.7.17> err_msg = os.strerror(errno_num) mcptoon-0.7.17> if err_filename is not None: mcptoon-0.7.17> > raise child_exception_type(errno_num, err_msg, err_filename) mcptoon-0.7.17> E FileNotFoundError: [Errno 2] No such file or directory: 'git' mcptoon-0.7.17> mcptoon-0.7.17> /nix/store/d64q19q1xjdwfhqx6czvrjgrhq0n3lcc-python3-3.14.7/lib/python3.14/subprocess.py:1990: FileNotFoundError mcptoon-0.7.17> _________ TombstoneTests.test_tombstone_commits_only_the_removed_path __________ mcptoon-0.7.17> mcptoon-0.7.17> self = mcptoon-0.7.17> mcptoon-0.7.17> def setUp(self): mcptoon-0.7.17> self.tmp = tempfile.TemporaryDirectory() mcptoon-0.7.17> self.base = Path(self.tmp.name) mcptoon-0.7.17> self.repo = self.base / "repo" mcptoon-0.7.17> (self.repo / "skills" / "alpha").mkdir(parents=True) mcptoon-0.7.17> (self.repo / "skills" / "alpha" / "SKILL.md").write_text( mcptoon-0.7.17> "---\nname: alpha\ndescription: d\n---\n", encoding="utf-8") mcptoon-0.7.17> (self.repo / "unrelated.txt").write_text("keep me\n", encoding="utf-8") mcptoon-0.7.17> > self._git("init") mcptoon-0.7.17> mcptoon-0.7.17> tests/test_skills.py:940: mcptoon-0.7.17> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ mcptoon-0.7.17> tests/test_skills.py:951: in _git mcptoon-0.7.17> return subprocess.run(["git", *args], cwd=str(self.repo), mcptoon-0.7.17> /nix/store/d64q19q1xjdwfhqx6czvrjgrhq0n3lcc-python3-3.14.7/lib/python3.14/subprocess.py:555: in run mcptoon-0.7.17> with Popen(*popenargs, **kwargs) as process: mcptoon-0.7.17> ^^^^^^^^^^^^^^^^^^^^^^^^^^^ mcptoon-0.7.17> /nix/store/d64q19q1xjdwfhqx6czvrjgrhq0n3lcc-python3-3.14.7/lib/python3.14/subprocess.py:1039: in __init__ mcptoon-0.7.17> self._execute_child(args, executable, preexec_fn, close_fds, mcptoon-0.7.17> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ mcptoon-0.7.17> mcptoon-0.7.17> self = , args = ['git', 'init'] mcptoon-0.7.17> executable = b'git', preexec_fn = None, close_fds = True, pass_fds = () mcptoon-0.7.17> cwd = '/build/tmp2ty_d45n/repo', env = None, startupinfo = None mcptoon-0.7.17> creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 mcptoon-0.7.17> c2pwrite = 12, errread = 13, errwrite = 14, restore_signals = True, gid = None mcptoon-0.7.17> gids = None, uid = None, umask = -1, start_new_session = False mcptoon-0.7.17> process_group = -1 mcptoon-0.7.17> mcptoon-0.7.17> def _execute_child(self, args, executable, preexec_fn, close_fds, mcptoon-0.7.17> pass_fds, cwd, env, mcptoon-0.7.17> startupinfo, creationflags, shell, mcptoon-0.7.17> p2cread, p2cwrite, mcptoon-0.7.17> c2pread, c2pwrite, mcptoon-0.7.17> errread, errwrite, mcptoon-0.7.17> restore_signals, mcptoon-0.7.17> gid, gids, uid, umask, mcptoon-0.7.17> start_new_session, process_group): mcptoon-0.7.17> """Execute program (POSIX version)""" mcptoon-0.7.17> mcptoon-0.7.17> if isinstance(args, (str, bytes)): mcptoon-0.7.17> args = [args] mcptoon-0.7.17> elif isinstance(args, os.PathLike): mcptoon-0.7.17> if shell: mcptoon-0.7.17> raise TypeError('path-like args is not allowed when ' mcptoon-0.7.17> 'shell is true') mcptoon-0.7.17> args = [args] mcptoon-0.7.17> else: mcptoon-0.7.17> args = list(args) mcptoon-0.7.17> mcptoon-0.7.17> if shell: mcptoon-0.7.17> # On Android the default shell is at '/system/bin/sh'. mcptoon-0.7.17> unix_shell = ('/system/bin/sh' if mcptoon-0.7.17> hasattr(sys, 'getandroidapilevel') else '/nix/store/svx59425zxp552p2b8gm11qj5r09b56i-bash-5.3p15/bin/sh') mcptoon-0.7.17> args = [unix_shell, "-c"] + args mcptoon-0.7.17> if executable: mcptoon-0.7.17> args[0] = executable mcptoon-0.7.17> mcptoon-0.7.17> if executable is None: mcptoon-0.7.17> executable = args[0] mcptoon-0.7.17> mcptoon-0.7.17> sys.audit("subprocess.Popen", executable, args, cwd, env) mcptoon-0.7.17> mcptoon-0.7.17> if (_USE_POSIX_SPAWN mcptoon-0.7.17> and os.path.dirname(executable) mcptoon-0.7.17> and preexec_fn is None mcptoon-0.7.17> and (not close_fds or _HAVE_POSIX_SPAWN_CLOSEFROM) mcptoon-0.7.17> and not pass_fds mcptoon-0.7.17> and cwd is None mcptoon-0.7.17> and (p2cread == -1 or p2cread > 2) mcptoon-0.7.17> and (c2pwrite == -1 or c2pwrite > 2) mcptoon-0.7.17> and (errwrite == -1 or errwrite > 2) mcptoon-0.7.17> and not start_new_session mcptoon-0.7.17> and process_group == -1 mcptoon-0.7.17> and gid is None mcptoon-0.7.17> and gids is None mcptoon-0.7.17> and uid is None mcptoon-0.7.17> and umask < 0): mcptoon-0.7.17> self._posix_spawn(args, executable, env, restore_signals, close_fds, mcptoon-0.7.17> p2cread, p2cwrite, mcptoon-0.7.17> c2pread, c2pwrite, mcptoon-0.7.17> errread, errwrite) mcptoon-0.7.17> return mcptoon-0.7.17> mcptoon-0.7.17> orig_executable = executable mcptoon-0.7.17> mcptoon-0.7.17> # For transferring possible exec failure from child to parent. mcptoon-0.7.17> # Data format: "exception name:hex errno:description" mcptoon-0.7.17> # Pickle is not used; it is complex and involves memory allocation. mcptoon-0.7.17> errpipe_read, errpipe_write = os.pipe() mcptoon-0.7.17> # errpipe_write must not be in the standard io 0, 1, or 2 fd range. mcptoon-0.7.17> low_fds_to_close = [] mcptoon-0.7.17> while errpipe_write < 3: mcptoon-0.7.17> low_fds_to_close.append(errpipe_write) mcptoon-0.7.17> errpipe_write = os.dup(errpipe_write) mcptoon-0.7.17> for low_fd in low_fds_to_close: mcptoon-0.7.17> os.close(low_fd) mcptoon-0.7.17> try: mcptoon-0.7.17> try: mcptoon-0.7.17> # We must avoid complex work that could involve mcptoon-0.7.17> # malloc or free in the child process to avoid mcptoon-0.7.17> # potential deadlocks, thus we do all this here. mcptoon-0.7.17> # and pass it to fork_exec() mcptoon-0.7.17> mcptoon-0.7.17> if env is not None: mcptoon-0.7.17> env_list = [] mcptoon-0.7.17> for k, v in env.items(): mcptoon-0.7.17> k = os.fsencode(k) mcptoon-0.7.17> if b'=' in k: mcptoon-0.7.17> raise ValueError("illegal environment variable name") mcptoon-0.7.17> env_list.append(k + b'=' + os.fsencode(v)) mcptoon-0.7.17> else: mcptoon-0.7.17> env_list = None # Use execv instead of execve. mcptoon-0.7.17> executable = os.fsencode(executable) mcptoon-0.7.17> if os.path.dirname(executable): mcptoon-0.7.17> executable_list = (executable,) mcptoon-0.7.17> else: mcptoon-0.7.17> # This matches the behavior of os._execvpe(). mcptoon-0.7.17> executable_list = tuple( mcptoon-0.7.17> os.path.join(os.fsencode(dir), executable) mcptoon-0.7.17> for dir in os.get_exec_path(env)) mcptoon-0.7.17> fds_to_keep = set(pass_fds) mcptoon-0.7.17> fds_to_keep.add(errpipe_write) mcptoon-0.7.17> self.pid = _fork_exec( mcptoon-0.7.17> args, executable_list, mcptoon-0.7.17> close_fds, tuple(sorted(map(int, fds_to_keep))), mcptoon-0.7.17> cwd, env_list, mcptoon-0.7.17> p2cread, p2cwrite, c2pread, c2pwrite, mcptoon-0.7.17> errread, errwrite, mcptoon-0.7.17> errpipe_read, errpipe_write, mcptoon-0.7.17> restore_signals, start_new_session, mcptoon-0.7.17> process_group, gid, gids, uid, umask, mcptoon-0.7.17> preexec_fn) mcptoon-0.7.17> self._child_created = True mcptoon-0.7.17> finally: mcptoon-0.7.17> # be sure the FD is closed no matter what mcptoon-0.7.17> os.close(errpipe_write) mcptoon-0.7.17> mcptoon-0.7.17> self._close_pipe_fds(p2cread, p2cwrite, mcptoon-0.7.17> c2pread, c2pwrite, mcptoon-0.7.17> errread, errwrite) mcptoon-0.7.17> mcptoon-0.7.17> # Wait for exec to fail or succeed; possibly raising an mcptoon-0.7.17> # exception (limited in size) mcptoon-0.7.17> errpipe_data = bytearray() mcptoon-0.7.17> while True: mcptoon-0.7.17> part = os.read(errpipe_read, 50000) mcptoon-0.7.17> errpipe_data += part mcptoon-0.7.17> if not part or len(errpipe_data) > 50000: mcptoon-0.7.17> break mcptoon-0.7.17> finally: mcptoon-0.7.17> # be sure the FD is closed no matter what mcptoon-0.7.17> os.close(errpipe_read) mcptoon-0.7.17> mcptoon-0.7.17> if errpipe_data: mcptoon-0.7.17> try: mcptoon-0.7.17> pid, sts = os.waitpid(self.pid, 0) mcptoon-0.7.17> if pid == self.pid: mcptoon-0.7.17> self._handle_exitstatus(sts) mcptoon-0.7.17> else: mcptoon-0.7.17> self.returncode = sys.maxsize mcptoon-0.7.17> except ChildProcessError: mcptoon-0.7.17> pass mcptoon-0.7.17> mcptoon-0.7.17> try: mcptoon-0.7.17> exception_name, hex_errno, err_msg = ( mcptoon-0.7.17> errpipe_data.split(b':', 2)) mcptoon-0.7.17> # The encoding here should match the encoding mcptoon-0.7.17> # written in by the subprocess implementations mcptoon-0.7.17> # like _posixsubprocess mcptoon-0.7.17> err_msg = err_msg.decode() mcptoon-0.7.17> except ValueError: mcptoon-0.7.17> exception_name = b'SubprocessError' mcptoon-0.7.17> hex_errno = b'0' mcptoon-0.7.17> err_msg = 'Bad exception data from child: {!r}'.format( mcptoon-0.7.17> bytes(errpipe_data)) mcptoon-0.7.17> child_exception_type = getattr( mcptoon-0.7.17> builtins, exception_name.decode('ascii'), mcptoon-0.7.17> SubprocessError) mcptoon-0.7.17> if issubclass(child_exception_type, OSError) and hex_errno: mcptoon-0.7.17> errno_num = int(hex_errno, 16) mcptoon-0.7.17> if err_msg == "noexec:chdir": mcptoon-0.7.17> err_msg = "" mcptoon-0.7.17> # The error must be from chdir(cwd). mcptoon-0.7.17> err_filename = cwd mcptoon-0.7.17> elif err_msg == "noexec": mcptoon-0.7.17> err_msg = "" mcptoon-0.7.17> err_filename = None mcptoon-0.7.17> else: mcptoon-0.7.17> err_filename = orig_executable mcptoon-0.7.17> if errno_num != 0: mcptoon-0.7.17> err_msg = os.strerror(errno_num) mcptoon-0.7.17> if err_filename is not None: mcptoon-0.7.17> > raise child_exception_type(errno_num, err_msg, err_filename) mcptoon-0.7.17> E FileNotFoundError: [Errno 2] No such file or directory: 'git' mcptoon-0.7.17> mcptoon-0.7.17> /nix/store/d64q19q1xjdwfhqx6czvrjgrhq0n3lcc-python3-3.14.7/lib/python3.14/subprocess.py:1990: FileNotFoundError mcptoon-0.7.17> =========================== short test summary info ============================ mcptoon-0.7.17> FAILED tests/test_skills.py::TombstoneTests::test_removal_uses_the_shared_graveyard_when_given_one - FileNotFoundError: [Errno 2] No such file or directory: 'git' mcptoon-0.7.17> FAILED tests/test_skills.py::TombstoneTests::test_removal_without_a_repo_still_archives - FileNotFoundError: [Errno 2] No such file or directory: 'git' mcptoon-0.7.17> FAILED tests/test_skills.py::TombstoneTests::test_tombstone_commits_only_the_removed_path - FileNotFoundError: [Errno 2] No such file or directory: 'git' mcptoon-0.7.17> ============= 3 failed, 1046 passed, 1 skipped in 62.70s (0:01:02) ============= error: Cannot build '/nix/store/s5yfiyv3br3dvxp1b7nizjnagfm5s00k-mcptoon-0.7.17.drv'. Reason: builder failed with exit code 1. Output paths: /nix/store/7nrcv55v6z2xwqjmzhlqw48yd16icds6-mcptoon-0.7.17-dist /nix/store/wfil1bf753n2g832mxmwx5qcjfyk9w0v-mcptoon-0.7.17 Last 25 log lines: > builtins, exception_name.decode('ascii'), > SubprocessError) > if issubclass(child_exception_type, OSError) and hex_errno: > errno_num = int(hex_errno, 16) > if err_msg == "noexec:chdir": > err_msg = "" > # The error must be from chdir(cwd). > err_filename = cwd > elif err_msg == "noexec": > err_msg = "" > err_filename = None > else: > err_filename = orig_executable > if errno_num != 0: > err_msg = os.strerror(errno_num) > if err_filename is not None: > > raise child_exception_type(errno_num, err_msg, err_filename) > E FileNotFoundError: [Errno 2] No such file or directory: 'git' > > /nix/store/d64q19q1xjdwfhqx6czvrjgrhq0n3lcc-python3-3.14.7/lib/python3.14/subprocess.py:1990: FileNotFoundError > =========================== short test summary info ============================ > FAILED tests/test_skills.py::TombstoneTests::test_removal_uses_the_shared_graveyard_when_given_one - FileNotFoundError: [Errno 2] No such file or directory: 'git' > FAILED tests/test_skills.py::TombstoneTests::test_removal_without_a_repo_still_archives - FileNotFoundError: [Errno 2] No such file or directory: 'git' > FAILED tests/test_skills.py::TombstoneTests::test_tombstone_commits_only_the_removed_path - FileNotFoundError: [Errno 2] No such file or directory: 'git' > ============= 3 failed, 1046 passed, 1 skipped in 62.70s (0:01:02) ============= For full logs, run: nix log /nix/store/s5yfiyv3br3dvxp1b7nizjnagfm5s00k-mcptoon-0.7.17.drv