How to run script from interpreter?

Steven D'Aprano steve+comp.lang.python at pearwood.info
Fri May 30 07:27:26 EDT 2014


On Fri, 30 May 2014 17:19:00 +1000, Chris Angelico wrote:

> On Fri, May 30, 2014 at 4:20 PM, Steven D'Aprano
> <steve+comp.lang.python at pearwood.info> wrote:
>>> It's on par with creating a file with a name beginning with a hyphen,
>>> and then fiddling around with various commands as you try to
>>> manipulate it (tip: "rm ./-r" works); programs will happily interpret
>>> "-r" as an option rather than a file name, without being concerned
>>> that it's technically legal.
>>
>> I don't see any connection between the two.
> 
> -r is a valid file name, just as . is a valid line of input. But with
> the rm command, you can't provide it with -r as a file name - you have
> to use ./-r or somesuch, because the parser gets to it first. That's the
> connection.

The analogy doesn't quite match, because rm, like all shell commands, 
does it's own argument parsing, whereas Python operators do not. But 
putting that aside, the parser's rule is "arguments starting with a dash 
are treated as options". That's *standard behaviour*. If you want to 
override that standard behaviour, you have to tweak the command:

rm -f ./-r /tmp/*

Some commands accept a single dash to mean "no more options following 
this". Assuming rm does the same:

rm -f - -r /tmp/*

Either way, it is the standard behaviour as defined by rm, and so 
expected. That makes this the equivalent of Python's rule that dot 
behaves somewhat like an operator, and that a dot on its own is legal any 
place a bare binary operator is legal.

The analogy to "the REPL is allowed to modify standard syntax to make a 
bare dot special" would be something like:

    the shell is allowed to pre-process the command line, so 
    that -r on a line on its own like this:

    rm -f \
    -r \
    /tmp/*

    which otherwise would have been treated as `rm -f -r /tmp/*`,
    is instead turned into `rm -f ./-r /tmp/*`.

Reading the rm man page won't tell you this, because it happens outside 
of rm, just as reading the Python documentation won't tell you about the 
tricks your hypothetical REPL does to otherwise legal syntax. rm doesn't 
know what tricks your hypothetical shell might do, and neither can the 
Python parser tell what tricks your hypothetical REPL might do. Both see 
only what the shell give them.

This is why I'm so adamant that, while REPLs may be permitted to 
introduce *new* syntax which is otherwise illegal to the Python parser, 
(e.g. like IPython's %magic and !shell commands) they *must not* change 
the meaning of otherwise legal Python syntax. It's simply a bad idea to 
have legal Python code mean different things depending on what 
environment you're running it in.

(As I mentioned before, the annoying "blank line closes all open blocks" 
rule gets an exception simply because I don't believe there is any 
practical alternative.)


-- 
Steven D'Aprano
http://import-that.dreamwidth.org/



More information about the Python-list mailing list