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