While testing Vinay Sajip’s Distil packaging work, I encountered a psycopg2 build problem around a version macro containing spaces. The saved issue discussion has a useful diagnostic: replace the compiler temporarily with a program that prints the argument vector it receives.
The printed argument was still one item, shaped like:
-DPSYCOPG_VERSION=2.5 (dt dec pq3 ext)Keeping the spaces in one argument answered the shell question. It did not answer the C preprocessor question. A macro intended to expand to a C string needs quote characters inside the argument that reaches the compiler.
For an illustrative direct subprocess call, the argument string would retain those characters:
argument = '-DVERSION="2.5 (example)"'The outer single quotes are Python syntax and do not become part of the string. The inner double quotes do, because the compiler needs to see them. If another shell sits between Python and the compiler, that shell introduces another interpretation of those characters. A visually convincing printed command does not prove they survive every stage.
Vinay also noted that using Python’s repr() as a quoting solution could produce a u prefix for Unicode strings in Python 2. A representation suitable for reading as Python was not automatically suitable for a command shell. We discussed avoiding shell=True; he reported the issue fixed in 995bd93.
The diagnostic still separates two easily conflated questions: how many arguments reached the program, and what syntax the program then found inside each argument. The first can be correct while the second is wrong.