Using set_tests_properties for setting or unsetting multiple variables

I’d like to use CTest to run some Python scripts; however, I need to run them with a different version of Python from the one which my system defaults to.

Getting the tests to run with the correct version of Python is easy enough: I just make sure that PYTHON_EXECUTABLE is defined correctly and then:

add_test(NAME SimplePythonTest
         COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/SimpleTest.py 
         WORKING_DIRECTORY ${my_home})

However, if this is all I do, then the global PYTHONPATH and PYTHONHOME environment variables still point to the system default version, and this will cause the tests to fail. As it happens, all the Python modules I want to use are in my custom version’s site-packages and it can find them directly, so if I run the tests from the command line (i.e. not via CMake at all) then all I have to do is type:

set PYTHONHOME=
set PYTHONPATH=

… and then it works.

I can’t find a syntax to do the equivalent for CTest, though. Alongside many other guesses which gave configuration-time errors, I’ve tried both:

set_tests_properties(SimplePythonTest
                     PROPERTIES ENVIRONMENT "PYTHONHOME="
                                ENVIRONMENT "PYTHONPATH=")

and

set_tests_properties(SimplePythonTest
                     PROPERTIES ENVIRONMENT PYTHONHOME=${THE_CORRECT_PYTHONHOME}
                                ENVIRONMENT PYTHONPATH=${THE_CORRECT_PYTHONPATH})

…but neither works. If I run the tests with CTest --verbose then the output shows:

1354: Environment variables:
1354: PYTHONPATH=
1354: Test timeout computed to be: 10000000

or

1354: Environment variables:
1354:  PYTHONPATH=< the correct path that I specified >
1354: Test timeout computed to be: 10000000

…which seems to indicate that set_tests_properties is only setting PYTHONPATH and leaving PYTHONHOME at its default.

So, what is the correct syntax for setting (or, preferably, unsetting altogether) both environment variables simultaneously?

The ENVIRONMENT property is meant to be a list. Try:

set_tests_properties(SimplePythonTest
                     PROPERTIES ENVIRONMENT "PYTHONHOME=;PYTHONPATH=")

By the way, you should consider finding Python using the standard FindPython module and then using the imported target Python::Interpreter in place of a custom PYTHON_EXECUTABLE variable.

Moreover, this looks like a use case for a virtualenv which, when active, would set those environment variables for you, before running CMake/CTest.

1 Like

Thank you; that’s the correct syntax for Windows, at least, but it doesn’t seem to work on Linux.

There, the syntax for unsetting an environment variable is not

PYTHONPATH=

but rather

unset(PYTHONPATH)

and trying to put that on the ENVIRONMENT line doesn’t work; I just get the same behaviour as I do if I leave the other Python’s definitions in place.

Sadly, I don’t believe I can use virtualenv in this particular context: it’s actually necessary to run scripts in the two different Python versions from within the same application.

Try running your test command with:

add_test(
  NAME ...
  COMMAND ${CMAKE_COMMAND} -E env
          --unset=PYTHONPATH
          --unset=PYTHONHOME
          ${rest_of_the_command})

This has been available since at least CMake 3.2

Ah, I see. I’d have struggled to work that out from the documentation, but yes this works on both platforms:

add_test(NAME SimplePythonTest
         COMMAND ${CMAKE_COMMAND} -E env --unset=PYTHONHOME --unset=PYTHONPATH  ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/SimpleTest.py 
         WORKING_DIRECTORY ${my_home})

Thank you.

You’re welcome! Happy to help.

1 Like

Just as a suggestion, for discoverability it might be useful to retitle this discussion something like…

Setting/unsetting environment variables for CTest tests

… as that’s what it’s actually about. It has nothing at all to do with the current title, really. (And I’m lucky I found it using the search, since it does have the info I was actually looking for, even though I almost didn’t click based on the title.)