Issue33119
Created on 2018-03-22 09:21 by Jonathan Huot, last changed 2018-03-24 04:25 by ncoghlan. This issue is now closed.
Messages (3) | |||
---|---|---|---|
msg314239 - (view) | Author: Jonathan Huot (Jonathan Huot) | Date: 2018-03-22 09:21 | |
Executing python modules with -m can lead to weird sys.argv parsing. "Argument parsing" section at https://docs.python.org/3.8/tutorial/interpreter.html#argument-passing mention : - When -m module is used, sys.argv[0] is set to the full name of the located module. The word "located" is used, but it doesn't mention anything when the module is not *yet* "located". For instance, let's see what is the sys.argv for each python files: $ cat mainmodule/__init__.py import sys; print("{}: {}".format(sys.argv, __file__)) $ cat mainmodule/submodule/__init__.py import sys; print("{}: {}".format(sys.argv, __file__)) $ cat mainmodule/submodule/foobar.py import sys; print("{}: {}".format(sys.argv, __file__)) Then we call "foobar" with -m: $ python -m mainmodule.submodule.foobar -o -b ['-m', '-o', 'b']: (..)/mainmodule/__init__.py ['-m', '-o', 'b']: (..)/mainmodule/submodule/__init__.py ['(..)/mainmodule/submodule/foobar.py', '-o', 'b']: (..)/mainmodule/submodule/foobar.py $ We notice that only "-m" is in sys.argv before we found "foobar". This can lead to a lot of troubles when we have meaningful processing in __init__.py which rely on sys.argv to initialize stuff. IMHO, it either should be the sys.argv intact ['-m', 'mainmodule.submodule.foobar', '-o', '-b'] or empty ['', '-o', '-b'] or only the latest ['-o', '-b'], but it should not be ['-m', '-o', '-b'] which is very confusing. |
|||
msg314350 - (view) | Author: Terry J. Reedy (terry.reedy) * ![]() |
Date: 2018-03-24 01:15 | |
Two of your 3 suggested alternatives could lead to bugs. To use your example: python -m mainmodule.submodule.foobar -o -b is a convenient alternative and abbreviation for python .../somedir/mainmodule/submodule/foobar.py -o -b The two invocations should give equivalent results and to the extent possible the same result. [What might be different is the form of argv[0]. In the first case, argv[0] will be the "preferred" form of the path to the python file while in the second, it will be whatever is given. On Windows, the difference might look like 'F:\\Python\\a\\tem2.py' versus 'f:/python/a/tem2.py'] Unless __init__.py does some evil monkeypatching, it cannot affect the main module unless imported directly or indirectly. So its behavior should be the same whether imported before or after execution of the main module. This means that argv must be the same either way (except for argv[0]). So argv[0:2] must be condensed to one arg before executing __init__. I don't see that '' is an improvement over '-m'. Command line arguments are intended for the invoked command. An __init__.py file is never the command unless invoked by its full path: "python somepath/__init__.py". In such a case, sys.argv access should be within a "__name__ == '__main__':" clause or a function called therein. |
|||
msg314355 - (view) | Author: Nick Coghlan (ncoghlan) * ![]() |
Date: 2018-03-24 04:25 | |
This is deliberate, and is covered in the documentation at https://docs.python.org/3/using/cmdline.html#cmdoption-m where it says 'If this option is given, the first element of sys.argv will be the full path to the module file (while the module file is being located, the first element will be set to "-m").' The part in parentheses is the bit that's applicable here. We've not going to change that, as the interpreter startup relies on checking sys.argv[0] for "-m" and "-c" in order to work out how it's expected to handle sys.path initialization. |
History | |||
---|---|---|---|
Date | User | Action | Args |
2018-03-24 04:25:00 | ncoghlan | set | status: open -> closed resolution: not a bug messages: + msg314355 stage: resolved |
2018-03-24 01:15:22 | terry.reedy | set | nosy:
+ terry.reedy messages: + msg314350 versions: - Python 3.4, Python 3.5 |
2018-03-22 23:09:21 | brett.cannon | set | nosy:
+ ncoghlan |
2018-03-22 09:21:13 | Jonathan Huot | create |