[GRASS-SVN] r56800 - in grass/trunk: gui/wxpython/core gui/wxpython/gui_core lib/python/script raster/r.colors scripts/g.extension scripts/i.in.spotvgt scripts/i.spectral scripts/r.in.aster scripts/v.db.univar vector/v.colors

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Jun 19 07:51:56 PDT 2013


Author: annakrat
Date: 2013-06-19 07:51:56 -0700 (Wed, 19 Jun 2013)
New Revision: 56800

Modified:
   grass/trunk/gui/wxpython/core/render.py
   grass/trunk/gui/wxpython/gui_core/gselect.py
   grass/trunk/gui/wxpython/gui_core/mapdisp.py
   grass/trunk/lib/python/script/core.py
   grass/trunk/raster/r.colors/thumbnails.py
   grass/trunk/scripts/g.extension/g.extension.py
   grass/trunk/scripts/i.in.spotvgt/i.in.spotvgt.py
   grass/trunk/scripts/i.spectral/i.spectral.py
   grass/trunk/scripts/r.in.aster/r.in.aster.py
   grass/trunk/scripts/v.db.univar/v.db.univar.py
   grass/trunk/vector/v.colors/thumbnails.py
Log:
pythonlib: change implementation of find_program (see #2008) and related changes

Modified: grass/trunk/gui/wxpython/core/render.py
===================================================================
--- grass/trunk/gui/wxpython/core/render.py	2013-06-19 14:42:58 UTC (rev 56799)
+++ grass/trunk/gui/wxpython/core/render.py	2013-06-19 14:51:56 UTC (rev 56800)
@@ -451,7 +451,7 @@
         """!Return region projection and map units information
         """
         projinfo = dict()
-        if not grass.find_program('g.proj', ['--help']):
+        if not grass.find_program('g.proj'):
             sys.exit(_("GRASS module '%s' not found. Unable to start map "
                        "display window.") % 'g.proj')
         

Modified: grass/trunk/gui/wxpython/gui_core/gselect.py
===================================================================
--- grass/trunk/gui/wxpython/gui_core/gselect.py	2013-06-19 14:42:58 UTC (rev 56799)
+++ grass/trunk/gui/wxpython/gui_core/gselect.py	2013-06-19 14:51:56 UTC (rev 56800)
@@ -1803,7 +1803,7 @@
                                 driver = 'pg').splitlines()
                 if db is not None:
                     win.SetItems(sorted(db))
-                elif grass.find_program('psql', ['--help']):
+                elif grass.find_program('psql'):
                     if not win.GetItems():
                         p = grass.Popen(['psql', '-ltA'], stdout = grass.PIPE)
                         ret = p.communicate()[0]

Modified: grass/trunk/gui/wxpython/gui_core/mapdisp.py
===================================================================
--- grass/trunk/gui/wxpython/gui_core/mapdisp.py	2013-06-19 14:42:58 UTC (rev 56799)
+++ grass/trunk/gui/wxpython/gui_core/mapdisp.py	2013-06-19 14:51:56 UTC (rev 56800)
@@ -105,7 +105,7 @@
     def _initMap(self, Map):
         """!Initialize map display, set dimensions and map region
         """
-        if not grass.find_program('g.region', ['--help']):
+        if not grass.find_program('g.region'):
             sys.exit(_("GRASS module '%s' not found. Unable to start map "
                        "display window.") % 'g.region')
         

Modified: grass/trunk/lib/python/script/core.py
===================================================================
--- grass/trunk/lib/python/script/core.py	2013-06-19 14:42:58 UTC (rev 56799)
+++ grass/trunk/lib/python/script/core.py	2013-06-19 14:51:56 UTC (rev 56800)
@@ -1156,42 +1156,69 @@
     return name
 
 # find a program (replacement for "which")
