Retrieving the full command line

Steven D'Aprano steve+comp.lang.python at pearwood.info
Wed Jan 23 04:58:52 CET 2013


On Wed, 23 Jan 2013 00:53:21 +0000, Oscar Benjamin wrote:

> On 22 January 2013 23:46, Steven D'Aprano
> <steve+comp.lang.python at pearwood.info> wrote: [SNIP]
>>
>> I am a bit disturbed that you cannot distinguish between:
>>
>> python C:\something\on\pythonpath\app\__main__.py
>>
>> python -m app
>>
>>
>> by inspecting the command line. I consider it a bug, or at least a
>> misfeature, if Python transforms the command line before making it
>> available in sys.argv.
> 
> The purpose of the -m option is that you can run a script that is
> located via the Python import path instead of an explicit file path. The
> idea is that if '/path/to/somewhere' is in sys.path then:
>     python -m script arg1 arg2
> is equivalent to
>     python /path/to/somewhere/script.py arg1 arg2
> 
> If Python didn't modify sys.argv then 'script.py' would need to be
> rewritten to understand that sys.argv would be in a different format
> when it was invoked using the -m option.

I don't think that it would be in a different format. Normally people 
only care about sys.argv[1:], the actual arguments. argv[0], the name of 
the script, already comes in multiple formats: absolute or relative paths.

Currently, if I have a package __main__.py that prints sys.argv, I get 
results like this:

steve at runes:~$ python3.3 /home/steve/python/testpackage/__main__.py ham 
spam eggs
['/home/steve/python/testpackage/__main__.py', 'ham', 'spam', 'eggs']


which is correct, that's what I gave on the command line. But:

steve at runes:~$ python3.3 -m testpackage ham spam eggs
['/home/steve/python/testpackage/__main__.py', 'ham', 'spam', 'eggs']


The second example is lying. It should say:

['-m testpackage', 'ham', 'spam', 'eggs']


If you are one of the few people who care about argv[0], then you are 
already dealing with the fact that the name of the executable script is 
not always an absolute path and therefore can vary greatly from one call 
to another. Hell, if you are on a system with soft links, the name of the 
script in the command line is not even necessarily the name of the 
module. So there's not much more effort involved in dealing with one 
extra case:

# assuming you care, which most people don't
if sys.argv[0].startswith('-m'):
    do_something()
elif os.path.isabs(sys.argv[0]):
    do_this()
else:  # relative path
    do_that()



-- 
Steven



More information about the Python-list mailing list