[GRASS-dev] Using grass.message in Python: Why does G_message() print to stderr and not stdout?

Hi,

Why does G_message() print to stderr and not stdout?
https://trac.osgeo.org/grass/browser/grass/trunk/lib/gis/error.c#L84

This is a big problem when working with grass.run_command() and
friends since Python tends to buffer error messages (or occasionally
eats them). I have no reference why Python does so but there a myriad
of posts from people complaining about it.

Why an issue? I am currently debugging a long Python script on a
remote system, all docker based, and errors do not really show up. But
especially the grass.message() output is not there so that I can not
easily add debug output. So, the latter I would like to change.
To now add simple print() statements (on stdout) in a GRASS GIS Python
script is a bit against the idea of grass.message()...
Can grass.message() please (optionally) print on stdout?

Likely I am missing something - suggestions are welcome.

thanks
Markus

On Sun, Sep 9, 2018 at 3:47 PM Markus Neteler <neteler@osgeo.org> wrote:

Hi,

Why does G_message() print to stderr and not stdout?
https://trac.osgeo.org/grass/browser/grass/trunk/lib/gis/error.c#L84

Messages, warnings and errors are not output. Consider g.region -g, r.info -g, r.univar -g or any module that produces an output file with default output=- meaning stdout. You don’t want any messages in the output if the output is to be automatically parsed later on.

Markus M

This is a big problem when working with grass.run_command() and
friends since Python tends to buffer error messages (or occasionally
eats them). I have no reference why Python does so but there a myriad
of posts from people complaining about it.

Why an issue? I am currently debugging a long Python script on a
remote system, all docker based, and errors do not really show up. But
especially the grass.message() output is not there so that I can not
easily add debug output. So, the latter I would like to change.
To now add simple print() statements (on stdout) in a GRASS GIS Python
script is a bit against the idea of grass.message()…
Can grass.message() please (optionally) print on stdout?

Likely I am missing something - suggestions are welcome.

thanks
Markus


grass-dev mailing list
grass-dev@lists.osgeo.org
https://lists.osgeo.org/mailman/listinfo/grass-dev

On Sun, Sep 9, 2018 at 4:23 PM Markus Metz
<markus.metz.giswork@gmail.com> wrote:

On Sun, Sep 9, 2018 at 3:47 PM Markus Neteler <neteler@osgeo.org> wrote:
>
> Hi,
>
> Why does G_message() print to stderr and not stdout?
> https://trac.osgeo.org/grass/browser/grass/trunk/lib/gis/error.c#L84

Messages, warnings and errors are not output. Consider g.region -g, r.info -g, r.univar -g or any module that produces an output file with default output=- meaning stdout. You don't want any messages in the output if the output is to be automatically parsed later on.

OK, I see.
So, for output like "Step X: processing ...:" I need to use print()?

My preferred way would be grass.debug() because then I would later
switch these message to level 1 in order to "hide" them. Yet, I think
that they disappear...

I'd also like to see a way to print through the parser, i.e. a
functionality similiar to "sh -x shellscript" which prints every step.
Is that possible?

markusN

On Sun, Sep 9, 2018 at 4:46 PM Markus Neteler <neteler@osgeo.org> wrote:

On Sun, Sep 9, 2018 at 4:23 PM Markus Metz
<markus.metz.giswork@gmail.com> wrote:

On Sun, Sep 9, 2018 at 3:47 PM Markus Neteler <neteler@osgeo.org> wrote:

Hi,

Why does G_message() print to stderr and not stdout?
https://trac.osgeo.org/grass/browser/grass/trunk/lib/gis/error.c#L84

Messages, warnings and errors are not output. Consider g.region -g, r.info -g, r.univar -g or any module that produces an output file with default output=- meaning stdout. You don’t want any messages in the output if the output is to be automatically parsed later on.

OK, I see.

So, for output like “Step X: processing …:” I need to use print()?

this is going to stdout

My preferred way would be grass.debug() because then I would later
switch these message to level 1 in order to “hide” them. Yet, I think

