[GRASS-SVN] r45936 - grass/branches/releasebranch_6_4/lib/python

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Apr 13 07:31:56 EDT 2011


Author: martinl
Date: 2011-04-13 04:31:56 -0700 (Wed, 13 Apr 2011)
New Revision: 45936

Modified:
   grass/branches/releasebranch_6_4/lib/python/array.py
   grass/branches/releasebranch_6_4/lib/python/core.py
   grass/branches/releasebranch_6_4/lib/python/db.py
   grass/branches/releasebranch_6_4/lib/python/pythonlib.dox
   grass/branches/releasebranch_6_4/lib/python/vector.py
Log:
pythonlib: sync with devbr6


Modified: grass/branches/releasebranch_6_4/lib/python/array.py
===================================================================
--- grass/branches/releasebranch_6_4/lib/python/array.py	2011-04-13 11:30:28 UTC (rev 45935)
+++ grass/branches/releasebranch_6_4/lib/python/array.py	2011-04-13 11:31:56 UTC (rev 45936)
@@ -1,6 +1,6 @@
 """!@package grass.script.array
 
- at brief GRASS Python scripting module
+ at brief GRASS Python scripting module (rasters with numpy)
 
 Functions to use GRASS rasters with NumPy.
 
@@ -11,7 +11,7 @@
 ...
 @endcode
 
-(C) 2010 by Glynn Clements and the GRASS Development Team
+(C) 2010-2011 by Glynn Clements and the GRASS Development Team
 This program is free software under the GNU General Public
 License (>=v2). Read the file COPYING that comes with GRASS
 for details.
@@ -26,46 +26,59 @@
 
 # i18N
 import gettext
-gettext.install('grasslibs', os.path.join(os.getenv("GISBASE"), 'locale'), unicode=True)
+gettext.install('grasslibs', os.path.join(os.getenv("GISBASE"), 'locale'), unicode = True)
 
 class array(numpy.memmap):
     def __new__(cls, dtype = numpy.double):
+        """!Define new numpy array
+
+        @param cls
+        @param dtype data type (default: numpy.double)
+        """
 	reg = grass.region()
 	r = reg['rows']
 	c = reg['cols']
 	shape = (r, c)
-
+        
 	filename = grass.tempfile()
-
+        
 	self = numpy.memmap.__new__(
 	    cls,
 	    filename = filename,
 	    dtype = dtype,
 	    mode = 'w+',
 	    shape = shape)
-
+        
 	self.filename = filename
 	return self
-
+    
     def _close(self):
 	numpy.memmap._close(self)
 	if isinstance(self, array):
 	    grass.try_remove(self.filename)
 
     def read(self, mapname, null = None):
+        """!Read raster map into array
+
+        @param mapname name of raster map to be read
+        @param null null value
+
+        @return 0 on success
+        @return non-zero code on failure
+        """
 	kind = self.dtype.kind
 	size = self.dtype.itemsize
-
+        
 	if kind == 'f':
 	    flags = 'f'
 	elif kind in 'biu':
 	    flags = 'i'
 	else:
-	    raise ValueError(_('invalid kind <%s>') % kind)
-
+	    raise ValueError(_('Invalid kind <%s>') % kind)
+        
 	if size not in [1,2,4,8]:
-	    raise ValueError(_('invalid size <%d>') % size)
-
+	    raise ValueError(_('Invalid size <%d>') % size)
+        
 	return grass.run_command(
 	    'r.out.bin',
 	    flags = flags,
@@ -75,28 +88,37 @@
 	    null = null,
 	    quiet = True)
 	
+    def write(self, mapname, title = None, null = None, overwrite = None):
+        """!Write array into raster map
 
