@@ -113,13 +113,60 @@ set(PYBIND11_FINDPYTHON
113113 ${_pybind11_findpython_default}
114114 CACHE STRING "Force new FindPython - NEW, OLD, COMPAT" )
115115
116- # Allow PYTHON_EXECUTABLE if in FINDPYTHON mode and building pybind11's tests
117- # (makes transition easier while we support both modes).
118- if (PYBIND11_MASTER_PROJECT
119- AND PYBIND11_FINDPYTHON
120- AND DEFINED PYTHON_EXECUTABLE
121- AND NOT DEFINED Python_EXECUTABLE)
122- set (Python_EXECUTABLE "${PYTHON_EXECUTABLE} " )
116+ if (PYBIND11_MASTER_PROJECT)
117+
118+ # Allow PYTHON_EXECUTABLE if in FINDPYTHON mode and building pybind11's tests
119+ # (makes transition easier while we support both modes).
120+ if (PYBIND11_FINDPYTHON
121+ AND DEFINED PYTHON_EXECUTABLE
122+ AND NOT DEFINED Python_EXECUTABLE)
123+ set (Python_EXECUTABLE "${PYTHON_EXECUTABLE} " )
124+ endif ()
125+
126+ if (NOT DEFINED Python3_EXECUTABLE
127+ AND NOT DEFINED Python_EXECUTABLE
128+ AND NOT DEFINED Python_ROOT_DIR
129+ AND NOT DEFINED ENV{VIRTUALENV}
130+ AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR} /.venv" )
131+ message (STATUS "Autodetecting Python in virtual environment" )
132+ set (Python_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR} /.venv" )
133+ endif ()
134+
135+ # This is a shortcut that is primarily for the venv cmake preset,
136+ # but can be used to quickly setup tests manually, too
137+ set (PYBIND11_CREATE_WITH_UV
138+ ""
139+ CACHE STRING "Create a virtualenv in Python_ROOT_DIR with uv if it doesn't exist" )
140+
141+ if (NOT PYBIND11_CREATE_WITH_UV STREQUAL "" )
142+ if (NOT DEFINED Python_ROOT_DIR)
143+ message (FATAL_ERROR "Python_ROOT_DIR must be defined to use PYBIND11_CREATE_WITH_UV" )
144+ endif ()
145+ if (EXISTS "${Python_ROOT_DIR} " )
146+ message (STATUS "Using existing venv at ${Python_ROOT_DIR} , remove to recreate" )
147+ else ()
148+ find_program (UV uv REQUIRED )
149+ # CMake 3.19+ would be able to use COMMAND_ERROR_IS_FATAL
150+ message (
151+ STATUS "Creating venv with ${UV} venv -p ${PYBIND11_CREATE_WITH_UV} '${Python_ROOT_DIR} '" )
152+ execute_process (COMMAND ${UV} venv -p ${PYBIND11_CREATE_WITH_UV} "${Python_ROOT_DIR} "
153+ RESULT_VARIABLE _venv_result )
154+ if (_venv_result AND NOT _venv_result EQUAL 0)
155+ message (FATAL_ERROR "uv venv failed with '${_venv_result} '" )
156+ endif ()
157+ message (
158+ STATUS
159+ "Installing deps with ${UV} pip install -p '${Python_ROOT_DIR} ' -r tests/requirements.txt"
160+ )
161+ execute_process (
162+ COMMAND ${UV} pip install -p "${Python_ROOT_DIR} " -r
163+ "${CMAKE_CURRENT_SOURCE_DIR} /tests/requirements.txt" RESULT_VARIABLE _pip_result )
164+ if (_pip_result AND NOT _pip_result EQUAL 0)
165+ message (FATAL_ERROR "uv pip install failed with '${_pip_result} '" )
166+ endif ()
167+ endif ()
168+ endif ()
169+
123170endif ()
124171
125172# NB: when adding a header don't forget to also add it to setup.py
0 commit comments