[GRASS-dev] [GRASS-user] Error in pansharp tool: missing grass.script

import aaa.bbb as aaa

Why not

import aaa.bbb

or often appropriate

import aaa.bbb as bbb

or (my favorite)

import aaa.bbb as ab

or simple

import aaa

?

Alias shouldn’t create confusion which I think it creates.

After

import grass.script as grass

which of the following will work?

from grass import run_commad
from grass import pygrass

The second line will work although in the following case it is the first line.

grass.run_command
grass.pygrass

Sure, this is just how Python interprets the import statements, so if you know it, you are fine, but why should we make reading of the source code harder then necessary?

The current situation leads to cases like:

import grass.script as grass
grass.run_command
<function run_command at 0x7f185ed61500>

Fine.

grass.script.run_command
Traceback (most recent call last):
File “”, line 1, in
AttributeError: ‘module’ object has no attribute ‘script’

OK. We haven’t imported grass.script in the proper way, so let’s do it.

import grass.script
grass.script.run_command
<function run_command at 0x7f185ed61500>

Works.

grass.run_command
Traceback (most recent call last):
File “”, line 1, in
AttributeError: ‘module’ object has no attribute ‘run_command’

Does not work anymore.

···

On Thu, Jun 25, 2015 at 3:41 AM, Moritz Lennert <mlennert@club.worldonline.be> wrote:

On 24/06/15 15:09, Vaclav Petras wrote:

It seems like one. I think it might help, at least help to debug, if you
replace “import grass.script as grass” by “import grass.script as
gscript” and “grass.” by “gscript.”. I think this change should be done
anyway in all source code.

Could you explain your reasoning behind this ? IMHO, it should not make any difference whether you use grass or gscript as the alias.

Sure. First of all, this just look strange by default I believe:

I think that broadly used

import grass.script as grass

is just a legacy from the first version of Python API where “grass.script” was the only package and thus it was just grass. Then new (sub-)packages were introduced, probably “grass.lib” which forced the former grass to be renamed/moved to grass.script. To avoid changing all calls of functions from grass.run_command to something else, grass.script was imported with alias grass. This then spread into new and user code because the code is (or hopefully was) the only documentation. The unfortunate part is that this was some very first version of the API which was never released as stable (official introduction of Python API is 7.0.0, it was just experimental and internal in 6.4) but it influenced the common practice which I think is not the best practice. At least, this is how I understand it.

I don’t see a reason why to keep it when there is a better practice available. We should especially change it in GUI and parser’s --script. I believe none of them are change of the API, so it can be done anytime. The code itself should be changed too, we are doing a lot of other non-crucial changes anyway. The benefit is better code as an example for users and easier maintenance because it is just more clear.

Well, that’s what I think.

Vaclav

* Vaclav Petras <wenzeslaus@gmail.com> [2015-06-25 09:58:47 -0400]:

On Thu, Jun 25, 2015 at 3:41 AM, Moritz Lennert <
mlennert@club.worldonline.be> wrote:

> On 24/06/15 15:09, Vaclav Petras wrote:
>
>> It seems like one. I think it might help, at least help to debug, if you
>> replace "import grass.script as grass" by "import grass.script as
>> gscript" and "grass." by "gscript.". I think this change should be done
>> anyway in all source code.
>>
>
> Could you explain your reasoning behind this ? IMHO, it should not make
> any difference whether you use grass or gscript as the alias.

Sure. First of all, this just look strange by default I believe:

import aaa.bbb as aaa

Why not

import aaa.bbb

or often appropriate

import aaa.bbb as bbb

or (my favorite)

import aaa.bbb as ab

or simple

import aaa

?

Alias shouldn't create confusion which I think it creates.

After

import grass.script as grass

which of the following will work?

from grass import run_commad
from grass import pygrass

The second line will work although in the following case it is the first
line.

grass.run_command
grass.pygrass

Sure, this is just how Python interprets the import statements, so if you
know it, you are fine, but why should we make reading of the source code
harder then necessary?

I prefer self-explained names in general. Why make it hard to read the
code, for anyone who cares, anyway?

At this point I'd like too to stress the need for proper commenting and
documenting source code. Many, if not most, scripts, are not easy to
read. There are simply too many short and not self-explained variable names,
and undocumented functions as well.

This is yet another bold ToDo in my list, at least for add-ons, once I
will have again the freedom and time to contribute.

The current situation leads to cases like:

>>> import grass.script as grass
>>> grass.run_command
<function run_command at 0x7f185ed61500>

Fine.

>>> grass.script.run_command
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'script'

OK. We haven't imported grass.script in the proper way, so let's do it.

>>> import grass.script
>>> grass.script.run_command
<function run_command at 0x7f185ed61500>

Works.

>>> grass.run_command
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'run_command'

Does not work anymore.

Yep, but a scripter wouldn't want to repeat `grass.script.` everytime.
Would he? I do agree with Vaclav, however, with a convention that is
not confusing. And, at the same time, it is still practical.

Please, think of "inviting" new scripters with code that is easy and a
joy to study.

Nikos

I think that broadly used

import grass.script as grass

