setup.py
takes a series of commands (setup.py --help
shows usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
). Critically, each command is its own script with its own command line options (which is why setup.py bdist_wheel --help
shows different options than setup.py sdist --help
).
The subtlety here is that certain commands generate calls to other commands under the hood but aren't nice enough to pass along common flags to the generated commands. For example, bdist_wheel
ends up calling build
and also egg_info
but it does not pass along any bdist-dir
you may specify. There's no global "use such and such working directory for the whole setup.py command" because all the commands are running independently and without knowledge of each other.
In order to redirect all temp directories somewhere else you have to manually specify each command and use its temp directory flag. In my case for bdist_wheel
the full invocation was:
python setup.py ^
build --build-base \path\to\working\dir ^
egg_info --egg-base \path\to\working\dir ^
bdist_wheel --dist-dir \path\to\final\output\dir
(Side note, I found that if build-base
and egg-base
didn't match I got a weird error about not having used relative paths.)
This was sufficient to put all temp directories outside of the source folder.
Unfortunately it's not directly obvious which temp directory is the result of which command. You can use the list of commands (setup.py --help-commands
) and some guesswork to determine which command created each temp directory. Then use --help
on that command to see how to change its working directory.