+# from http://hg.python.org/cpython/file/6860263c05b3/Lib/shutil.py#l1068
+# see ticket #2008
+def find_program(cmd, mode=os.F_OK | os.X_OK, path=None):
+    """Given a command, mode, and a PATH string, return the path which
+    conforms to the given mode on the PATH, or None if there is no such
+    file.
 
-def find_program(pgm, args = []):
-    """!Attempt to run a program, with optional arguments.
-    You must call the program in a way that will return a successful
-    exit code. For GRASS modules this means you need to pass it some
-    valid CLI option, like "--help". For other programs a common
-    valid do-little option is "--version".
-    
-    Example:
+    `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result
+    of os.environ.get("PATH"), or can be overridden with a custom search
+    path.
 
-    @code
-    >>> grass.find_program('r.sun', ['help'])
-    True
-    >>> grass.find_program('gdalwarp', ['--version'])
-    True
-    @endcode
+    """
+    # Check that a given file can be accessed with the correct mode.
+    # Additionally check that `file` is not a directory, as on Windows
+    # directories pass the os.access check.
+    def _access_check(fn, mode):
+        return (os.path.exists(fn) and os.access(fn, mode)
+                and not os.path.isdir(fn))
 
-    @param pgm program name
-    @param args list of arguments
+    # If we're given a path with a directory part, look it up directly rather
+    # than referring to PATH directories. This includes checking relative to the
+    # current directory, e.g. ./script
+    if os.path.dirname(cmd):
+        if _access_check(cmd, mode):
+            return cmd
+        return None
 
-    @return False if the attempt failed due to a missing executable
-            or non-zero return code
-    @return True otherwise
-    """
-    nuldev = file(os.devnull, 'w+')
-    try:
-        ret = call([pgm] + args, stdin = nuldev, stdout = nuldev, stderr = nuldev)
-        if ret == 0:
-            found = True
+    if path is None:
+        path = os.environ.get("PATH", os.defpath)
+    if not path:
+        return None
+    path = path.split(os.pathsep)
+
+    if sys.platform == "win32":
+        # The current directory takes precedence on Windows.
+        if not os.curdir in path:
+            path.insert(0, os.curdir)
+
+        # PATHEXT is necessary to check on Windows.
+        pathext = os.environ.get("PATHEXT", "").split(os.pathsep)
+        # See if the given file matches any of the expected path extensions.
+        # This will allow us to short circuit when given "python.exe".
+        # If it does match, only test that one, otherwise we have to try
+        # others.
+        if any(cmd.lower().endswith(ext.lower()) for ext in pathext):
+            files = [cmd]
         else:
-            found = False
-    except:
-        found = False
-    nuldev.close()
+            files = [cmd + ext for ext in pathext]
+    else:
+        # On other platforms you don't have things like PATHEXT to tell you
+        # what file suffixes are executable, so just pass on cmd as-is.
+        files = [cmd]
 
-    return found
+    seen = set()
+    for dir in path:
+        normdir = os.path.normcase(dir)
+        if not normdir in seen:
+            seen.add(normdir)
+            for thefile in files:
+                name = os.path.join(dir, thefile)
+                if _access_check(name, mode):
+                    return name
+    return None
 
 # try to remove a file, without complaints
 
@@ -1410,7 +1437,7 @@
     if _debug_level is not None:
         return _debug_level
     _debug_level = 0
-    if find_program('g.gisenv', ['--help']):
+    if find_program('g.gisenv'):
         _debug_level = int(gisenv().get('DEBUG', 0))
 
 def legal_name(s):

Modified: grass/trunk/raster/r.colors/thumbnails.py
===================================================================
--- grass/trunk/raster/r.colors/thumbnails.py	2013-06-19 14:42:58 UTC (rev 56799)
+++ grass/trunk/raster/r.colors/thumbnails.py	2013-06-19 14:51:56 UTC (rev 56800)
@@ -83,7 +83,7 @@
     return dstd
 
 def ppmtopng(dst, src):
-    if grass.find_program("g.ppmtopng", ["help"]):
+    if grass.find_program("g.ppmtopng"):
         grass.run_command('g.ppmtopng', input = src, output = dst, quiet = True)
     elif grass.find_program("pnmtopng"):
         fh = open(dst, 'wb')

Modified: grass/trunk/scripts/g.extension/g.extension.py
===================================================================
--- grass/trunk/scripts/g.extension/g.extension.py	2013-06-19 14:42:58 UTC (rev 56799)
+++ grass/trunk/scripts/g.extension/g.extension.py	2013-06-19 14:51:56 UTC (rev 56800)
@@ -139,7 +139,7 @@
 # check requirements
 def check_progs():
     for prog in ('svn', 'make', 'gcc'):
-        if not grass.find_program(prog, ['--help']):
+        if not grass.find_program(prog):
             grass.fatal(_("'%s' required. Please install '%s' first.") % (prog, prog))
 
 # expand prefix to class name

Modified: grass/trunk/scripts/i.in.spotvgt/i.in.spotvgt.py
===================================================================
--- grass/trunk/scripts/i.in.spotvgt/i.in.spotvgt.py	2013-06-19 14:42:58 UTC (rev 56799)
+++ grass/trunk/scripts/i.in.spotvgt/i.in.spotvgt.py	2013-06-19 14:51:56 UTC (rev 56800)
@@ -112,7 +112,7 @@
     also = flags['a']
 
     #### check for gdalinfo (just to check if installation is complete)
-    if not grass.find_program('gdalinfo', ['--version']):
+    if not grass.find_program('gdalinfo'):
 	grass.fatal(_("'gdalinfo' not found, install GDAL tools first (http://www.gdal.org)"))
 
     pid = str(os.getpid())

Modified: grass/trunk/scripts/i.spectral/i.spectral.py
===================================================================
--- grass/trunk/scripts/i.spectral/i.spectral.py	2013-06-19 14:42:58 UTC (rev 56799)
+++ grass/trunk/scripts/i.spectral/i.spectral.py	2013-06-19 14:51:56 UTC (rev 56800)
@@ -166,7 +166,7 @@
         grass.fatal(_("group= and raster= are mutually exclusive"))
 
     #check if present
-    if gnuplot and not grass.find_program('gnuplot', ['-V']):
+    if gnuplot and not grass.find_program('gnuplot'):
         grass.fatal(_("gnuplot required, please install first"))
 
     # get y-data for gnuplot-data file

Modified: grass/trunk/scripts/r.in.aster/r.in.aster.py
===================================================================
--- grass/trunk/scripts/r.in.aster/r.in.aster.py	2013-06-19 14:42:58 UTC (rev 56799)
+++ grass/trunk/scripts/r.in.aster/r.in.aster.py	2013-06-19 14:51:56 UTC (rev 56800)
@@ -98,7 +98,7 @@
     band = options['band']
 
     #check whether gdalwarp is in path and executable
-    if not grass.find_program('gdalwarp', ['--version']):
+    if not grass.find_program('gdalwarp'):
         grass.fatal(_("gdalwarp is not in the path and executable"))
 
     #create temporary file to hold gdalwarp output before importing to GRASS

Modified: grass/trunk/scripts/v.db.univar/v.db.univar.py
===================================================================
--- grass/trunk/scripts/v.db.univar/v.db.univar.py	2013-06-19 14:42:58 UTC (rev 56799)
+++ grass/trunk/scripts/v.db.univar/v.db.univar.py	2013-06-19 14:51:56 UTC (rev 56800)
@@ -72,7 +72,7 @@
     inf = file(infile, 'r')
     outf = file(outfile, 'w')
 
-    if grass.find_program('sort', ['-n']):
+    if grass.find_program('sort'):
         grass.run_command('sort', flags = 'n', stdin = inf, stdout = outf)
     else:
         # FIXME: we need a large-file sorting function

Modified: grass/trunk/vector/v.colors/thumbnails.py
===================================================================
--- grass/trunk/vector/v.colors/thumbnails.py	2013-06-19 14:42:58 UTC (rev 56799)
+++ grass/trunk/vector/v.colors/thumbnails.py	2013-06-19 14:51:56 UTC (rev 56800)
@@ -71,7 +71,7 @@
     return dstd
 
 def ppmtopng(dst, src):
-    if grass.find_program("g.ppmtopng", ["help"]):
+    if grass.find_program("g.ppmtopng"):
         grass.run_command('g.ppmtopng', input = src, output = dst, quiet = True)
     elif grass.find_program("pnmtopng"):
         fh = open(dst, 'wb')



More information about the grass-commit mailing list