-    def write(self, mapname, title = None, null = None, overwrite = None):
+        @param mapname name for raster map
+        @param title title for raster map
+        @param null null value
+        @param overwrite True for overwritting existing raster maps
+
+        @return 0 on success
+        @return non-zero code on failure
+        """
 	kind = self.dtype.kind
 	size = self.dtype.itemsize
-
+        
 	if kind == 'f':
 	    if size == 4:
 		flags = 'f'
 	    elif size == 8:
 		flags = 'd'
 	    else:
-		raise ValueError(_('invalid FP size <%d>') % size)
+		raise ValueError(_('Invalid FP size <%d>') % size)
 	    size = None
 	elif kind in 'biu':
 	    if size not in [1,2,4]:
-		raise ValueError(_('invalid integer size <%d>') % size)
+		raise ValueError(_('Invalid integer size <%d>') % size)
 	    flags = None
 	else:
-	    raise ValueError(_('invalid kind <%s>') % kind)
-
+	    raise ValueError(_('Invalid kind <%s>') % kind)
+        
 	reg = grass.region()
-
+        
 	return grass.run_command(
 	    'r.in.bin',
 	    flags = flags,
@@ -113,3 +135,4 @@
 	    west  = reg['w'],
 	    rows  = reg['rows'],
 	    cols  = reg['cols'])
+    

Modified: grass/branches/releasebranch_6_4/lib/python/core.py
===================================================================
--- grass/branches/releasebranch_6_4/lib/python/core.py	2011-04-13 11:30:28 UTC (rev 45935)
+++ grass/branches/releasebranch_6_4/lib/python/core.py	2011-04-13 11:31:56 UTC (rev 45936)
@@ -13,14 +13,14 @@
 ...
 @endcode
 
-(C) 2008-2010 by the GRASS Development Team
+(C) 2008-2011 by the GRASS Development Team
 This program is free software under the GNU General Public
 License (>=v2). Read the file COPYING that comes with GRASS
 for details.
 
 @author Glynn Clements
 @author Martin Landa <landa.martin gmail.com>
- at author Michael Barton <michael.barton at asu.edu>
+ at author Michael Barton <michael.barton asu.edu>
 """
 
 import os
@@ -30,6 +30,7 @@
 import atexit
 import subprocess
 import shutil
+import locale
 import codecs
 
 # i18N
@@ -39,15 +40,15 @@
 # subprocess wrapper that uses shell on Windows
 
 class Popen(subprocess.Popen):
-    def __init__(self, args, bufsize=0, executable=None,
-                 stdin=None, stdout=None, stderr=None,
-                 preexec_fn=None, close_fds=False, shell=None,
-                 cwd=None, env=None, universal_newlines=False,
-                 startupinfo=None, creationflags=0):
-
+    def __init__(self, args, bufsize = 0, executable = None,
+                 stdin = None, stdout = None, stderr = None,
+                 preexec_fn = None, close_fds = False, shell = None,
+                 cwd = None, env = None, universal_newlines = False,
+                 startupinfo = None, creationflags = 0):
+        
 	if shell == None:
 	    shell = (sys.platform == "win32")
-
+        
 	subprocess.Popen.__init__(self, args, bufsize, executable,
                                   stdin, stdout, stderr,
                                   preexec_fn, close_fds, shell,
@@ -57,7 +58,7 @@
 PIPE = subprocess.PIPE
 STDOUT = subprocess.STDOUT
 
-class ScriptException(Exception):
+class ScriptError(Exception):
     def __init__(self, msg):
         self.value = msg
     
@@ -76,6 +77,13 @@
 	       "preexec_fn", "close_fds", "cwd", "env",
 	       "universal_newlines", "startupinfo", "creationflags"]
 
+def _decode(string):
+    enc = locale.getdefaultlocale()[1]
+    if enc:
+        return string.decode(enc)
+    
+    return string
+
 def _make_val(val):
     if isinstance(val, types.StringType) or \
             isinstance(val, types.UnicodeType):
@@ -86,6 +94,12 @@
 	return _make_val(list(val))
     return str(val)
 
+def _get_error(string):
+    try:
+        return string.split('\n')[-2]
+    except:
+        return ''
+
 def make_command(prog, flags = "", overwrite = False, quiet = False, verbose = False, **options):
     """!Return a list of strings suitable for use as the args parameter to
     Popen() or call(). Example:
@@ -173,9 +187,23 @@
 
     @return exit code (0 for success)
     """
+    if get_raise_on_error():
+        kwargs['stderr'] = PIPE
+        env = os.getenv('GRASS_MESSAGE_FORMAT')
+        os.environ['GRASS_MESSAGE_FORMAT'] = 'plain'
+
     ps = start_command(*args, **kwargs)
-    return ps.wait()
-
+    
+    if get_raise_on_error():
+        err = ps.communicate()[1]
+        if env:
+            os.environ['GRASS_MESSAGE_FORMAT'] = env
+        if ps.returncode != 0:
+            raise ScriptError(_("Error in %s(%s): %s") % ('run_command', args[0], _get_error(err)))
+        return ps.returncode
+    else:
+        return ps.wait()
+    
 def pipe_command(*args, **kwargs):
     """!Passes all arguments to start_command(), but also adds
     "stdout = PIPE". Returns the Popen object.
@@ -222,8 +250,22 @@
     
     @return stdout
     """