is just a legacy from the first version of Python API where "grass.script"
was the only package and thus it was just `grass`. Then new (sub-)packages
were introduced, probably "grass.lib" which forced the former `grass` to be
renamed/moved to `grass.script`. To avoid changing all calls of functions
from `grass.run_command` to something else, `grass.script` was imported
with alias `grass`. This then spread into new and user code because the
code is (or hopefully was) the only documentation. The unfortunate part is
that this was some very first version of the API which was never released
as stable (official introduction of Python API is 7.0.0, it was just
experimental and internal in 6.4) but it influenced the common practice
which I think is not the best practice. At least, this is how I understand
it.

I don't see a reason why to keep it when there is a better practice
available. We should especially change it in GUI and parser's --script. I
believe none of them are change of the API, so it can be done anytime. The
code itself should be changed too, we are doing a lot of other non-crucial
changes anyway. The benefit is better code as an example for users and
easier maintenance because it is just more clear.

Well, that's what I think.

Vaclav

On Thu, Jun 25, 2015 at 11:38 AM, Nikos Alexandris <nik@nikosalexandris.net>
wrote:

Yep, but a scripter wouldn't want to repeat `grass.script.` everytime.
Would he?

That's why I think

import grass.script as gscript

should be used. The examples were just showing different scenarios and
possible confusion.

I past I was thinking about it and at the beginning I though that we should
use

import grass.script.core as gcore
import grass.script.raster as graster
...

which is most detailed and allows for an empty __init__.py in script
directory, but after trying it, considering the existing practice, and
state of grass.script package, I decided that

import grass.script as gscript

is better.

* Vaclav Petras <wenzeslaus@gmail.com> [2015-06-25 11:42:45 -0400]:

On Thu, Jun 25, 2015 at 11:38 AM, Nikos Alexandris <nik@nikosalexandris.net>
wrote:

> Yep, but a scripter wouldn't want to repeat `grass.script.` everytime.
> Would he?
>

That's why I think

import grass.script as gscript

should be used. The examples were just showing different scenarios and
possible confusion.

I past I was thinking about it and at the beginning I though that we should
use

import grass.script.core as gcore
import grass.script.raster as graster
...

which is most detailed and allows for an empty __init__.py in script
directory, but after trying it, considering the existing practice, and
state of grass.script package, I decided that

import grass.script as gscript

is better.

Makes sense. If someone can come up with something even better, please
chime in. Thanks for demonstrating it Vaclav,

Nikos

On 25/06/15 15:58, Vaclav Petras wrote:

On Thu, Jun 25, 2015 at 3:41 AM, Moritz Lennert
<mlennert@club.worldonline.be <mailto:mlennert@club.worldonline.be>> wrote:

    On 24/06/15 15:09, Vaclav Petras wrote:

        It seems like one. I think it might help, at least help to
        debug, if you
        replace "import grass.script as grass" by "import grass.script as
        gscript" and "grass." by "gscript.". I think this change should
        be done
        anyway in all source code.

    Could you explain your reasoning behind this ? IMHO, it should not
    make any difference whether you use grass or gscript as the alias.

Sure. First of all, this just look strange by default I believe:

import aaa.bbb as aaa

Why not

import aaa.bbb

or often appropriate

import aaa.bbb as bbb

or (my favorite)

import aaa.bbb as ab

or simple

import aaa

?

Alias shouldn't create confusion which I think it creates.

After

import grass.script as grass

which of the following will work?

from grass import run_commad
from grass import pygrass

The second line will work although in the following case it is the first
line.

grass.run_command
grass.pygrass

Sure, this is just how Python interprets the import statements, so if
you know it, you are fine, but why should we make reading of the source
code harder then necessary?

The current situation leads to cases like:

>>> import grass.script as grass
>>> grass.run_command
<function run_command at 0x7f185ed61500>

Fine.

>>> grass.script.run_command
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'script'

OK. We haven't imported grass.script in the proper way, so let's do it.

>>> import grass.script
>>> grass.script.run_command
<function run_command at 0x7f185ed61500>

Works.

>>> grass.run_command
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'run_command'

Does not work anymore.

I think that broadly used

import grass.script as grass

is just a legacy from the first version of Python API where
"grass.script" was the only package and thus it was just `grass`. Then
new (sub-)packages were introduced, probably "grass.lib" which forced
the former `grass` to be renamed/moved to `grass.script`. To avoid
changing all calls of functions from `grass.run_command` to something
else, `grass.script` was imported with alias `grass`. This then spread
into new and user code because the code is (or hopefully was) the only
documentation. The unfortunate part is that this was some very first
version of the API which was never released as stable (official
introduction of Python API is 7.0.0, it was just experimental and
internal in 6.4) but it influenced the common practice which I think is
not the best practice. At least, this is how I understand it.

I don't see a reason why to keep it when there is a better practice
available. We should especially change it in GUI and parser's --script.
I believe none of them are change of the API, so it can be done anytime.
The code itself should be changed too, we are doing a lot of other
non-crucial changes anyway. The benefit is better code as an example for
users and easier maintenance because it is just more clear.

Well, that's what I think.

Thanks for that detailed explanation. Although I don't feel as strongly about this as you seem to (probably because my scripts are never that complex), I understand your point and I agree that i) we should have a unified way of doing it and ii) using your gscript (or something similar) is probably better than the current grass.

Moritz