Ray's Knowledge Base

Run the Python suite and the docs build without installing anything

RecipeVerified 27 Sep 2026Holds project: dftracer-utils
Recipe. When to use it, the steps, and what showed that they work.

When to use#

Use this when you changed C++ that the Python extension builds, or Python code, and must run tests/python or the Sphinx docs, but the active environment has no editable install and you must not install tools (no pip install, no brew, no npm -g).

Steps#

  1. Build the tests preset, which also builds the extension: cmake --build --preset tests.

  2. Make a scratch package from the source tree and the built extension. $SCRATCH is any scratch folder:

    rm -rf $SCRATCH/pypkg/dftracer && mkdir -p $SCRATCH/pypkg
    cp -R python/dftracer $SCRATCH/pypkg/
    cp build/build-tests/dftracer/utils/dftracer_utils_ext.cpython-314-darwin.so \
       $SCRATCH/pypkg/dftracer/utils/
    

    Copy again after every edit to python/ or rebuild of the extension; the copy does not follow the tree.

  3. Run the suite in a throwaway uv environment. Set DFTRACER_PLUGIN_INCLUDE, because the scratch package has no include/ folder for the plugin build tests:

    DFTRACER_PLUGIN_INCLUDE=$PWD/include PYTHONPATH=$SCRATCH/pypkg \
      uv run --no-project -p 3.14 --with pytest --with pyarrow \
      --with typing_extensions --with pandas --with polars --with numpy \
      --with dask --with distributed \
      python -m pytest tests/python -q -p no:cacheprovider
    

    Without --with dask --with distributed, the distributed tests are skipped.

    The tests build is instrumented for coverage, so the run ends with many profiling: ... .gcda: cannot merge previous GCDA file lines that push the pytest summary out of tail. Append 2>&1 | grep -v '^profiling:' | tail -3 to see the summary.

  4. Build the docs the same way:

    PYTHONPATH=$SCRATCH/pypkg uv run --no-project -p 3.14 \
      --with-requirements docs/requirements.txt \
      sphinx-build -j auto -q docs/source $SCRATCH/html
    

    Compare the warnings with a run before your change: the autodoc: failed to import 'dfanalyzer...' warnings were already there.

  5. Run the linters with uvx ruff check python/ tests/python/, uvx ruff format --check python/ tests/python/ and uvx ty check python/.

Evidence#

  • Plain python3 -m pytest tests/python (system Python, no install) stops at collection: ModuleNotFoundError: No module named 'dftracer'. python is not on PATH.
  • Without DFTRACER_PLUGIN_INCLUDE: PluginBuildError: cannot locate the plugin include dir; set DFTRACER_PLUGIN_INCLUDE in tests/python/test_op_run.py.
  • Plain sphinx-build exited 127 (command not found); the uv run --with-requirements docs/requirements.txt form built with rc 0 and 16 warnings, all from dfanalyzer autodoc imports.
  • Suite results on macOS with Python 3.14: 1102 passed, 52 skipped without dask; 1131 passed, 23 skipped with dask and distributed.