+    if get_raise_on_error():
+        kwargs['stderr'] = PIPE
+        env = os.getenv('GRASS_MESSAGE_FORMAT')
+        os.environ['GRASS_MESSAGE_FORMAT'] = 'plain'
+    
     ps = pipe_command(*args, **kwargs)
-    return ps.communicate()[0]
+    
+    if get_raise_on_error():
+        out, err = ps.communicate()
+        if env:
+            os.environ['GRASS_MESSAGE_FORMAT'] = env
+        if ps.returncode != 0:
+            raise ScriptError(_("Error in %s(%s): %s") % ('read_command', args[0], _get_error(err)))
+        return _decode(out)
+    else:
+        return _decode(ps.communicate()[0])
 
 def parse_command(*args, **kwargs):
     """!Passes all arguments to read_command, then parses the output by
@@ -266,11 +308,26 @@
     @return return code
     """
     stdin = kwargs['stdin']
+    if get_raise_on_error():
+        kwargs['stderr'] = PIPE
+        env = os.getenv('GRASS_MESSAGE_FORMAT')
+        os.environ['GRASS_MESSAGE_FORMAT'] = 'plain'
+    
     p = feed_command(*args, **kwargs)
     p.stdin.write(stdin)
-    p.stdin.close()
-    return p.wait()
-
+    
+    if get_raise_on_error():
+        err = p.communicate()[1]
+        if env:
+            os.environ['GRASS_MESSAGE_FORMAT'] = env
+        p.stdin.close()
+        if p.returncode != 0:
+            raise ScriptError(_("Error in %s(%s): %s") % ('write_command', args[0], _get_error(err)))
+        return p.returncode
+    else:
+        p.stdin.close()
+        return p.wait()
+    
 def exec_command(prog, flags = "", overwrite = False, quiet = False, verbose = False, env = None, **kwargs):
     """!Interface to os.execvpe(), but with the make_command() interface.
 
@@ -353,7 +410,7 @@
     """
     global raise_on_error
     if raise_on_error:
-        raise ScriptException(msg)
+        raise ScriptError(msg)
     else:
         message(msg, flag = 'e')
 
@@ -368,7 +425,7 @@
 def set_raise_on_error(raise_exp = True):
     """!Define behaviour on error (error() called)
 
-    @param raise_exp True to raise ScriptException instead of calling
+    @param raise_exp True to raise ScriptError instead of calling
     error()
     
     @return current status
@@ -376,7 +433,17 @@
     global raise_on_error
     tmp_raise = raise_on_error
     raise_on_error = raise_exp
+    
+    return tmp_raise
 
+def get_raise_on_error():
+    """!Get raise_on_error status
+
+    @return True to raise exception
+    """
+    global raise_on_error
+    return raise_on_error
+
 # interface to g.parser
 
 def _parse_opts(lines):
@@ -945,7 +1012,7 @@
                     datum = None, desc = None):
     """!Create new location
 
-    Raise ScriptException on error.
+    Raise ScriptError on error.
     
     @param dbase path to GRASS database
     @param location location name to create
@@ -1007,7 +1074,7 @@
                     set = 'GISDBASE=%s' % gisdbase)
         
         if ps.returncode != 0 and error:
