[GRASS-dev] [GRASS GIS] #2326: Command functions in grass.script.core miss a correct error reporting
GRASS GIS
trac at osgeo.org
Wed Jun 25 14:09:17 PDT 2014
#2326: Command functions in grass.script.core miss a correct error reporting
--------------------------------+-------------------------------------------
Reporter: wenzeslaus | Owner: grass-dev@…
Type: enhancement | Status: new
Priority: major | Milestone: 7.1.0
Component: Python | Version: svn-trunk
Keywords: script, exceptions | Platform: All
Cpu: Unspecified |
--------------------------------+-------------------------------------------
Comment(by glynn):
Replying to [comment:9 wenzeslaus]:
> That's true but I don't know how to solve the following case.
>
> I'm currently testing the testing framework.
Your testing framework probably shouldn't be using functions designed for
normal scripts. Conversely (and more importantly), features which are
necessary or useful for a testing framework shouldn't be imposed upon
normal scripts.
Write your own "run_command" function atop grass.script.start_command(),
and use that.
> > Also, checking kwargs!["args"] isn't useful.
>
> If you mean `cmd = kwargs.get("args")`, this is from `Popen`, source
code, I don't know what exactly they are trying to accomplish.
Python's Popen() is at a lower level than the grass.script functions. The
latter don't accept an "args" parameter, but use grass.script.make_command
to generate the argument list from the keyword arguments.
> > In most cases, the failure to check exit codes was inherited from the
original shell script. run_command() replaces "simple" command execution,
read_command() replaces backticks. pipe_command() and feed_command() are
used for a GRASS command at one end of a pipeline. write_command()
replaces "echo data | command".
> >
> Beginning and end of the pipe line still does not convince me about
usefulness of the functions. I still see them as unnecessary complication
of interface. If one need something like this, he or she can use
`start_commnad` directly.
All of the functions (except for exec_command) can be replaced by
start_command, as all of those functions are implemented using
start_command. They exist as convenience interfaces for the most common
cases (e.g. being able to use "data = read_command(...)" rather than
having to explicitly manage a Popen object).
The cases of a single pipe to either stdin or stdout are simpler (for the
caller) than those which require multiple pipes, as they avoid the
potential for deadlock. This is why Unix' popen() lets you read stdout or
write stderr but not both.
These interfaces could perhaps be simplified further by supporting the
context manager interface, so that scripts could use e.g.
{{{
with grass.script.pipe_command(...) as p:
for line in p.stdout:
# whatever
}}}
This would avoid the need for an explicit check of the exit code (the
check would be performed in the context manager's `__exit__` method).
> > My suggestion would be that the functions which wait for the process
to terminate (run_command, read_command, write_command) should call a
check_status() function, e.g.
> >
> I don't agree with the name. It does not `check_status` it waits and
then checks status, so I would suggest `_wait_check_status`.
The "status" in question is the process' exit status, which doesn't exist
until the process has terminated. How about check_exit_status()?
> > Alternatively, we could just modify the Popen wrapper to provide a
modified .wait() method which does this automatically. This would probably
"do the right thing" for scripts which use start_command() etc and
subsequently call p.wait() themselves.
>
> I vote against. The lower level API (when using `Popen` object) should
behave in the same way as Python `Popen` to allow users/programmers switch
between them easily. Moreover, it would be a violation of some OOP
principles, although in case of Python not so big violation, I believe.
Another alternative is the same thing under a different name, e.g.
.finish(). This would still require modifying existing scripts to use that
rather than .wait(), but at least it keeps it as a method rather than a
function.
--
Ticket URL: <https://trac.osgeo.org/grass/ticket/2326#comment:13>
GRASS GIS <http://grass.osgeo.org>
More information about the grass-dev
mailing list