Retrieving the full command line

Oscar Benjamin oscar.j.benjamin at gmail.com
Wed Jan 23 11:01:24 CET 2013


On 23 January 2013 03:58, Steven D'Aprano
<steve+comp.lang.python at pearwood.info> wrote:
> 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]
>>>
>> 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']

I don't know why you would expect this. I imagined that you would want

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

If the two were combined into one string I would expect it to at least
be a valid argument list:

['-mtestpackage', '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:

Unless I've missed something sys.argv[0] is always a valid path to the
script. Whether it is absolute or not shouldn't matter. For imported
modules the path is available from __name__. For a script that is
executed rather than imported __name__ == "__main__" but the path is
accessible from sys.argv[0]. If you are one of those people who cares
about sys.argv[0] then this is probably the value that you wanted it
to contain.

If it were important for sys.argv to show how exactly the script was
located and executed, then why not also include the 'python3.3'
command line argument (the real argv[0])? sys.argv emulates the argv
that e.g. a C program would get. The real command line used is not
exactly the same since a Python script is not a directly executable
binary, so Python processes the argument list before passing it
through.

In the OP's case, the script is never invoked without -m so the following works:

cmdline = [sys.executable, '-m', __package__] + sys.argv[1:]

In the more general case it would be better to have an API
specifically for this purpose.


Oscar



More information about the Python-list mailing list