that they disappear…

if stderr disappears, they disappear

the question is, what happens with stderr in Python? Where is it? Is it recoverable? See also your other post.

I’d also like to see a way to print through the parser, i.e. a
functionality similiar to “sh -x shellscript” which prints every step.

Is that possible?

In Python you mean? Maybe one of the GRASS Python gurus can answer that (not me).

Markus M

On Sun, Sep 9, 2018 at 3:37 PM Markus Metz <markus.metz.giswork@gmail.com> wrote:

On Sun, Sep 9, 2018 at 4:46 PM Markus Neteler <neteler@osgeo.org> wrote:

I’d also like to see a way to print through the parser, i.e. a
functionality similiar to “sh -x shellscript” which prints every step.
Is that possible?

In Python you mean? Maybe one of the GRASS Python gurus can answer that (not me).

It is not clear to me either what you are asking for. Do you want every Python line? Python can do that with module trace (python -m trace --trace). Here is an example (just for testing purposes, using the --tmp-location and --exec):

grass --tmp-location XY --exec python -m trace --trace grass --tmp-location XY --exec which r.mask -r

That gives little too much information, so perhaps:

FILE=“./bin.x86_64-pc-linux-gnu/grass77 --tmp-location XY --exec which r.mask

grass --tmp-location XY --exec python -m trace --trace $FILE -r | grep basename $FILE

Or do you want GRASS parser to print every module being executed?

Vaclav

On Sun, Sep 9, 2018 at 10:13 PM Vaclav Petras <wenzeslaus@gmail.com> wrote:

On Sun, Sep 9, 2018 at 3:37 PM Markus Metz <markus.metz.giswork@gmail.com> wrote:
> On Sun, Sep 9, 2018 at 4:46 PM Markus Neteler <neteler@osgeo.org> wrote:
>
> >
> > I'd also like to see a way to print through the parser, i.e. a
> > functionality similiar to "sh -x shellscript" which prints every step.
> > Is that possible?

It is not clear to me either what you are asking for. Do you want every Python line? Python can do that with module `trace` (python -m trace --trace).
Here is an example (just for testing purposes, using the --tmp-location and --exec):

grass --tmp-location XY --exec python -m trace --trace `grass --tmp-location XY --exec which r.mask` -r

Good to know. Yet that's not what I meant - it also shows all the subcalls etc.

That gives little too much information, so perhaps:

FILE="`./bin.x86_64-pc-linux-gnu/grass77 --tmp-location XY --exec which r.mask`"
grass --tmp-location XY --exec python -m trace --trace $FILE -r | grep `basename $FILE`

Or do you want GRASS parser to print every module being executed?

Yes, just the sequence of commands along with the parameter/flags
used. Like "shell history" style. This would help for a quick
orientation in long Python scripts with functions etc.

Markus

On Sun, Sep 9, 2018 at 4:47 PM Markus Neteler <neteler@osgeo.org> wrote:

That gives little too much information, so perhaps:

FILE=“./bin.x86_64-pc-linux-gnu/grass77 --tmp-location XY --exec which r.mask
grass --tmp-location XY --exec python -m trace --trace $FILE -r | grep basename $FILE

Or do you want GRASS parser to print every module being executed?

Yes, just the sequence of commands along with the parameter/flags
used. Like “shell history” style. This would help for a quick
orientation in long Python scripts with functions etc.

This sounds like a good enhancement for the parser. Ticket?

On Mon, Sep 10, 2018 at 1:37 AM Vaclav Petras <wenzeslaus@gmail.com> wrote:

On Sun, Sep 9, 2018 at 4:47 PM Markus Neteler <neteler@osgeo.org> wrote:

...

> Yes, just the sequence of commands along with the parameter/flags
> used. Like "shell history" style. This would help for a quick
> orientation in long Python scripts with functions etc.

This sounds like a good enhancement for the parser. Ticket?

I have created a new ticket:
https://trac.osgeo.org/grass/ticket/3647

Markus