Good news is that a simple patch aiming to add automatic script generation functionality to packaging can work now. Current patch can create executable script with no extension on POSIX and .exe file on Windows platform, which is a good starting point for future deeper work. So, I told others this news on the bug tracker, hoping guys help me test on other platforms, esp. non Windows platform.
To create an executable script file on POSIX, my patch mainly does the following three things:
1) add a correct shebang line
2) add a correct import line, which is constructed from the input dotted path
3) add the specific ‘main’ function which is the executing entry of the script; create the script file and change its mode to make it executable
To create an .exe file on Windows, the patch does the following things:
1) create the wrapper script file as above
2) reuse cli.exe to get the resource string
3) create the .exe file
Future work will focus on supporting kind of ‘gui_scripts’ features for packaging, by reusing gui.exe, what’s more, writting robust tests to make this patch ok for other platforms.
In the mean time, I would have to blog two wonderful things which I have learned in this week after mentor’s good suggestion:
1) how to test the output of an executable script
There is a good utility function in packaging’s test module – captured_stdout, which can redirect our standard output(std.out), thus we can capture the output and test if it’s correct as expected. Actually, I somtimes also wanted to write such a function in my test, but I gave it up, because it seems making tests more complex. As a result, I used another workaround which may make others a little confused. I got to know that there always better solutions already supported in current Python, which I was not familiar with and didn’t know how to look for them.
I also spent a little time on readint the source of captured_stdout; it just defines a variable which has the ‘io.StringIO’ type to redirect the standard output. It’s so concise and useful, and I think there are still a lot of things to learn in future.
2) how to test the .exe files on Windows
The only way I knew to test .exe files is using ‘os.system()’, while I didn’t know how to pass the modified sys.path to it, because os.system will run Python in another process. I also know there is a subprocess module, but I’m also not sure how to pass it the sys.path. Thanks to mentor’s suggestion, I spent a little time on reading the source code of test_sys and found that many test functions are using such module to test the output of an executable file. subprocess.Popen function can take an enhanced os.environ as its parameter and can also easily get the output or error message from it. How exciting! It solved the problems which troubled me days.
Thank you, Eric, I have learned a lot in this summer, especially after your suggestions.