-            raise ScriptException(repr(error))
+            raise ScriptError(repr(error))
 
     try:
         fd = codecs.open(os.path.join(dbase, location,
@@ -1019,12 +1086,12 @@
             fd.write(os.linesep)
         fd.close()
     except OSError, e:
-        raise ScriptException(repr(e))
+        raise ScriptError(repr(e))
         
 def _create_location_xy(database, location):
     """!Create unprojected location
 
-    Raise ScriptException on error.
+    Raise ScriptError on error.
     
     @param database GRASS database where to create new location
     @param location location name
@@ -1066,8 +1133,23 @@
         
         os.chdir(cur_dir)
     except OSError, e:
-        raise ScriptException(repr(e))
-    
+        raise ScriptError(repr(e))
+
+# interface to g.version
+
+def version():
+    """!Get GRASS version as dictionary
+
+    @code
+    version()
+
+    {'date': '2011', 'libgis_revision': '38990', 'version': '6.5.svn',
+     'libgis_date': '2009-09-05 19:01:13 +0200 (Sat, 05 Sep 2009)'}
+    @endcode
+    """
+    return parse_command('g.version',
+                         flags = 'rg')
+
 # get debug_level
 if find_program('g.gisenv', ['--help']):
     debug_level = int(gisenv().get('DEBUG', 0))

Modified: grass/branches/releasebranch_6_4/lib/python/db.py
===================================================================
--- grass/branches/releasebranch_6_4/lib/python/db.py	2011-04-13 11:30:28 UTC (rev 45935)
+++ grass/branches/releasebranch_6_4/lib/python/db.py	2011-04-13 11:31:56 UTC (rev 45936)
@@ -9,7 +9,6 @@
 @code
 from grass.script import db as grass
 
-grass.parser()
 grass.db_describe(table)
 ...
 @endcode
@@ -23,6 +22,8 @@
 @author Martin Landa <landa.martin gmail.com>
 """
 
+import tempfile as pytempfile # conflict with core.tempfile
+
 from core import *
 
 # i18N
@@ -48,7 +49,8 @@
     """
     s = read_command('db.describe', flags = 'c', table = table, **args)
     if not s:
-	return None
+	fatal(_("Unable to describe table <%s>") % table)
+    
     cols = []
     result = {}
     for l in s.splitlines():
@@ -63,6 +65,7 @@
 	else:
 	    result[key] = f[1:]
     result['cols'] = cols
+    
     return result
 
 # run "db.connect -p" and parse output
@@ -80,3 +83,30 @@
     """
     s = read_command('db.connect', flags = 'p')
     return parse_key_val(s, sep = ':')
+
+def db_select(table, sql, file = False, **args):
+    """!Perform SQL select statement
+
+    @param table table name
+    @param sql   SQL select statement (string or file)
+    @param file  True if sql is filename
+    @param args  see db.select arguments
+    """
+    ofile = pytempfile.NamedTemporaryFile(mode = 'w+b')
+    if not file:
+        ret = run_command('db.select', quiet = True,
+                          flags = 'c',
+                          table = table,
+                          sql = sql,
+                          output = ofile.name)
+    else: # -> sql is file
+        ret = run_command('db.select', quiet = True,
+                          flags = 'c',
+                          table = table,
+                          input = sql,
+                          output = ofile.name)
+    
+    if ret != 0:
+        fatal(_("Fetching data from table <%s> failed") % table)
+        
+    return ofile.readlines()

Modified: grass/branches/releasebranch_6_4/lib/python/pythonlib.dox
===================================================================
--- grass/branches/releasebranch_6_4/lib/python/pythonlib.dox	2011-04-13 11:30:28 UTC (rev 45935)
+++ grass/branches/releasebranch_6_4/lib/python/pythonlib.dox	2011-04-13 11:31:56 UTC (rev 45936)
@@ -15,6 +15,8 @@
 - db.py
 - raster.py
 - vector.py
+- setup.py
+- array.py
 
 <b>Table of content</b>
 
@@ -24,17 +26,21 @@
  - \subpage pythonDb
  - \subpage pythonRaster
  - \subpage pythonVector
+ - \subpage pythonSetup
+ - \subpage pythonArray
 
 \section pythonScripting GRASS scripting tasks for Python provided by "grass.script"
 
-Usage:
+Statement
 
 \code
 import grass.script as grass
 \endcode
 
-or just import selected module, e.g.
+imports core.py, db.py, raster.py and vector.py modules.
 
+To import only selected module
+
 \code
 from grass.script import core as grass
 \endcode
@@ -171,6 +177,10 @@
 
  - mapsets()
 
+<b>Interface to g.version</b>
+
+ - python::core::version()
+
 <b>Color parsing</b>
 
  - parse_color()
@@ -245,6 +255,22 @@
 
  - vector_layer_db()
 
+\section pythonSetup Setup
+
+\code
+from grass.script import setup as gsetup
+\endcode
+
+ - python::setup::init()
+
+\section pythonArray Array
+
+\code
+from grass.script import array as garray
+\endcode
+
+ - python::array::array
+
 \section pythonAuthors Authors
 
  Glynn Clements

Modified: grass/branches/releasebranch_6_4/lib/python/vector.py
===================================================================
--- grass/branches/releasebranch_6_4/lib/python/vector.py	2011-04-13 11:30:28 UTC (rev 45935)
+++ grass/branches/releasebranch_6_4/lib/python/vector.py	2011-04-13 11:31:56 UTC (rev 45936)
@@ -9,7 +9,6 @@
 @code
 from grass.script import vector as grass
 
-grass.parser()
 grass.vector_db(map)
 ...
 @endcode



More information about the grass-commit mailing list