They work with call if you use a string argument. That's the core of the problem: The callv function doesn't support passing a string-type args argument to the Popen constructor.
OK, I read the code again and I see what you mean. So yes, this argues even more against the existence of callv(). I would have expected that it would always be possible to translate a call() invocation to its callv() equivalent and vice-versa.
That turns out not to be true in the case of call() users who want MSC-style command-line parsing done on a bare string (whether by CreateProcess() on windows or cmdline2list() on unix), because the _execute_child() implementations need to know whether args was originally a string or a list, and this information is hidden by callv()'s list encapsulation of the args.
This all makes me think there could be a better approach to cross-platform handling of command-line arguments. When is anyone ever going to want the braindamaged MS cmdline expansion done while they're trying to invoke a subprocess on unix? I don't see that getting used a lot.
I think I need to understand better the division of labor between parent and child on Windows when it comes to passing the command line during process creation. I'd like to think that unix execv() is a superset of the interface offered by CreateProcess(), in that you can initialize your child's argv however you like without regard to whitespace or quoting. So it would be best if it were possible to offer the execv() interface on both platforms if that's possible.