To make your build definition more robust, you can try to find python executable at first with find_program(). This will stop build with verbose reason if python can't be found (You may alter this behavior by passing required: false
as an argument).
Then, to ensure that there are no path issues if your arguments are files or directories, make sure to wrap those with files().
All in all:
python_exe = find_program('python3', 'python')
params = files('file1', 'dir/file2')
r = run_command(python_exe, params, 'arg1', 'arg2')
if r.returncode() != 0
error('Error message')
endif
You may also consider defining your code-generation via python with actual building targets, e.g. generator() or custom_target(). This way, you can use the code-generation target as a dependency for actual c++ compiling target, therefore, it is guaranteed that code will be generated first and only then compiled.