Opened 10 years ago

Closed 7 years ago

#2133 closed defect (fixed)

g.parser does call the with full path

Reported by: wenzeslaus Owned by: wenzeslaus
Priority: normal Milestone: 7.2.0
Component: Parser Version: svn-trunk
Keywords: parser, forms, wxGUI, pyedit Cc:
CPU: All Platform: All


When I run gui/wxpython/gui_core/ directly with full path:

python gui_core/ ../../temporal/t.list/

I get the module form/dialog (task frame) for the command and following debug output (g.gisenv set=WX_DEBUG=1):

GUI D1/1: called using command: ../../temporal/t.list/
GUI D1/1: opening form for: ['']

However, when I run the module itself (here with --ui because of other parameters):

../../temporal/t.list/ --ui

I don't get the GUI for module, I get an error dialog with message:

Unable to fetch interface description for command ''.

Details: [Errno 2] No such file or directory

Try to set up GRASS_ADDON_PATH or GRASS_ADDON_BASE variable.

and the reason is actually clear from the debug output:

GUI D1/1: called using command: type="strds" temporaltype="absolute,relative" order="id" columns="id"
GUI D1/1: opening form for: ['unknown']

The parser mechanism does not pass the full path to file, so it is not found by the mechanism. The should probably end with some other error then setting the name to unknown but that's another story.

The function responsible for running GUI is module_gui_wx in lib/gis/parser.c. It is passing result of G_recreate_command() as a first parameter and this works pretty well. The problem is that it returns only base name of the command returned by G_program_name() which uses global variable set by G_set_program_name function which stripes the name to using G_basename function.

I cannot go further because G_recreate_command does not have any useful documentations (the only line of doc is related to non-interactivity which is really outdated). I hope that some others knows what is the concept of this and so what is the right solution.

This functionality is important for testing non-core modules (addons/extensions) and more importantly it is crucial for running user scripts or scripts distributed in other way then GRASS Addons repository.

Note that you need at least r58212 (GRASS 7) to test this because I added the debug messages in r58212. By the way, I've fixed the two tests there and extended usage suggestions when you run it without parameters.

*This is the second Trac component I'm suggesting in past few weeks but what about Parser/G_parser/GRASS Parser/g.parser component*.

Change History (6)

in reply to:  description comment:1 by hamish, 10 years ago

Component: wxGUIParser

Replying to wenzeslaus:

*This is the second Trac component I'm suggesting in past few weeks but what about Parser/G_parser/GRASS Parser/g.parser component*.


regards, Hamish

comment:2 by hamish, 10 years ago

ps- typically scripts using g.parser need to be somewhere in the system PATH since they run in two passes, and the second time it has forgotten the original path (if it ever knew it, it could have been called as "./script"). For compiled addon modules they don't need to be in the PATH since the module is run in the same process as the parser.

try adding the directory you script is in to the PATH.

comment:3 by wenzeslaus, 8 years ago

Keywords: forms wxGUI added
Owner: changed from grass-dev@… to wenzeslaus

This is still an issue. Custom Python scripts using grass.script.parser() won't open a GUI from the command line. You will get (tested on a copy of t.list, i.e. something on "on PATH"):

Unable to fetch interface description for command 't.list2'.

Details: [Errno 2] No such file or directory

Try to set up GRASS_ADDON_PATH or GRASS_ADDON_BASE variable.

But there is no reason for modifying any path variables, you provided full (or relative) path, so this should be enough. In GUI Console, you will get the GUI dialog/form but running the module will show a run in the dialog's Command output tab but [Errno 2] No such file or directory in the main GUI's Console (I'm not sure what is the exact mechanism in GUI).

Removing the G_basename calls and directory stripping from G_set_program_name() makes it work both in command line and the GUI.

Index: lib/gis/parser.c
--- lib/gis/parser.c    (revision 67989)
+++ lib/gis/parser.c    (working copy)
@@ -340,8 +340,6 @@
-    G_basename(tmp_name, "exe");
-    st->pgm_name = tmp_name;
Index: lib/gis/progrm_nme.c
--- lib/gis/progrm_nme.c        (revision 67989)
+++ lib/gis/progrm_nme.c        (working copy)
@@ -44,18 +44,8 @@
-    i = strlen(s);
-    while (--i >= 0) {
-       if (G_is_dirsep(s[i])) {
-           s += i + 1;
-           break;
-       }
-    }
     /* strip extension from program name */
-    temp = G_store(s);
-    G_basename(temp, "exe");
-    G_basename(temp, "py");
     name = G_store(s);

Extensions are probably present on MS Windows and we don't want them in history (r21674, r62904). But I have no idea why we are stripping the directories (blame goes to r9499).

Is there a occasion when modules are called with full path? Maybe MS Windows e.g., without shell=True in Python? Or can we just preserve path when it is present and leave the extension there as well? (Resulting in G_program_name() returning whatever was there, putting it into history and passing it to GUI.)

Alternatively, we can add another function which will return the originally used path and will be used in module_gui_wx() (in parser.c) instead of G_program_name(). This will leave the history behavior intact (you will get stripped name although you provided a full path) but the GUI will get the full (or relative) path needed to run the script to obtain the interface and execute script later.

comment:4 by wenzeslaus, 8 years ago

r67994 adds functions to lib/gis which allow passing the originally provided path to to in module_gui_wx(). r67993 adds the original path to a task used to create the GUI form/dialog for a module.

comment:5 by neteler, 7 years ago


Milestone renamed

comment:6 by wenzeslaus, 7 years ago

Keywords: pyedit added
Resolution: fixed
Status: newclosed

Now I get GUI when running:

cp temporal/

Works well also for the Simple Python Editor in trunk (7.1).

Note: See TracTickets for help on using tickets.