Browse Source

python script library: update documentation and doctest; fix pep8

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@61917 15284696-431f-4ddb-bdfa-cd5b030d7da7
Luca Delucchi 11 years ago
parent
commit
28aac9cd13

+ 40 - 51
lib/python/script/array.py

@@ -1,30 +1,25 @@
-"""!@package grass.script.array
-
-@brief GRASS Python scripting module (2D and 3D raster with numpy)
-
+"""
 Functions to use GRASS 2D and 3D rasters with NumPy.
 Functions to use GRASS 2D and 3D rasters with NumPy.
 
 
 Usage:
 Usage:
 
 
-@code
-
 >>> import grass.script as grass
 >>> import grass.script as grass
 >>> from grass.script import array as garray
 >>> from grass.script import array as garray
->>> 
+>>>
 >>> # We create a temporary region that is only valid in this python session
 >>> # We create a temporary region that is only valid in this python session
 ... grass.use_temp_region()
 ... grass.use_temp_region()
 >>> grass.run_command("g.region", n=80, e=120, t=60, s=0, w=0, b=0, res=20, res3=20)
 >>> grass.run_command("g.region", n=80, e=120, t=60, s=0, w=0, b=0, res=20, res3=20)
 0
 0
->>> 
+>>>
 >>> # Lets create a raster map numpy array
 >>> # Lets create a raster map numpy array
 ... # based at the current region settings
 ... # based at the current region settings
 ... map2d_1 = garray.array()
 ... map2d_1 = garray.array()
->>> 
+>>>
 >>> # Write some data
 >>> # Write some data
 ... for y in range(map2d_1.shape[0]):
 ... for y in range(map2d_1.shape[0]):
 ...     for x in range(map2d_1.shape[1]):
 ...     for x in range(map2d_1.shape[1]):
 ...         map2d_1[y][x] = y + x
 ...         map2d_1[y][x] = y + x
-... 
+...
 >>> # Lets have a look at the array
 >>> # Lets have a look at the array
 ... print map2d_1
 ... print map2d_1
 [[ 0.  1.  2.  3.  4.  5.]
 [[ 0.  1.  2.  3.  4.  5.]
@@ -36,7 +31,7 @@ Usage:
 ... map2d_1.write(mapname="map2d_1", overwrite=True)
 ... map2d_1.write(mapname="map2d_1", overwrite=True)
  100%
  100%
 0
 0
->>> 
+>>>
 >>> # We create a new array and read map2d_1 to modify it
 >>> # We create a new array and read map2d_1 to modify it
 ... map2d_2 = garray.array()
 ... map2d_2 = garray.array()
 >>> # Don't do map2d_2 = map2d_1 % 3
 >>> # Don't do map2d_2 = map2d_1 % 3
@@ -54,30 +49,28 @@ Usage:
 ... map2d_2.write(mapname="map2d_2", overwrite=True)
 ... map2d_2.write(mapname="map2d_2", overwrite=True)
  100%
  100%
 0
 0
->>> 
+>>>
 >>> # Here we create a 3D raster map numpy array
 >>> # Here we create a 3D raster map numpy array
 ... # based in the current region settings
 ... # based in the current region settings
 ... map3d_1 = garray.array3d()
 ... map3d_1 = garray.array3d()
->>> 
+>>>
 >>> # Write some data
 >>> # Write some data
 ... # Note: the 3D array has map[depth][row][column] order
 ... # Note: the 3D array has map[depth][row][column] order
 ... for z in range(map3d_1.shape[0]):
 ... for z in range(map3d_1.shape[0]):
 ...     for y in range(map3d_1.shape[1]):
 ...     for y in range(map3d_1.shape[1]):
 ...         for x in range(map3d_1.shape[2]):
 ...         for x in range(map3d_1.shape[2]):
 ...             map3d_1[z][y][x] = z + y + x
 ...             map3d_1[z][y][x] = z + y + x
-... 
+...
 >>> # Lets have a look at the 3D array
 >>> # Lets have a look at the 3D array
 ... print map3d_1
 ... print map3d_1
 [[[  0.   1.   2.   3.   4.   5.]
 [[[  0.   1.   2.   3.   4.   5.]
   [  1.   2.   3.   4.   5.   6.]
   [  1.   2.   3.   4.   5.   6.]
   [  2.   3.   4.   5.   6.   7.]
   [  2.   3.   4.   5.   6.   7.]
   [  3.   4.   5.   6.   7.   8.]]
   [  3.   4.   5.   6.   7.   8.]]
-
  [[  1.   2.   3.   4.   5.   6.]
  [[  1.   2.   3.   4.   5.   6.]
   [  2.   3.   4.   5.   6.   7.]
   [  2.   3.   4.   5.   6.   7.]
   [  3.   4.   5.   6.   7.   8.]
   [  3.   4.   5.   6.   7.   8.]
   [  4.   5.   6.   7.   8.   9.]]
   [  4.   5.   6.   7.   8.   9.]]
-
  [[  2.   3.   4.   5.   6.   7.]
  [[  2.   3.   4.   5.   6.   7.]
   [  3.   4.   5.   6.   7.   8.]
   [  3.   4.   5.   6.   7.   8.]
   [  4.   5.   6.   7.   8.   9.]
   [  4.   5.   6.   7.   8.   9.]
@@ -101,12 +94,10 @@ Loading floating point data with 8 bytes ... (6x4x3)
   [ 1.  2.  0.  1.  2.  0.]
   [ 1.  2.  0.  1.  2.  0.]
   [ 2.  0.  1.  2.  0.  1.]
   [ 2.  0.  1.  2.  0.  1.]
   [ 0.  1.  2.  0.  1.  2.]]
   [ 0.  1.  2.  0.  1.  2.]]
-
  [[ 1.  2.  0.  1.  2.  0.]
  [[ 1.  2.  0.  1.  2.  0.]
   [ 2.  0.  1.  2.  0.  1.]
   [ 2.  0.  1.  2.  0.  1.]
   [ 0.  1.  2.  0.  1.  2.]
   [ 0.  1.  2.  0.  1.  2.]
   [ 1.  2.  0.  1.  2.  0.]]
   [ 1.  2.  0.  1.  2.  0.]]
-
  [[ 2.  0.  1.  2.  0.  1.]
  [[ 2.  0.  1.  2.  0.  1.]
   [ 0.  1.  2.  0.  1.  2.]
   [ 0.  1.  2.  0.  1.  2.]
   [ 1.  2.  0.  1.  2.  0.]
   [ 1.  2.  0.  1.  2.  0.]
@@ -117,14 +108,12 @@ Loading floating point data with 8 bytes ... (6x4x3)
  100%
  100%
 0
 0
 
 
-@endcode
-
 (C) 2010-2012 by Glynn Clements and the GRASS Development Team
 (C) 2010-2012 by Glynn Clements and the GRASS Development Team
 This program is free software under the GNU General Public
 This program is free software under the GNU General Public
 License (>=v2). Read the file COPYING that comes with GRASS
 License (>=v2). Read the file COPYING that comes with GRASS
 for details.
 for details.
 
 
-@author Glynn Clements
+.. sectionauthor:: Glynn Clements
 """
 """
 
 
 import os
 import os
@@ -138,10 +127,10 @@ import core as grass
 
 
 class array(numpy.memmap):
 class array(numpy.memmap):
     def __new__(cls, dtype=numpy.double):
     def __new__(cls, dtype=numpy.double):
-        """!Define new numpy array
+        """Define new numpy array
 
 
-        @param cls
-        @param dtype data type (default: numpy.double)
+        :param cls:
+        :param dtype: data type (default: numpy.double)
         """
         """
         reg = grass.region()
         reg = grass.region()
         r = reg['rows']
         r = reg['rows']
@@ -166,13 +155,13 @@ class array(numpy.memmap):
             try_remove(self.filename)
             try_remove(self.filename)
 
 
     def read(self, mapname, null=None):
     def read(self, mapname, null=None):
-        """!Read raster map into array
+        """Read raster map into array
 
 
-        @param mapname name of raster map to be read
-        @param null null value
+        :param str mapname: name of raster map to be read
+        :param null: null value
 
 
-        @return 0 on success
-        @return non-zero code on failure
+        :return: 0 on success
+        :return: non-zero code on failure
         """
         """
         kind = self.dtype.kind
         kind = self.dtype.kind
         size = self.dtype.itemsize
         size = self.dtype.itemsize
@@ -198,15 +187,15 @@ class array(numpy.memmap):
             overwrite=True)
             overwrite=True)
 
 
     def write(self, mapname, title=None, null=None, overwrite=None):
     def write(self, mapname, title=None, null=None, overwrite=None):
-        """!Write array into raster map
+        """Write array into raster map
 
 
-        @param mapname name for raster map
-        @param title title for raster map
-        @param null null value
-        @param overwrite True for overwritting existing raster maps
+        :param str mapname: name for raster map
+        :param str title: title for raster map
+        :param null: null value
+        :param bool overwrite: True for overwritting existing raster maps
 
 
-        @return 0 on success
-        @return non-zero code on failure
+        :return: 0 on success
+        :return: non-zero code on failure
         """
         """
         kind = self.dtype.kind
         kind = self.dtype.kind
         size = self.dtype.itemsize
         size = self.dtype.itemsize
@@ -246,12 +235,13 @@ class array(numpy.memmap):
 
 
 ###############################################################################
 ###############################################################################
 
 
+
 class array3d(numpy.memmap):
 class array3d(numpy.memmap):
     def __new__(cls, dtype=numpy.double):
     def __new__(cls, dtype=numpy.double):
-        """!Define new 3d numpy array
+        """Define new 3d numpy array
 
 
-        @param cls
-        @param dtype data type (default: numpy.double)
+        :param cls:
+        :param dtype: data type (default: numpy.double)
         """
         """
         reg = grass.region(True)
         reg = grass.region(True)
         r = reg['rows3']
         r = reg['rows3']
@@ -279,13 +269,13 @@ class array3d(numpy.memmap):
             try_remove(self.filename)
             try_remove(self.filename)
 
 
     def read(self, mapname, null=None):
     def read(self, mapname, null=None):
-        """!Read 3D raster map into array
+        """Read 3D raster map into array
 
 
-        @param mapname name of 3D raster map to be read
-        @param null null value
+        :param str mapname: name of 3D raster map to be read
+        :param null: null value
 
 
-        @return 0 on success
-        @return non-zero code on failure
+        :return: 0 on success
+        :return: non-zero code on failure
         """
         """
         kind = self.dtype.kind
         kind = self.dtype.kind
         size = self.dtype.itemsize
         size = self.dtype.itemsize
@@ -311,14 +301,14 @@ class array3d(numpy.memmap):
             overwrite=True)
             overwrite=True)
 
 
     def write(self, mapname, null=None, overwrite=None):
     def write(self, mapname, null=None, overwrite=None):
-        """!Write array into 3D raster map
+        """Write array into 3D raster map
 
 
-        @param mapname name for 3D raster map
-        @param null null value
-        @param overwrite True for overwriting existing raster maps
+        :param str mapname: name for 3D raster map
+        :param null: null value
+        :param bool overwrite: True for overwriting existing raster maps
 
 
-        @return 0 on success
-        @return non-zero code on failure
+        :return: 0 on success
+        :return: non-zero code on failure
         """
         """
         kind = self.dtype.kind
         kind = self.dtype.kind
         size = self.dtype.itemsize
         size = self.dtype.itemsize
@@ -353,4 +343,3 @@ class array3d(numpy.memmap):
             depths=reg['depths'],
             depths=reg['depths'],
             rows=reg['rows3'],
             rows=reg['rows3'],
             cols=reg['cols3'])
             cols=reg['cols3'])
-

File diff suppressed because it is too large
+ 275 - 300
lib/python/script/core.py


+ 28 - 14
lib/python/script/db.py

@@ -18,8 +18,8 @@ This program is free software under the GNU General Public
 License (>=v2). Read the file COPYING that comes with GRASS
 License (>=v2). Read the file COPYING that comes with GRASS
 for details.
 for details.
 
 
-@author Glynn Clements
-@author Martin Landa <landa.martin gmail.com>
+.. sectionauthor:: Glynn Clements
+.. sectionauthor:: Martin Landa <landa.martin gmail.com>
 """
 """
 
 
 from core import *
 from core import *
@@ -30,8 +30,12 @@ def db_describe(table, **args):
     """Return the list of columns for a database table
     """Return the list of columns for a database table
     (interface to `db.describe -c'). Example:
     (interface to `db.describe -c'). Example:
 
 
-    >>> db_describe('firestations')  # doctest: +ELLIPSIS
+    >>> run_command('g.copy', vect='firestations,myfirestations')
+    0
+    >>> db_describe('myfirestations') # doctest: +ELLIPSIS
     {'nrows': 71, 'cols': [['cat', 'INTEGER', '20'], ... 'ncols': 22}
     {'nrows': 71, 'cols': [['cat', 'INTEGER', '20'], ... 'ncols': 22}
+    >>> run_command('g.remove', vect='myfirestations')
+    0
 
 
     :param str table: table name
     :param str table: table name
     :param list args:
     :param list args:
@@ -66,8 +70,12 @@ def db_table_exist(table, **args):
     If no driver or database are given, then default settings is used
     If no driver or database are given, then default settings is used
     (check db_connection()).
     (check db_connection()).
 
 
-    >>> db_table_exist('firestations')
+    >>> run_command('g.copy', vect='firestations,myfirestations')
+    0
+    >>> db_table_exist('myfirestations')
     True
     True
+    >>> run_command('g.remove', vect='myfirestations')
+    0
 
 
     :param str table: table name
     :param str table: table name
     :param args:
     :param args:
@@ -104,12 +112,17 @@ def db_select(sql=None, filename=None, table=None, **args):
 
 
     Examples:
     Examples:
 
 
-    >>> db_select(sql = 'SELECT cat,CITY FROM firestations WHERE cat < 4')
-    (('1', 'Vet School'), ('2', 'West'), ('3', 'North'))
+    >>> run_command('g.copy', vect='firestations,myfirestations')
+    0
+    >>> db_select(sql = 'SELECT cat,CITY FROM myfirestations WHERE cat < 4')
+    (('1', 'Morrisville'), ('2', 'Morrisville'), ('3', 'Apex'))
 
 
-    Simplyfied usage (it performs <tt>SELECT * FROM busstopsall</tt>.)
+    Simplyfied usage (it performs <tt>SELECT * FROM myfirestations</tt>.)
 
 
-    >>> db_select(table = 'firestations')
+    >>> db_select(table = 'myfirestations') # doctest: +ELLIPSIS
+    (('1', '24', 'Morrisville #3', ... 'HS2A', '1.37'))
+    >>> run_command('g.remove', vect='myfirestations')
+    0
 
 
     :param str sql: SQL statement to perform (or None)
     :param str sql: SQL statement to perform (or None)
     :param str filename: name of file with SQL statements (or None)
     :param str filename: name of file with SQL statements (or None)
@@ -149,14 +162,15 @@ def db_table_in_vector(table):
     """Return the name of vector connected to the table.
     """Return the name of vector connected to the table.
     It returns None if no vectors are connected to the table.
     It returns None if no vectors are connected to the table.
 
 
-    >>> db_table_in_vector('geology')
-    ['geology@PERMANENT']
-    >>> db_table_in_vector('geologies')
-
+    >>> run_command('g.copy', vect='firestations,myfirestations')
+    0
+    >>> db_table_in_vector('myfirestations')
+    ['myfirestations@user1']
+    >>> db_table_in_vector('mfirestations')
+    >>> run_command('g.remove', vect='myfirestations')
+    0
 
 
     :param str table: name of table to query
     :param str table: name of table to query
-
-
     """
     """
     from vector import vector_db
     from vector import vector_db
     nuldev = file(os.devnull, 'w')
     nuldev = file(os.devnull, 'w')

+ 83 - 87
lib/python/script/raster.py

@@ -1,4 +1,4 @@
-"""!@package grass.script.raster
+"""@package grass.script.raster
 
 
 @brief GRASS Python scripting module (raster functions)
 @brief GRASS Python scripting module (raster functions)
 
 
@@ -6,20 +6,19 @@ Raster related functions to be used in Python scripts.
 
 
 Usage:
 Usage:
 
 
-@code
-from grass.script import raster as grass
+::
+
+    from grass.script import raster as grass
+    grass.raster_history(map)
 
 
-grass.raster_history(map)
-...
-@endcode
 
 
 (C) 2008-2011 by the GRASS Development Team
 (C) 2008-2011 by the GRASS Development Team
 This program is free software under the GNU General Public
 This program is free software under the GNU General Public
 License (>=v2). Read the file COPYING that comes with GRASS
 License (>=v2). Read the file COPYING that comes with GRASS
 for details.
 for details.
 
 
-@author Glynn Clements
-@author Martin Landa <landa.martin gmail.com>
+.. sectionauthor:: Glynn Clements
+.. sectionauthor:: Martin Landa <landa.martin gmail.com>
 """
 """
 
 
 import os
 import os
@@ -30,44 +29,38 @@ import time
 from core import *
 from core import *
 from utils import float_or_dms, parse_key_val
 from utils import float_or_dms, parse_key_val
 
 
-# add raster history
 
 
 def raster_history(map):
 def raster_history(map):
-    """!Set the command history for a raster map to the command used to
+    """Set the command history for a raster map to the command used to
     invoke the script (interface to `r.support').
     invoke the script (interface to `r.support').
 
 
-    @param map map name
+    :param str map: map name
+
+    :return: True on success
+    :return: False on failure
 
 
-    @return True on success
-    @return False on failure
     """
     """
     current_mapset = gisenv()['MAPSET']
     current_mapset = gisenv()['MAPSET']
-    if find_file(name = map)['mapset'] == current_mapset:
-        run_command('r.support', map = map, history = os.environ['CMDLINE'])
+    if find_file(name=map)['mapset'] == current_mapset:
+        run_command('r.support', map=map, history=os.environ['CMDLINE'])
         return True
         return True
-    
+
     warning(_("Unable to write history for <%(map)s>. "
     warning(_("Unable to write history for <%(map)s>. "
-              "Raster map <%(map)s> not found in current mapset." % { 'map' : map, 'map' : map}))
+              "Raster map <%(map)s> not found in current mapset." % { 'map': map, 'map': map}))
     return False
     return False
 
 
-# run "r.info -gre ..." and parse output
 
 
 def raster_info(map):
 def raster_info(map):
-    """!Return information about a raster map (interface to
-    `r.info'). Example:
-
-    \code
-    >>> grass.raster_info('elevation')
-    {'north': 228500.0, 'timestamp': '"none"', 'min': 55.578792572021499,
-    'datatype': 'FCELL', 'max': 156.32986450195301, 'ewres': 10.0,
-    'vertical_datum': '', 'west': 630000.0, 'units': '',
-    'title': 'South-West Wake county: Elevation NED 10m (elev_ned10m)',
-    'east': 645000.0, 'nsres': 10.0, 'south': 215000.0}
-    \endcode
-
-    @param map map name
-    
-    @return parsed raster info
+    """Return information about a raster map (interface to
+    `r.info -gre'). Example:
+
+    >>> raster_info('elevation') # doctest: +ELLIPSIS
+    {'creator': '"helena"', 'cols': '1500' ... 'south': 215000.0}
+
+    :param str map: map name
+
+    :return: parsed raster info
+
     """
     """
 
 
     def float_or_null(s):
     def float_or_null(s):
@@ -76,7 +69,7 @@ def raster_info(map):
         else:
         else:
             return float(s)
             return float(s)
 
 
-    s = read_command('r.info', flags = 'gre', map = map)
+    s = read_command('r.info', flags='gre', map=map)
     kv = parse_key_val(s)
     kv = parse_key_val(s)
     for k in ['min', 'max']:
     for k in ['min', 'max']:
         kv[k] = float_or_null(kv[k])
         kv[k] = float_or_null(kv[k])
@@ -86,20 +79,19 @@ def raster_info(map):
         kv[k] = float_or_dms(kv[k])
         kv[k] = float_or_dms(kv[k])
     return kv
     return kv
 
 
-# interface to r.mapcalc
 
 
-def mapcalc(exp, quiet = False, verbose = False, overwrite = False,
-            seed = None, env = None, **kwargs):
-    """!Interface to r.mapcalc.
+def mapcalc(exp, quiet=False, verbose=False, overwrite=False,
+            seed=None, env=None, **kwargs):
+    """Interface to r.mapcalc.
 
 
-    @param exp expression
-    @param quiet True to run quietly (<tt>--q</tt>)
-    @param verbose True to run verbosely (<tt>--v</tt>)
-    @param overwrite True to enable overwriting the output (<tt>--o</tt>)
-    @param seed an integer used to seed the random-number generator for the rand() function,
-    or 'auto' to generate a random seed
-    @param env dictionary of environment variables for child process
-    @param kwargs
+    :param str exp: expression
+    :param bool quiet: True to run quietly (<tt>--q</tt>)
+    :param bool verbose: True to run verbosely (<tt>--v</tt>)
+    :param bool overwrite: True to enable overwriting the output (<tt>--o</tt>)
+    :param seed: an integer used to seed the random-number generator for the
+                 rand() function, or 'auto' to generate a random seed
+    :param dict env: dictionary of environment variables for child process
+    :param kwargs:
     """
     """
 
 
     if seed == 'auto':
     if seed == 'auto':
@@ -108,41 +100,40 @@ def mapcalc(exp, quiet = False, verbose = False, overwrite = False,
     t = string.Template(exp)
     t = string.Template(exp)
     e = t.substitute(**kwargs)
     e = t.substitute(**kwargs)
 
 
-    if write_command('r.mapcalc', file = '-', stdin = e,
-                     env = env,
-                     seed = seed,
-                     quiet = quiet,
-                     verbose = verbose,
-                     overwrite = overwrite) != 0:
+    if write_command('r.mapcalc', file='-', stdin=e, env=env, seed=seed,
+                     quiet=quiet, verbose=verbose, overwrite=overwrite) != 0:
         fatal(_("An error occurred while running r.mapcalc"))
         fatal(_("An error occurred while running r.mapcalc"))
 
 
 
 
-def mapcalc_start(exp, quiet = False, verbose = False, overwrite = False,
-                  seed = None, env = None, **kwargs):
-    """!Interface to r.mapcalc, doesn't wait for it to finish, returns Popen object.
+def mapcalc_start(exp, quiet=False, verbose=False, overwrite=False,
+                  seed=None, env=None, **kwargs):
+    """Interface to r.mapcalc, doesn't wait for it to finish, returns Popen object.
 
 
-    \code
+    >>> output = 'newele'
+    >>> input = 'elevation'
     >>> expr1 = '"%s" = "%s" * 10' % (output, input)
     >>> expr1 = '"%s" = "%s" * 10' % (output, input)
     >>> expr2 = '...'   # etc.
     >>> expr2 = '...'   # etc.
     >>> # launch the jobs:
     >>> # launch the jobs:
-    >>> p1 = grass.mapcalc_start(expr1)
-    >>> p2 = grass.mapcalc_start(expr2)   # etc.
+    >>> p1 = mapcalc_start(expr1)
+    >>> p2 = mapcalc_start(expr2)
     ...
     ...
     >>> # wait for them to finish:
     >>> # wait for them to finish:
     >>> p1.wait()
     >>> p1.wait()
-    >>> p2.wait()   # etc.
-    \endcode
-
-    @param exp expression
-    @param quiet True to run quietly (<tt>--q</tt>)
-    @param verbose True to run verbosely (<tt>--v</tt>)
-    @param overwrite True to enable overwriting the output (<tt>--o</tt>)
-    @param seed an integer used to seed the random-number generator for the rand() function,
-    or 'auto' to generate a random seed
-    @param env dictionary of environment variables for child process
-    @param kwargs
-    
-    @return Popen object
+    0
+    >>> p2.wait()
+    1
+    >>> run_command('g.remove', rast=output)
+
+    :param str exp: expression
+    :param bool quiet: True to run quietly (<tt>--q</tt>)
+    :param bool verbose: True to run verbosely (<tt>--v</tt>)
+    :param bool overwrite: True to enable overwriting the output (<tt>--o</tt>)
+    :param seed: an integer used to seed the random-number generator for the
+                 rand() function, or 'auto' to generate a random seed
+    :param dict env: dictionary of environment variables for child process
+    :param kwargs:
+
+    :return: Popen object
     """
     """
 
 
     if seed == 'auto':
     if seed == 'auto':
@@ -151,19 +142,24 @@ def mapcalc_start(exp, quiet = False, verbose = False, overwrite = False,
     t = string.Template(exp)
     t = string.Template(exp)
     e = t.substitute(**kwargs)
     e = t.substitute(**kwargs)
 
 
-    p = feed_command('r.mapcalc', file = '-',
-                     env = env,
-                     seed = seed,
-                     quiet = quiet,
-                     verbose = verbose,
-                     overwrite = overwrite)
+    p = feed_command('r.mapcalc', file='-', env=env, seed=seed,
+                     quiet=quiet, verbose=verbose, overwrite=overwrite)
     p.stdin.write(e)
     p.stdin.write(e)
     p.stdin.close()
     p.stdin.close()
     return p
     return p
 
 
-# interface to r.what
-def raster_what(map, coord, env = None):
-    """!TODO"""
+
+def raster_what(map, coord, env=None):
+    """Interface to r.what
+
+    >>> raster_what('elevation', [[640000, 228000]])
+    [{'elevation': {'color': '255:214:000', 'label': '', 'value': '102.479'}}]
+
+    :param str map: the map name
+    :param list coord: a list of list containing all the point that you want
+                       query
+    :param env:
+    """
     if type(map) in (types.StringType, types.UnicodeType):
     if type(map) in (types.StringType, types.UnicodeType):
         map_list = [map]
         map_list = [map]
     else:
     else:
@@ -175,18 +171,18 @@ def raster_what(map, coord, env = None):
     else:
     else:
         for e, n in coord:
         for e, n in coord:
             coord_list.append('%f,%f' % (e, n))
             coord_list.append('%f,%f' % (e, n))
-    
+
     sep = '|'
     sep = '|'
     # separator '|' not included in command
     # separator '|' not included in command
     # because | is causing problems on Windows
     # because | is causing problems on Windows
     # change separator?
     # change separator?
     ret = read_command('r.what',
     ret = read_command('r.what',
-                       flags = 'rf',
-                       map = ','.join(map_list),
-                       coordinates = ','.join(coord_list),
-                       null = _("No data"),
-                       quiet = True,
-                       env = env)
+                       flags='rf',
+                       map=','.join(map_list),
+                       coordinates=','.join(coord_list),
+                       null=_("No data"),
+                       quiet=True,
+                       env=env)
     data = list()
     data = list()
     if not ret:
     if not ret:
         return data
         return data

+ 31 - 41
lib/python/script/raster3d.py

@@ -1,52 +1,43 @@
-"""!@package grass.script.raster3d
-
-@brief GRASS Python scripting module (raster3d functions)
-
+"""
 Raster3d related functions to be used in Python scripts.
 Raster3d related functions to be used in Python scripts.
 
 
 Usage:
 Usage:
 
 
-@code
-from grass.script import raster3d as grass
+::
+
+    from grass.script import raster3d as grass
+    grass.raster3d_info(map)
 
 
-grass.raster3d_info(map)
-...
-@endcode
 
 
 (C) 2008-2009 by the GRASS Development Team
 (C) 2008-2009 by the GRASS Development Team
 This program is free software under the GNU General Public
 This program is free software under the GNU General Public
 License (>=v2). Read the file COPYING that comes with GRASS
 License (>=v2). Read the file COPYING that comes with GRASS
 for details.
 for details.
 
 
-@author Glynn Clements
-@author Martin Landa <landa.martin gmail.com>
-@author Soeren Gebbert <soeren.gebbert gmail.com>
+.. sectionauthor:: Glynn Clements
+.. sectionauthor:: Martin Landa <landa.martin gmail.com>
+.. sectionauthor:: Soeren Gebbert <soeren.gebbert gmail.com>
 """
 """
 
 
-import os
 import string
 import string
 
 
 from core import *
 from core import *
 from utils import float_or_dms, parse_key_val
 from utils import float_or_dms, parse_key_val
 
 
-# add raster history
-
-# run "r3.info -rstgip ..." and parse output
 
 
 def raster3d_info(map):
 def raster3d_info(map):
-    """!Return information about a raster3d map (interface to
-    `r3.info'). Example:
-
-    \code
-    >>> grass.raster3d_info('volume')
-    {'tiledimz': 1, 'tbres': 1.0, 'tiledimx': 27, 'tiledimy': 16, 'north': 60.490001999999997, 'tilenumy': 1, 'tilenumz': 1, 
-    'min': 1.0, 'datatype': '"DCELL"', 'max': 1.0, 'top': 0.5, 'bottom': -0.5, 'west': -3.2200000000000002, 'tilenumx': 1, 
-    'ewres': 0.98222219, 'east': 23.299999, 'nsres': 0.99937511999999995, 'Timestamp': '"none"', 'south': 44.5}
-    \endcode
-
-    @param map map name
-    
-    @return parsed raster3d info
+    """Return information about a raster3d map (interface to `r3.info`).
+    Example:
+
+    >>> mapcalc3d('volume = row() + col() + depth()')
+    >>> raster3d_info('volume') # doctest: +ELLIPSIS
+    {'vertical_units': '"units"', 'tbres': 1.0, ... 'south': 185000.0}
+    >>> run_command('g.remove', rast3d='volume')
+    0
+
+    :param str map: map name
+
+    :return: parsed raster3d info
     """
     """
 
 
     def float_or_null(s):
     def float_or_null(s):
@@ -71,22 +62,21 @@ def raster3d_info(map):
         kv[k] = int(kv[k])
         kv[k] = int(kv[k])
     return kv
     return kv
 
 
-# interface to r3.mapcalc
 
 
-def mapcalc3d(exp, quiet = False, verbose = False, overwrite = False, **kwargs):
-    """!Interface to r3.mapcalc.
+def mapcalc3d(exp, quiet=False, verbose=False, overwrite=False, **kwargs):
+    """Interface to r3.mapcalc.
 
 
-    @param exp expression
-    @param quiet True to run quietly (<tt>--q</tt>)
-    @param verbose True to run verbosely (<tt>--v</tt>)
-    @param overwrite True to enable overwriting the output (<tt>--o</tt>)
-    @param kwargs
+    :param str exp: expression
+    :param bool quiet: True to run quietly (<tt>--q</tt>)
+    :param bool verbose: True to run verbosely (<tt>--v</tt>)
+    :param bool overwrite: True to enable overwriting the output (<tt>--o</tt>)
+    :param kwargs:
     """
     """
     t = string.Template(exp)
     t = string.Template(exp)
     e = t.substitute(**kwargs)
     e = t.substitute(**kwargs)
 
 
-    if run_command('r3.mapcalc', expression = e,
-                   quiet = quiet,
-                   verbose = verbose,
-                   overwrite = overwrite) != 0:
+    if run_command('r3.mapcalc', expression=e,
+                   quiet=quiet,
+                   verbose=verbose,
+                   overwrite=overwrite) != 0:
         fatal(_("An error occurred while running r3.mapcalc"))
         fatal(_("An error occurred while running r3.mapcalc"))

+ 212 - 199
lib/python/script/task.py

@@ -1,26 +1,21 @@
-"""!@package grass.script.task
-
-@brief GRASS Python scripting module (task)
-
+"""
 Get interface description of GRASS commands
 Get interface description of GRASS commands
 
 
 Based on gui/wxpython/gui_modules/menuform.py
 Based on gui/wxpython/gui_modules/menuform.py
 
 
 Usage:
 Usage:
 
 
-@code
-from grass.script import task as gtask
+::
 
 
-gtask.command_info('r.info')
-...
-@endcode
+    from grass.script import task as gtask
+    gtask.command_info('r.info')
 
 
 (C) 2011 by the GRASS Development Team
 (C) 2011 by the GRASS Development Team
 This program is free software under the GNU General Public
 This program is free software under the GNU General Public
 License (>=v2). Read the file COPYING that comes with GRASS
 License (>=v2). Read the file COPYING that comes with GRASS
 for details.
 for details.
 
 
-@author Martin Landa <landa.martin gmail.com>
+.. sectionauthor:: Martin Landa <landa.martin gmail.com>
 """
 """
 
 
 import types
 import types
@@ -33,22 +28,23 @@ except ImportError:
 from utils import decode
 from utils import decode
 from core import *
 from core import *
 
 
+
 class grassTask:
 class grassTask:
-    """!This class holds the structures needed for filling by the
+    """This class holds the structures needed for filling by the
     parser
     parser
 
 
     Parameter blackList is a dictionary with fixed structure, eg.
     Parameter blackList is a dictionary with fixed structure, eg.
 
 
-    @code
-    blackList = {'items' : {'d.legend' : { 'flags' : ['m'],
-                                           'params' : [] }},
+    ::
+
+    blackList = {'items' : {'d.legend' : { 'flags' : ['m'], 'params' : [] }},
                  'enabled': True}
                  'enabled': True}
-    @endcode
-    
-    @param path full path
-    @param blackList hide some options in the GUI (dictionary)
+
+
+    :param str path: full path
+    :param blackList: hide some options in the GUI (dictionary)
     """
     """
-    def __init__(self, path = None, blackList = None):
+    def __init__(self, path=None, blackList=None):
         self.path = path
         self.path = path
         self.name = _('unknown')
         self.name = _('unknown')
         self.params = list()
         self.params = list()
@@ -61,34 +57,34 @@ class grassTask:
         if blackList:
         if blackList:
             self.blackList = blackList
             self.blackList = blackList
         else:
         else:
-            self.blackList = { 'enabled' : False, 'items' : {} }
-        
+            self.blackList = {'enabled': False, 'items': {}}
+
         if path is not None:
         if path is not None:
             try:
             try:
-                processTask(tree = etree.fromstring(get_interface_description(path)),
-                            task = self)
+                processTask(tree=etree.fromstring(get_interface_description(path)),
+                            task=self)
             except ScriptError as e:
             except ScriptError as e:
                 self.errorMsg = e.value
                 self.errorMsg = e.value
-            
+
             self.define_first()
             self.define_first()
-        
+
     def define_first(self):
     def define_first(self):
-        """!Define first parameter
+        """Define first parameter
 
 
-        @return name of first parameter
+        :return: name of first parameter
         """
         """
         if len(self.params) > 0:
         if len(self.params) > 0:
             self.firstParam = self.params[0]['name']
             self.firstParam = self.params[0]['name']
-        
+
         return self.firstParam
         return self.firstParam
-    
+
     def get_error_msg(self):
     def get_error_msg(self):
-        """!Get error message ('' for no error)
+        """Get error message ('' for no error)
         """
         """
         return self.errorMsg
         return self.errorMsg
-    
+
     def get_name(self):
     def get_name(self):
-        """!Get task name
+        """Get task name
         """
         """
         if sys.platform == 'win32':
         if sys.platform == 'win32':
             name, ext = os.path.splitext(self.name)
             name, ext = os.path.splitext(self.name)
@@ -96,13 +92,13 @@ class grassTask:
                 return name
                 return name
             else:
             else:
                 return self.name
                 return self.name
-        
+
         return self.name
         return self.name
 
 
-    def get_description(self, full = True):
-        """!Get module's description
+    def get_description(self, full=True):
+        """Get module's description
 
 
-        @param full True for label + desc
+        :param bool full: True for label + desc
         """
         """
         if self.label:
         if self.label:
             if full:
             if full:
@@ -113,38 +109,38 @@ class grassTask:
             return self.description
             return self.description
 
 
     def get_keywords(self):
     def get_keywords(self):
-        """!Get module's keywords
+        """Get module's keywords
         """
         """
         return self.keywords
         return self.keywords
-    
-    def get_list_params(self, element = 'name'):
-        """!Get list of parameters
 
 
-        @param element element name
+    def get_list_params(self, element='name'):
+        """Get list of parameters
+
+        :param str element: element name
         """
         """
         params = []
         params = []
         for p in self.params:
         for p in self.params:
             params.append(p[element])
             params.append(p[element])
-        
+
         return params
         return params
 
 
-    def get_list_flags(self, element = 'name'):
-        """!Get list of flags
+    def get_list_flags(self, element='name'):
+        """Get list of flags
 
 
-        @param element element name
+        :param str element: element name
         """
         """
         flags = []
         flags = []
         for p in self.flags:
         for p in self.flags:
             flags.append(p[element])
             flags.append(p[element])
-        
+
         return flags
         return flags
-    
-    def get_param(self, value, element = 'name', raiseError = True):
-        """!Find and return a param by name
 
 
-        @param value param's value
-        @param element element name
-        @param raiseError True for raise on error
+    def get_param(self, value, element='name', raiseError=True):
+        """Find and return a param by name
+
+        :param value: param's value
+        :param str element: element name
+        :param bool raiseError: True for raise on error
         """
         """
         try:
         try:
             for p in self.params:
             for p in self.params:
@@ -162,7 +158,7 @@ class grassTask:
                         return p
                         return p
         except KeyError:
         except KeyError:
             pass
             pass
-        
+
         if raiseError:
         if raiseError:
             raise ValueError, _("Parameter element '%(element)s' not found: '%(value)s'") % \
             raise ValueError, _("Parameter element '%(element)s' not found: '%(value)s'") % \
                 { 'element' : element, 'value' : value }
                 { 'element' : element, 'value' : value }
@@ -170,28 +166,28 @@ class grassTask:
             return None
             return None
 
 
     def get_flag(self, aFlag):
     def get_flag(self, aFlag):
-        """!Find and return a flag by name
+        """Find and return a flag by name
 
 
         Raises ValueError when the flag is not found.
         Raises ValueError when the flag is not found.
 
 
-        @param aFlag name of the flag
+        :param str aFlag: name of the flag
         """
         """
         for f in self.flags:
         for f in self.flags:
-            if f['name'] ==  aFlag:
+            if f['name'] == aFlag:
                 return f
                 return f
         raise ValueError, _("Flag not found: %s") % aFlag
         raise ValueError, _("Flag not found: %s") % aFlag
 
 
     def get_cmd_error(self):
     def get_cmd_error(self):
-        """!Get error string produced by get_cmd(ignoreErrors = False)
-        
-        @return list of errors
+        """Get error string produced by get_cmd(ignoreErrors = False)
+
+        :return: list of errors
         """
         """
         errorList = list()
         errorList = list()
         # determine if suppress_required flag is given
         # determine if suppress_required flag is given
         for f in self.flags:
         for f in self.flags:
             if f['value'] and f['suppress_required']:
             if f['value'] and f['suppress_required']:
                 return errorList
                 return errorList
-        
+
         for p in self.params:
         for p in self.params:
             if not p.get('value', '') and p.get('required', False):
             if not p.get('value', '') and p.get('required', False):
                 if not p.get('default', ''):
                 if not p.get('default', ''):
@@ -199,136 +195,138 @@ class grassTask:
                     if not desc:
                     if not desc:
                         desc = p['description']
                         desc = p['description']
                     errorList.append(_("Parameter '%(name)s' (%(desc)s) is missing.") % \
                     errorList.append(_("Parameter '%(name)s' (%(desc)s) is missing.") % \
-                                         {'name' : p['name'], 'desc' : desc })
-        
+                                     {'name': p['name'], 'desc': desc})
+
         return errorList
         return errorList
-    
-    def get_cmd(self, ignoreErrors = False, ignoreRequired = False, ignoreDefault = True):
-        """!Produce an array of command name and arguments for feeding
+
+    def get_cmd(self, ignoreErrors=False, ignoreRequired=False,
+                ignoreDefault=True):
+        """Produce an array of command name and arguments for feeding
         into some execve-like command processor.
         into some execve-like command processor.
 
 
-        @param ignoreErrors True to return whatever has been built so
-        far, even though it would not be a correct command for GRASS
-        @param ignoreRequired True to ignore required flags, otherwise
-        '@<required@>' is shown
-        @param ignoreDefault True to ignore parameters with default values
+        :param bool ignoreErrors: True to return whatever has been built so
+                                  far, even though it would not be a correct
+                                  command for GRASS
+        :param bool ignoreRequired: True to ignore required flags, otherwise
+                                    '@<required@>' is shown
+        :param bool ignoreDefault: True to ignore parameters with default values
         """
         """
         cmd = [self.get_name()]
         cmd = [self.get_name()]
-        
+
         suppress_required = False
         suppress_required = False
         for flag in self.flags:
         for flag in self.flags:
             if flag['value']:
             if flag['value']:
-                if len(flag['name']) > 1: # e.g. overwrite
-                    cmd +=  [ '--' + flag['name'] ]
+                if len(flag['name']) > 1:  # e.g. overwrite
+                    cmd += ['--' + flag['name']]
                 else:
                 else:
-                    cmd +=  [ '-' + flag['name'] ]
+                    cmd += ['-' + flag['name']]
                 if flag['suppress_required']:
                 if flag['suppress_required']:
                     suppress_required = True
                     suppress_required = True
         for p in self.params:
         for p in self.params:
-            if p.get('value', '') ==  '' and p.get('required', False):
-                if p.get('default', '') !=  '':
-                    cmd +=  [ '%s=%s' % (p['name'], p['default']) ]
+            if p.get('value', '') == '' and p.get('required', False):
+                if p.get('default', '') != '':
+                    cmd += ['%s=%s' % (p['name'], p['default'])]
                 elif ignoreErrors and not suppress_required and not ignoreRequired:
                 elif ignoreErrors and not suppress_required and not ignoreRequired:
                     cmd += [('%s=%s' % (p['name'], _('<required>'))).decode('utf-8')]
                     cmd += [('%s=%s' % (p['name'], _('<required>'))).decode('utf-8')]
-            elif p.get('value', '') ==  '' and p.get('default', '') != '' and not ignoreDefault:
-                cmd +=  [ '%s=%s' % (p['name'], p['default']) ]
-            elif p.get('value', '') !=  '' and \
-                    (p['value'] !=  p.get('default', '') or not ignoreDefault):
+            elif p.get('value', '') == '' and p.get('default', '') != '' and not ignoreDefault:
+                cmd += ['%s=%s' % (p['name'], p['default'])]
+            elif p.get('value', '') != '' and \
+                    (p['value'] != p.get('default', '') or not ignoreDefault):
                 # output only values that have been set, and different from defaults
                 # output only values that have been set, and different from defaults
-                cmd +=  [ '%s=%s' % (p['name'], p['value']) ]
-        
+                cmd += ['%s=%s' % (p['name'], p['value'])]
+
         errList = self.get_cmd_error()
         errList = self.get_cmd_error()
         if ignoreErrors is False and errList:
         if ignoreErrors is False and errList:
             raise ValueError, '\n'.join(errList)
             raise ValueError, '\n'.join(errList)
-        
+
         return cmd
         return cmd
 
 
     def get_options(self):
     def get_options(self):
-        """!Get options
+        """Get options
         """
         """
-        return { 'flags'  : self.flags,
-                 'params' : self.params }
-    
+        return {'flags': self.flags, 'params': self.params}
+
     def has_required(self):
     def has_required(self):
-        """!Check if command has at least one required paramater
+        """Check if command has at least one required paramater
         """
         """
         for p in self.params:
         for p in self.params:
             if p.get('required', False):
             if p.get('required', False):
                 return True
                 return True
-        
+
         return False
         return False
-    
-    def set_param(self, aParam, aValue, element = 'value'):
-        """!Set param value/values.
+
+    def set_param(self, aParam, aValue, element='value'):
+        """Set param value/values.
         """
         """
         try:
         try:
             param = self.get_param(aParam)
             param = self.get_param(aParam)
         except ValueError:
         except ValueError:
             return
             return
-        
+
         param[element] = aValue
         param[element] = aValue
 
 
-    def set_flag(self, aFlag, aValue, element = 'value'):
-        """!Enable / disable flag.
+    def set_flag(self, aFlag, aValue, element='value'):
+        """Enable / disable flag.
         """
         """
         try:
         try:
             param = self.get_flag(aFlag)
             param = self.get_flag(aFlag)
         except ValueError:
         except ValueError:
             return
             return
-        
+
         param[element] = aValue
         param[element] = aValue
 
 
     def set_options(self, opts):
     def set_options(self, opts):
-        """!Set flags and parameters
+        """Set flags and parameters
 
 
-        @param opts list of flags and parameters"""
+        :param opts list of flags and parameters"""
         for opt in opts:
         for opt in opts:
-            if opt[0] ==  '-': # flag
+            if opt[0] ==  '-':  # flag
                 self.set_flag(opt.lstrip('-'), True)
                 self.set_flag(opt.lstrip('-'), True)
-            else: # parameter
+            else:  # parameter
                 key, value = opt.split('=', 1)
                 key, value = opt.split('=', 1)
                 self.set_param(key, value)
                 self.set_param(key, value)
-        
+
+
 class processTask:
 class processTask:
-    """!A ElementTree handler for the --interface-description output,
+    """A ElementTree handler for the --interface-description output,
     as defined in grass-interface.dtd. Extend or modify this and the
     as defined in grass-interface.dtd. Extend or modify this and the
     DTD if the XML output of GRASS' parser is extended or modified.
     DTD if the XML output of GRASS' parser is extended or modified.
 
 
-    @param tree root tree node
-    @param task grassTask instance or None
-    @param blackList list of flags/params to hide
-    
-    @return grassTask instance
+    :param tree: root tree node
+    :param task: grassTask instance or None
+    :param blackList: list of flags/params to hide
+
+    :return: grassTask instance
     """
     """
-    def __init__(self, tree, task = None, blackList = None):
+    def __init__(self, tree, task=None, blackList=None):
         if task:
         if task:
             self.task = task
             self.task = task
         else:
         else:
             self.task = grassTask()
             self.task = grassTask()
         if blackList:
         if blackList:
             self.task.blackList = blackList
             self.task.blackList = blackList
-        
+
         self.root = tree
         self.root = tree
-        
+
         self._process_module()
         self._process_module()
         self._process_params()
         self._process_params()
         self._process_flags()
         self._process_flags()
         self.task.define_first()
         self.task.define_first()
-        
+
     def _process_module(self):
     def _process_module(self):
-        """!Process module description
+        """Process module description
         """
         """
-        self.task.name = self.root.get('name', default = 'unknown')
-        
+        self.task.name = self.root.get('name', default='unknown')
+
         # keywords
         # keywords
         for keyword in self._get_node_text(self.root, 'keywords').split(','):
         for keyword in self._get_node_text(self.root, 'keywords').split(','):
             self.task.keywords.append(keyword.strip())
             self.task.keywords.append(keyword.strip())
-        
-        self.task.label       = self._get_node_text(self.root, 'label')
+
+        self.task.label = self._get_node_text(self.root, 'label')
         self.task.description = self._get_node_text(self.root, 'description')
         self.task.description = self._get_node_text(self.root, 'description')
-        
+
     def _process_params(self):
     def _process_params(self):
-        """!Process parameters
+        """Process parameters
         """
         """
         for p in self.root.findall('parameter'):
         for p in self.root.findall('parameter'):
             # gisprompt
             # gisprompt
@@ -337,10 +335,10 @@ class processTask:
             age = element = prompt = None
             age = element = prompt = None
             if node_gisprompt is not None:
             if node_gisprompt is not None:
                 gisprompt = True
                 gisprompt = True
-                age     = node_gisprompt.get('age', '')
+                age = node_gisprompt.get('age', '')
                 element = node_gisprompt.get('element', '')
                 element = node_gisprompt.get('element', '')
-                prompt  = node_gisprompt.get('prompt', '')
-            
+                prompt = node_gisprompt.get('prompt', '')
+
             # value(s)
             # value(s)
             values = []
             values = []
             values_desc = []
             values_desc = []
@@ -351,30 +349,30 @@ class processTask:
                     desc = self._get_node_text(pv, 'description')
                     desc = self._get_node_text(pv, 'description')
                     if desc:
                     if desc:
                         values_desc.append(desc)
                         values_desc.append(desc)
-            
+
             # keydesc
             # keydesc
             key_desc = []
             key_desc = []
             node_key_desc = p.find('keydesc')
             node_key_desc = p.find('keydesc')
             if node_key_desc is not None:
             if node_key_desc is not None:
                 for ki in node_key_desc.findall('item'):
                 for ki in node_key_desc.findall('item'):
                     key_desc.append(ki.text)
                     key_desc.append(ki.text)
-            
-            if p.get('multiple', 'no') ==  'yes':
+
+            if p.get('multiple', 'no') == 'yes':
                 multiple = True
                 multiple = True
             else:
             else:
                 multiple = False
                 multiple = False
-            if p.get('required', 'no') ==  'yes':
+            if p.get('required', 'no') == 'yes':
                 required = True
                 required = True
             else:
             else:
                 required = False
                 required = False
-            
+
             if self.task.blackList['enabled'] and \
             if self.task.blackList['enabled'] and \
                     self.task.name in self.task.blackList['items'] and \
                     self.task.name in self.task.blackList['items'] and \
                     p.get('name') in self.task.blackList['items'][self.task.name].get('params', []):
                     p.get('name') in self.task.blackList['items'][self.task.name].get('params', []):
                 hidden = True
                 hidden = True
             else:
             else:
                 hidden = False
                 hidden = False
-            
+
             self.task.params.append( {
             self.task.params.append( {
                 "name"           : p.get('name'),
                 "name"           : p.get('name'),
                 "type"           : p.get('type'),
                 "type"           : p.get('type'),
@@ -395,9 +393,9 @@ class processTask:
                 "key_desc"       : key_desc,
                 "key_desc"       : key_desc,
                 "hidden"         : hidden
                 "hidden"         : hidden
                 })
                 })
-            
+
     def _process_flags(self):
     def _process_flags(self):
-        """!Process flags
+        """Process flags
         """
         """
         for p in self.root.findall('flag'):
         for p in self.root.findall('flag'):
             if self.task.blackList['enabled'] and \
             if self.task.blackList['enabled'] and \
@@ -406,12 +404,12 @@ class processTask:
                 hidden = True
                 hidden = True
             else:
             else:
                 hidden = False
                 hidden = False
-            
+
             if p.find('suppress_required') is not None:
             if p.find('suppress_required') is not None:
                 suppress_required = True
                 suppress_required = True
             else:
             else:
                 suppress_required = False
                 suppress_required = False
-            
+
             self.task.flags.append( {
             self.task.flags.append( {
                     "name"              : p.get('name'),
                     "name"              : p.get('name'),
                     "label"             : self._get_node_text(p, 'label'),
                     "label"             : self._get_node_text(p, 'label'),
@@ -421,141 +419,156 @@ class processTask:
                     "value"             : False,
                     "value"             : False,
                     "hidden"            : hidden
                     "hidden"            : hidden
                     } )
                     } )
-        
-    def _get_node_text(self, node, tag, default = ''):
-        """!Get node text"""
+
+    def _get_node_text(self, node, tag, default=''):
+        """Get node text"""
         p = node.find(tag)
         p = node.find(tag)
         if p is not None:
         if p is not None:
             return string.join(string.split(p.text), ' ')
             return string.join(string.split(p.text), ' ')
-        
+
         return default
         return default
-    
+
     def get_task(self):
     def get_task(self):
-        """!Get grassTask instance"""
+        """Get grassTask instance"""
         return self.task
         return self.task
 
 
+
 def convert_xml_to_utf8(xml_text):
 def convert_xml_to_utf8(xml_text):
     # enc = locale.getdefaultlocale()[1]
     # enc = locale.getdefaultlocale()[1]
-    
+
     # modify: fetch encoding from the interface description text(xml)
     # modify: fetch encoding from the interface description text(xml)
     # e.g. <?xml version="1.0" encoding="GBK"?>
     # e.g. <?xml version="1.0" encoding="GBK"?>
     pattern = re.compile('<\?xml[^>]*\Wencoding="([^"]*)"[^>]*\?>')
     pattern = re.compile('<\?xml[^>]*\Wencoding="([^"]*)"[^>]*\?>')
     m = re.match(pattern, xml_text)
     m = re.match(pattern, xml_text)
-    if m == None:
+    if m is None:
         return xml_text
         return xml_text
     #
     #
     enc = m.groups()[0]
     enc = m.groups()[0]
-    
+
     # modify: change the encoding to "utf-8", for correct parsing
     # modify: change the encoding to "utf-8", for correct parsing
     xml_text_utf8 = xml_text.decode(enc).encode("utf-8")
     xml_text_utf8 = xml_text.decode(enc).encode("utf-8")
     p = re.compile('encoding="' + enc + '"', re.IGNORECASE)
     p = re.compile('encoding="' + enc + '"', re.IGNORECASE)
     xml_text_utf8 = p.sub('encoding="utf-8"', xml_text_utf8)
     xml_text_utf8 = p.sub('encoding="utf-8"', xml_text_utf8)
-    
+
     return xml_text_utf8
     return xml_text_utf8
 
 
+
 def get_interface_description(cmd):
 def get_interface_description(cmd):
-    """!Returns the XML description for the GRASS cmd (force text encoding to "utf-8").
+    """Returns the XML description for the GRASS cmd (force text encoding to
+    "utf-8").
 
 
     The DTD must be located in $GISBASE/gui/xml/grass-interface.dtd,
     The DTD must be located in $GISBASE/gui/xml/grass-interface.dtd,
     otherwise the parser will not succeed.
     otherwise the parser will not succeed.
 
 
-    @param cmd command (name of GRASS module)
+    :param cmd: command (name of GRASS module)
     """
     """
     try:
     try:
-        p = Popen([cmd, '--interface-description'], stdout = PIPE,
-                  stderr = PIPE)
+        p = Popen([cmd, '--interface-description'], stdout=PIPE,
+                  stderr=PIPE)
         cmdout, cmderr = p.communicate()
         cmdout, cmderr = p.communicate()
-        
+
         # TODO: do it better (?)
         # TODO: do it better (?)
         if not cmdout and sys.platform == 'win32':
         if not cmdout and sys.platform == 'win32':
             # we in fact expect pure module name (without extension)
             # we in fact expect pure module name (without extension)
             # so, lets remove extension
             # so, lets remove extension
             if cmd.endswith('.py'):
             if cmd.endswith('.py'):
                 cmd = os.path.splitext(cmd)[0]
                 cmd = os.path.splitext(cmd)[0]
-            
+
             if cmd == 'd.rast3d':
             if cmd == 'd.rast3d':
-                sys.path.insert(0, os.path.join(os.getenv('GISBASE'), 'etc', 'gui', 'scripts'))
-            
-            p = Popen([sys.executable, get_real_command(cmd), '--interface-description'],
-                      stdout = PIPE, stderr = PIPE)
+                sys.path.insert(0, os.path.join(os.getenv('GISBASE'), 'etc',
+                                                'gui', 'scripts'))
+
+            p = Popen([sys.executable, get_real_command(cmd),
+                       '--interface-description'],
+                      stdout=PIPE, stderr=PIPE)
             cmdout, cmderr = p.communicate()
             cmdout, cmderr = p.communicate()
-            
+
             if cmd == 'd.rast3d':
             if cmd == 'd.rast3d':
-                del sys.path[0] # remove gui/scripts from the path
-            
+                del sys.path[0]  # remove gui/scripts from the path
+
         if p.returncode != 0:
         if p.returncode != 0:
             raise ScriptError, _("Unable to fetch interface description for command '%(cmd)s'."
             raise ScriptError, _("Unable to fetch interface description for command '%(cmd)s'."
-                                 "\n\nDetails: %(det)s") % { 'cmd' : cmd, 'det' : decode(cmderr) }
-    
+                                 "\n\nDetails: %(det)s") % {'cmd': cmd, 'det': decode(cmderr)}
+
     except OSError as e:
     except OSError as e:
         raise ScriptError, _("Unable to fetch interface description for command '%(cmd)s'."
         raise ScriptError, _("Unable to fetch interface description for command '%(cmd)s'."
-                             "\n\nDetails: %(det)s") % { 'cmd' : cmd, 'det' : e }
-    
-    desc = cmdout.replace('grass-interface.dtd', os.path.join(os.getenv('GISBASE'), 'gui', 'xml', 'grass-interface.dtd'))
+                             "\n\nDetails: %(det)s") % {'cmd': cmd, 'det': e}
+
+    desc = cmdout.replace('grass-interface.dtd',
+                          os.path.join(os.getenv('GISBASE'),
+                                       'gui', 'xml',
+                                       'grass-interface.dtd'))
     return convert_xml_to_utf8(desc)
     return convert_xml_to_utf8(desc)
 
 
-def parse_interface(name, parser = processTask, blackList = None):
-    """!Parse interface of given GRASS module
-    
-    @param name name of GRASS module to be parsed
+
+def parse_interface(name, parser=processTask, blackList=None):
+    """Parse interface of given GRASS module
+
+    :param str name: name of GRASS module to be parsed
+    :param parser:
+    :param blackList:
     """
     """
     tree = etree.fromstring(get_interface_description(name))
     tree = etree.fromstring(get_interface_description(name))
-    return parser(tree, blackList = blackList).get_task()
+    return parser(tree, blackList=blackList).get_task()
+
 
 
 def command_info(cmd):
 def command_info(cmd):
-    """!Returns meta information for any GRASS command as dictionary
+    """Returns meta information for any GRASS command as dictionary
     with entries for description, keywords, usage, flags, and
     with entries for description, keywords, usage, flags, and
     parameters, e.g.
     parameters, e.g.
-    
-    @code
-    >>> gtask.command_info('g.tempfile')
-    
-    {'keywords': ['general', 'map management'],
-     'params': [{'gisprompt': False, 'multiple': False, 'name': 'pid', 'guidependency': '',
-                'default': '', 'age': None, 'required': True, 'value': '',
-                'label': '', 'guisection': '', 'key_desc': [], 'values': [], 'values_desc': [],
-                'prompt': None, 'hidden': False, 'element': None, 'type': 'integer',
-                'description': 'Process id to use when naming the tempfile'}],
-     'flags': [{'description': 'Verbose module output', 'value': False, 'label': '', 'guisection': '',
-                'suppress_required': False, 'hidden': False, 'name': 'verbose'}, {'description': 'Quiet module output',
-                'value': False, 'label': '', 'guisection': '', 'suppress_required': False, 'hidden': False, 'name': 'quiet'}],
-     'description': 'Creates a temporary file and prints the file name.',
-     'usage': 'g.tempfile pid=integer [--verbose] [--quiet]'
-    }
-
-    >>> gtask.command_info('v.buffer')['keywords']
-    
+
+    >>> command_info('g.tempfile') # doctest: +NORMALIZE_WHITESPACE
+    {'keywords': ['general', 'support'], 'params': [{'gisprompt': False,
+    'multiple': False, 'name': 'pid', 'guidependency': '', 'default': '',
+    'age': None, 'required': True, 'value': '', 'label': '', 'guisection': '',
+    'key_desc': [], 'values': [], 'values_desc': [], 'prompt': None,
+    'hidden': False, 'element': None, 'type': 'integer', 'description':
+    'Process id to use when naming the tempfile'}], 'flags': [{'description':
+    "Dry run - don't create a file, just prints it's file name", 'value':
+    False, 'label': '', 'guisection': '', 'suppress_required': False,
+    'hidden': False, 'name': 'd'}, {'description': 'Print usage summary',
+    'value': False, 'label': '', 'guisection': '', 'suppress_required': False,
+    'hidden': False, 'name': 'help'}, {'description': 'Verbose module output',
+    'value': False, 'label': '', 'guisection': '', 'suppress_required': False,
+    'hidden': False, 'name': 'verbose'}, {'description': 'Quiet module output',
+    'value': False, 'label': '', 'guisection': '', 'suppress_required': False,
+    'hidden': False, 'name': 'quiet'}], 'description': "Creates a temporary
+    file and prints it's file name.", 'usage': 'g.tempfile pid=integer [--help]
+    [--verbose] [--quiet]'}
+
+    >>> command_info('v.buffer')
     ['vector', 'geometry', 'buffer']
     ['vector', 'geometry', 'buffer']
-    @endcode
+
+    :param str cmd: the command to query
     """
     """
     task = parse_interface(cmd)
     task = parse_interface(cmd)
     cmdinfo = {}
     cmdinfo = {}
-    
+
     cmdinfo['description'] = task.get_description()
     cmdinfo['description'] = task.get_description()
-    cmdinfo['keywords']    = task.get_keywords()
-    cmdinfo['flags']       = flags = task.get_options()['flags']
-    cmdinfo['params']      = params = task.get_options()['params']
-    
+    cmdinfo['keywords'] = task.get_keywords()
+    cmdinfo['flags'] = flags = task.get_options()['flags']
+    cmdinfo['params'] = params = task.get_options()['params']
+
     usage = task.get_name()
     usage = task.get_name()
     flags_short = list()
     flags_short = list()
-    flags_long  = list()
+    flags_long = list()
     for f in flags:
     for f in flags:
         fname = f.get('name', 'unknown')
         fname = f.get('name', 'unknown')
         if len(fname) > 1:
         if len(fname) > 1:
             flags_long.append(fname)
             flags_long.append(fname)
         else:
         else:
             flags_short.append(fname)
             flags_short.append(fname)
-    
+
     if len(flags_short) > 1:
     if len(flags_short) > 1:
         usage += ' [-' + ''.join(flags_short) + ']'
         usage += ' [-' + ''.join(flags_short) + ']'
-    
+
     for p in params:
     for p in params:
         ptype = ','.join(p.get('key_desc', []))
         ptype = ','.join(p.get('key_desc', []))
         if not ptype:
         if not ptype:
             ptype = p.get('type', '')
             ptype = p.get('type', '')
-        req =  p.get('required', False)
+        req = p.get('required', False)
         if not req:
         if not req:
-           usage += ' ['
+            usage += ' ['
         else:
         else:
             usage += ' '
             usage += ' '
         usage += p['name'] + '=' + ptype
         usage += p['name'] + '=' + ptype
@@ -563,10 +576,10 @@ def command_info(cmd):
             usage += '[,' + ptype + ',...]'
             usage += '[,' + ptype + ',...]'
         if not req:
         if not req:
             usage += ']'
             usage += ']'
-        
+
     for key in flags_long:
     for key in flags_long:
         usage += ' [--' + key + ']'
         usage += ' [--' + key + ']'
-    
+
     cmdinfo['usage'] = usage
     cmdinfo['usage'] = usage
-    
+
     return cmdinfo
     return cmdinfo

+ 38 - 38
lib/python/script/utils.py

@@ -1,25 +1,20 @@
-"""!@package grass.script.utils
-
-@brief GRASS Python scripting module (various useful functions)
-
+"""
 Useful functions to be used in Python scripts.
 Useful functions to be used in Python scripts.
 
 
 Usage:
 Usage:
 
 
-@code
-from grass.script import utils as gutils
+::
 
 
-...
-@endcode
+    from grass.script import utils as gutils
 
 
 (C) 2014 by the GRASS Development Team
 (C) 2014 by the GRASS Development Team
 This program is free software under the GNU General Public
 This program is free software under the GNU General Public
 License (>=v2). Read the file COPYING that comes with GRASS
 License (>=v2). Read the file COPYING that comes with GRASS
 for details.
 for details.
 
 
-@author Glynn Clements
-@author Martin Landa <landa.martin gmail.com>
-@author Anna Petrasova <kratochanna gmail.com>
+.. sectionauthor:: Glynn Clements
+.. sectionauthor:: Martin Landa <landa.martin gmail.com>
+.. sectionauthor:: Anna Petrasova <kratochanna gmail.com>
 """
 """
 
 
 import os
 import os
@@ -28,22 +23,22 @@ import locale
 
 
 
 
 def float_or_dms(s):
 def float_or_dms(s):
-    """!Convert DMS to float.
+    """Convert DMS to float.
 
 
     >>> round(float_or_dms('26:45:30'), 5)
     >>> round(float_or_dms('26:45:30'), 5)
     26.75833
     26.75833
     >>> round(float_or_dms('26:0:0.1'), 5)
     >>> round(float_or_dms('26:0:0.1'), 5)
     26.00003
     26.00003
 
 
-    @param s DMS value
+    :param s: DMS value
 
 
-    @return float value
+    :return: float value
     """
     """
     return sum(float(x) / 60 ** n for (n, x) in enumerate(s.split(':')))
     return sum(float(x) / 60 ** n for (n, x) in enumerate(s.split(':')))
 
 
 
 
 def separator(sep):
 def separator(sep):
-    """!Returns separator from G_OPT_F_SEP appropriately converted
+    """Returns separator from G_OPT_F_SEP appropriately converted
     to character.
     to character.
 
 
     >>> separator('pipe')
     >>> separator('pipe')
@@ -57,9 +52,9 @@ def separator(sep):
     >>> separator(', ')
     >>> separator(', ')
     ', '
     ', '
 
 
-    @param separator character or separator keyword
+    :param str separator: character or separator keyword
 
 
-    @return separator character
+    :return: separator character
     """
     """
     if sep == "pipe":
     if sep == "pipe":
         return "|"
         return "|"
@@ -75,12 +70,12 @@ def separator(sep):
 
 
 
 
 def diff_files(filename_a, filename_b):
 def diff_files(filename_a, filename_b):
-    """!Diffs two text files and returns difference.
+    """Diffs two text files and returns difference.
 
 
-    @param filename_a first file path
-    @param filename_b second file path
+    :param str filename_a: first file path
+    :param str filename_b: second file path
 
 
-    @return list of strings
+    :return: list of strings
     """
     """
     import difflib
     import difflib
     differ = difflib.Differ()
     differ = difflib.Differ()
@@ -92,10 +87,10 @@ def diff_files(filename_a, filename_b):
 
 
 
 
 def try_remove(path):
 def try_remove(path):
-    """!Attempt to remove a file; no exception is generated if the
+    """Attempt to remove a file; no exception is generated if the
     attempt fails.
     attempt fails.
 
 
-    @param path path to file to remove
+    :param str path: path to file to remove
     """
     """
     try:
     try:
         os.remove(path)
         os.remove(path)
@@ -104,10 +99,10 @@ def try_remove(path):
 
 
 
 
 def try_rmdir(path):
 def try_rmdir(path):
-    """!Attempt to remove a directory; no exception is generated if the
+    """Attempt to remove a directory; no exception is generated if the
     attempt fails.
     attempt fails.
 
 
-    @param path path to directory to remove
+    :param str path: path to directory to remove
     """
     """
     try:
     try:
         os.rmdir(path)
         os.rmdir(path)
@@ -116,11 +111,11 @@ def try_rmdir(path):
 
 
 
 
 def basename(path, ext=None):
 def basename(path, ext=None):
-    """!Remove leading directory components and an optional extension
+    """Remove leading directory components and an optional extension
     from the specified path
     from the specified path
 
 
-    @param path path
-    @param ext extension
+    :param str path: path
+    :param str ext: extension
     """
     """
     name = os.path.basename(path)
     name = os.path.basename(path)
     if not ext:
     if not ext:
@@ -137,7 +132,6 @@ class KeyValue(dict):
     KeyValue is a subclass of dict, but also allows entries to be read and
     KeyValue is a subclass of dict, but also allows entries to be read and
     written using attribute syntax. Example:
     written using attribute syntax. Example:
 
 
-    \code
     >>> reg = KeyValue()
     >>> reg = KeyValue()
     >>> reg['north'] = 489
     >>> reg['north'] = 489
     >>> reg.north
     >>> reg.north
@@ -145,8 +139,6 @@ class KeyValue(dict):
     >>> reg.south = 205
     >>> reg.south = 205
     >>> reg['south']
     >>> reg['south']
     205
     205
-
-    \endcode
     """
     """
 
 
     def __getattr__(self, key):
     def __getattr__(self, key):
@@ -157,7 +149,7 @@ class KeyValue(dict):
 
 
 
 
 def parse_key_val(s, sep='=', dflt=None, val_type=None, vsep=None):
 def parse_key_val(s, sep='=', dflt=None, val_type=None, vsep=None):
-    """!Parse a string into a dictionary, where entries are separated
+    """Parse a string into a dictionary, where entries are separated
     by newlines and the key and value are separated by `sep' (default: `=')
     by newlines and the key and value are separated by `sep' (default: `=')
 
 
     >>> parse_key_val('min=20\\nmax=50') == {'min': '20', 'max': '50'}
     >>> parse_key_val('min=20\\nmax=50') == {'min': '20', 'max': '50'}
@@ -166,13 +158,13 @@ def parse_key_val(s, sep='=', dflt=None, val_type=None, vsep=None):
     ...     val_type=float) == {'min': 20, 'max': 50}
     ...     val_type=float) == {'min': 20, 'max': 50}
     True
     True
 
 
-    @param s string to be parsed
-    @param sep key/value separator
-    @param dflt default value to be used
-    @param val_type value type (None for no cast)
-    @param vsep vertical separator (default is Python 'universal newlines' approach)
+    :param str s: string to be parsed
+    :param str sep: key/value separator
+    :param dflt: default value to be used
+    :param val_type: value type (None for no cast)
+    :param vsep: vertical separator (default is Python 'universal newlines' approach)
 
 
-    @return parsed input (dictionary of keys/values)
+    :return: parsed input (dictionary of keys/values)
     """
     """
     result = KeyValue()
     result = KeyValue()
 
 
@@ -205,6 +197,10 @@ def parse_key_val(s, sep='=', dflt=None, val_type=None, vsep=None):
 
 
 
 
 def decode(string):
 def decode(string):
+    """Decode string with defualt locale
+
+    :param str string: the string to decode
+    """
     enc = locale.getdefaultlocale()[1]
     enc = locale.getdefaultlocale()[1]
     if enc:
     if enc:
         return string.decode(enc)
         return string.decode(enc)
@@ -213,6 +209,10 @@ def decode(string):
 
 
 
 
 def encode(string):
 def encode(string):
+    """Encode string with defualt locale
+
+    :param str string: the string to encode
+    """
     enc = locale.getdefaultlocale()[1]
     enc = locale.getdefaultlocale()[1]
     if enc:
     if enc:
         return string.encode(enc)
         return string.encode(enc)

+ 172 - 184
lib/python/script/vector.py

@@ -1,25 +1,20 @@
-"""!@package grass.script.vector
-
-@brief GRASS Python scripting module (vector functions)
-
+"""
 Vector related functions to be used in Python scripts.
 Vector related functions to be used in Python scripts.
 
 
 Usage:
 Usage:
 
 
-@code
-from grass.script import vector as grass
+::
 
 
-grass.vector_db(map)
-...
-@endcode
+    from grass.script import vector as grass
+    grass.vector_db(map)
 
 
 (C) 2008-2010 by the GRASS Development Team
 (C) 2008-2010 by the GRASS Development Team
 This program is free software under the GNU General Public
 This program is free software under the GNU General Public
 License (>=v2). Read the file COPYING that comes with GRASS
 License (>=v2). Read the file COPYING that comes with GRASS
 for details.
 for details.
 
 
-@author Glynn Clements
-@author Martin Landa <landa.martin gmail.com>
+.. sectionauthor:: Glynn Clements
+.. sectionauthor:: Martin Landa <landa.martin gmail.com>
 """
 """
 
 
 import os
 import os
@@ -30,32 +25,28 @@ import __builtin__
 from utils import parse_key_val
 from utils import parse_key_val
 from core import *
 from core import *
 
 
-# run "v.db.connect -g ..." and parse output
 
 
 def vector_db(map, **args):
 def vector_db(map, **args):
-    """!Return the database connection details for a vector map
+    """Return the database connection details for a vector map
     (interface to `v.db.connect -g'). Example:
     (interface to `v.db.connect -g'). Example:
-    
-    \code
-    >>> grass.vector_db('lakes')
-    {1: {'layer': 1, 'name': '',
-    'database': '/home/martin/grassdata/nc_spm_08/PERMANENT/dbf/',
-    'driver': 'dbf', 'key': 'cat', 'table': 'lakes'}}
-    \endcode
-    
-    @param map vector map
-    @param args other v.db.connect's arguments
-    
-    @return dictionary
+
+    >>> vector_db('geology') # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
+    {1: {'layer': 1, ... 'table': 'geology'}}
+
+    :param str map: vector map
+    :param args: other v.db.connect's arguments
+
+    :return: dictionary
     """
     """
-    s = read_command('v.db.connect', quiet = True, flags = 'g', map = map, sep = ';', **args)
+    s = read_command('v.db.connect', quiet=True, flags='g', map=map, sep=';',
+                     **args)
     result = {}
     result = {}
-    
+
     for l in s.splitlines():
     for l in s.splitlines():
         f = l.split(';')
         f = l.split(';')
         if len(f) != 5:
         if len(f) != 5:
             continue
             continue
-        
+
         if '/' in f[0]:
         if '/' in f[0]:
             f1 = f[0].split('/')
             f1 = f[0].split('/')
             layer = f1[0]
             layer = f1[0]
@@ -63,7 +54,7 @@ def vector_db(map, **args):
         else:
         else:
             layer = f[0]
             layer = f[0]
             name = ''
             name = ''
-            
+
         result[int(layer)] = {
         result[int(layer)] = {
             'layer'    : int(layer),
             'layer'    : int(layer),
             'name'     : name,
             'name'     : name,
@@ -71,17 +62,18 @@ def vector_db(map, **args):
             'key'      : f[2],
             'key'      : f[2],
             'database' : f[3],
             'database' : f[3],
             'driver'   : f[4] }
             'driver'   : f[4] }
-    
+
     return result
     return result
 
 
+
 def vector_layer_db(map, layer):
 def vector_layer_db(map, layer):
-    """!Return the database connection details for a vector map layer.
+    """Return the database connection details for a vector map layer.
     If db connection for given layer is not defined, fatal() is called.
     If db connection for given layer is not defined, fatal() is called.
-    
-    @param map map name
-    @param layer layer number
-    
-    @return parsed output
+
+    :param str map: map name
+    :param layer: layer number
+
+    :return: parsed output
     """
     """
     try:
     try:
         f = vector_db(map)[int(layer)]
         f = vector_db(map)[int(layer)]
@@ -92,27 +84,40 @@ def vector_layer_db(map, layer):
 
 
 # run "v.info -c ..." and parse output
 # run "v.info -c ..." and parse output
 
 
-def vector_columns(map, layer = None, getDict = True, **args):
-    """!Return a dictionary (or a list) of the columns for the
+
+def vector_columns(map, layer=None, getDict=True, **args):
+    """Return a dictionary (or a list) of the columns for the
     database table connected to a vector map (interface to `v.info
     database table connected to a vector map (interface to `v.info
     -c').
     -c').
 
 
-    @code
-    >>> vector_columns(urbanarea, getDict = True)
-    {'UA_TYPE': {'index': 4, 'type': 'CHARACTER'}, 'UA': {'index': 2, 'type': 'CHARACTER'}, 'NAME': {'index': 3, 'type': 'CHARACTER'}, 'OBJECTID': {'index': 1, 'type': 'INTEGER'}, 'cat': {'index': 0, 'type': 'INTEGER'}}
-
-    >>> vector_columns(urbanarea, getDict = False)
-    ['cat', 'OBJECTID', 'UA', 'NAME', 'UA_TYPE']
-    @endcode
-    
-    @param map map name
-    @param layer layer number or name (None for all layers)
-    @param getDict True to return dictionary of columns otherwise list of column names is returned
-    @param args (v.info's arguments)
-    
-    @return dictionary/list of columns
+    >>> vector_columns('geology', getDict=True) # doctest: +NORMALIZE_WHITESPACE
+    {'PERIMETER': {'index': 2, 'type': 'DOUBLE PRECISION'}, 'GEOL250_':
+    {'index': 3, 'type': 'INTEGER'}, 'SHAPE_area': {'index': 6, 'type':
+    'DOUBLE PRECISION'}, 'onemap_pro': {'index': 1, 'type': 'DOUBLE
+    PRECISION'}, 'SHAPE_len': {'index': 7, 'type': 'DOUBLE PRECISION'},
+    'cat': {'index': 0, 'type': 'INTEGER'}, 'GEOL250_ID': {'index': 4, 'type':
+    'INTEGER'}, 'GEO_NAME': {'index': 5, 'type': 'CHARACTER'}}
+
+    >>> vector_columns('geology', getDict=False) # doctest: +NORMALIZE_WHITESPACE
+    ['cat',
+     'onemap_pro',
+     'PERIMETER',
+     'GEOL250_',
+     'GEOL250_ID',
+     'GEO_NAME',
+     'SHAPE_area',
+     'SHAPE_len']
+
+    :param str map: map name
+    :param layer: layer number or name (None for all layers)
+    :param bool getDict: True to return dictionary of columns otherwise list
+                         of column names is returned
+    :param args: (v.info's arguments)
+
+    :return: dictionary/list of columns
     """
     """
-    s = read_command('v.info', flags = 'c', map = map, layer = layer, quiet = True, **args)
+    s = read_command('v.info', flags='c', map=map, layer=layer, quiet=True,
+                     **args)
     if getDict:
     if getDict:
         result = dict()
         result = dict()
     else:
     else:
@@ -121,85 +126,67 @@ def vector_columns(map, layer = None, getDict = True, **args):
     for line in s.splitlines():
     for line in s.splitlines():
         ctype, cname = line.split('|')
         ctype, cname = line.split('|')
         if getDict:
         if getDict:
-            result[cname] = { 'type' : ctype,
-                              'index' : i }
+            result[cname] = {'type': ctype, 'index': i}
         else:
         else:
             result.append(cname)
             result.append(cname)
-        i+=1
-    
+        i += 1
+
     return result
     return result
 
 
-# add vector history
 
 
 def vector_history(map):
 def vector_history(map):
-    """!Set the command history for a vector map to the command used to
+    """Set the command history for a vector map to the command used to
     invoke the script (interface to `v.support').
     invoke the script (interface to `v.support').
 
 
-    @param map mapname
+    :param str map: mapname
 
 
-    @return v.support output
+    :return: v.support output
     """
     """
-    run_command('v.support', map = map, cmdhist = os.environ['CMDLINE'])
+    run_command('v.support', map=map, cmdhist=os.environ['CMDLINE'])
 
 
-# run "v.info -t" and parse output
 
 
 def vector_info_topo(map):
 def vector_info_topo(map):
-    """!Return information about a vector map (interface to `v.info
+    """Return information about a vector map (interface to `v.info
     -t'). Example:
     -t'). Example:
 
 
-    \code
-    >>> grass.vector_info_topo('lakes')
-    {'kernels': 0, 'lines': 0, 'centroids': 15279,
-    'boundaries': 27764, 'points': 0, 'faces': 0,
-    'primitives': 43043, 'islands': 7470, 'nodes': 35234, 'map3d': False, 'areas': 15279}
-    \endcode
-    
-    @param map map name
+    >>> vector_info_topo('geology') # doctest: +NORMALIZE_WHITESPACE
+    {'lines': 0, 'centroids': 1832, 'boundaries': 3649, 'points': 0,
+    'primitives': 5481, 'islands': 907, 'nodes': 2724, 'map3d': False,
+    'areas': 1832}
+
+    :param str map: map name
 
 
-    @return parsed output
+    :return: parsed output
     """
     """
-    s = read_command('v.info', flags = 't', map = map)
-    ret = parse_key_val(s, val_type = int)
+    s = read_command('v.info', flags='t', map=map)
+    ret = parse_key_val(s, val_type=int)
     if 'map3d' in ret:
     if 'map3d' in ret:
         ret['map3d'] = bool(ret['map3d'])
         ret['map3d'] = bool(ret['map3d'])
-    
-    return ret
 
 
+    return ret
 
 
-# run "v.info -get ..." and parse output
 
 
 def vector_info(map):
 def vector_info(map):
-    """!Return information about a vector map (interface to
+    """Return information about a vector map (interface to
     `v.info'). Example:
     `v.info'). Example:
 
 
-    \code
-    >>> grass.vector_info('random_points')
-    {'comment': '', 'projection': 'x,y', 'creator': 'soeren', 'holes': 0, 
-     'primitives': 20, 'kernels': 0, 'scale': '1:1', 'title': '', 
-     'west': 0.046125489999999998, 'top': 2376.133159, 'boundaries': 0, 
-     'location': 'XYLocation', 'nodes': 0, 'east': 0.97305646000000001, 
-     'source_date': 'Mon Aug 29 10:55:57 2011', 'north': 0.9589993, 
-     'format': 'native', 'faces': 0, 'centroids': 0, 
-     'digitization_threshold': '0.000000', 'islands': 0, 'level': 2, 
-     'mapset': 'test', 'areas': 0, 'name': 'random_points', 
-     'database': '/home/soeren/grassdata', 'bottom': 22.186596999999999, 
-     'lines': 0, 'points': 20, 'map3d': True, 'volumes': 0, 'num_dblinks': 0, 
-     'organization': '', 'south': 0.066047099999999997}
-    
-    \endcode
-    @param map map name
-    
-    @return parsed vector info
+    >>> vector_info('geology') # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
+    {'comment': '', 'projection': 'Lambert Conformal Conic' ... 'south': 10875.8272320917}
+
+    :param str map: map name
+
+    :return: parsed vector info
     """
     """
 
 
-    s = read_command('v.info', flags = 'get', map = map)
-    
+    s = read_command('v.info', flags='get', map=map)
+
     kv = parse_key_val(s)
     kv = parse_key_val(s)
     for k in ['north', 'south', 'east', 'west', 'top', 'bottom']:
     for k in ['north', 'south', 'east', 'west', 'top', 'bottom']:
         kv[k] = float(kv[k])
         kv[k] = float(kv[k])
     for k in ['level', 'num_dblinks']:
     for k in ['level', 'num_dblinks']:
         kv[k] = int(kv[k])
         kv[k] = int(kv[k])
-    for k in ['nodes', 'points', 'lines', 'boundaries', 'centroids', 'areas', 'islands', 'primitives']:
+    for k in ['nodes', 'points', 'lines', 'boundaries', 'centroids', 'areas',
+              'islands', 'primitives']:
         kv[k] = int(kv[k])
         kv[k] = int(kv[k])
     if 'map3d' in kv:
     if 'map3d' in kv:
         kv['map3d'] = bool(int(kv['map3d']))
         kv['map3d'] = bool(int(kv['map3d']))
@@ -210,36 +197,32 @@ def vector_info(map):
     return kv
     return kv
 
 
 
 
-# interface for v.db.select
-
-def vector_db_select(map, layer = 1, **kwargs):
-    """!Get attribute data of selected vector map layer.
+def vector_db_select(map, layer=1, **kwargs):
+    """Get attribute data of selected vector map layer.
 
 
     Function returns list of columns and dictionary of values ordered by
     Function returns list of columns and dictionary of values ordered by
     key column value. Example:
     key column value. Example:
 
 
-    \code
-    >>> print grass.vector_db_select('lakes')['columns']
-    ['cat', 'AREA', 'PERIMETER', 'FULL_HYDRO', 'FULL_HYDR2', 'FTYPE', 'FCODE', 'NAME']
-    >>> print grass.vector_db_select('lakes')['values'][3]
-    ['3', '19512.86146', '708.44683', '4', '55652', 'LAKE/POND', '39000', '']
-    >>> print grass.vector_db_select('lakes', columns = 'FTYPE')['values'][3]
-    ['LAKE/POND']
-    \endcode
+    >>> print vector_db_select('geology')['columns']
+    ['cat', 'onemap_pro', 'PERIMETER', 'GEOL250_', 'GEOL250_ID', 'GEO_NAME', 'SHAPE_area', 'SHAPE_len']
+    >>> print vector_db_select('geology')['values'][3]
+    ['3', '579286.875', '3335.55835', '4', '3', 'Zml', '579286.829631', '3335.557182']
+    >>> print vector_db_select('geology', columns = 'GEO_NAME')['values'][3]
+    ['Zml']
 
 
-    @param map map name
-    @param layer layer number
-    @param kwargs v.db.select options
+    :param str map: map name
+    :param str layer: layer number
+    :param kwargs: v.db.select options
 
 
-    @return dictionary ('columns' and 'values')
+    :return: dictionary ('columns' and 'values')
     """
     """
     try:
     try:
-        key = vector_db(map = map)[layer]['key']
+        key = vector_db(map=map)[layer]['key']
     except KeyError:
     except KeyError:
         error(_('Missing layer %(layer)d in vector map <%(map)s>') % \
         error(_('Missing layer %(layer)d in vector map <%(map)s>') % \
-                  { 'layer' : layer, 'map' : map })
-        return { 'columns' : [], 'values' : {} }
-        
+              {'layer': layer, 'map': map})
+        return {'columns': [], 'values': {}}
+
     include_key = True
     include_key = True
     if 'columns' in kwargs:
     if 'columns' in kwargs:
         if key not in kwargs['columns'].split(','):
         if key not in kwargs['columns'].split(','):
@@ -247,16 +230,13 @@ def vector_db_select(map, layer = 1, **kwargs):
             include_key = False
             include_key = False
             debug("Adding key column to the output")
             debug("Adding key column to the output")
             kwargs['columns'] += ',' + key
             kwargs['columns'] += ',' + key
-    
-    ret = read_command('v.db.select',
-                       map = map,
-                       layer = layer,
-                       **kwargs)
-    
+
+    ret = read_command('v.db.select', map=map, layer=layer, **kwargs)
+
     if not ret:
     if not ret:
         error(_('vector_db_select() failed'))
         error(_('vector_db_select() failed'))
-        return { 'columns' : [], 'values' : {} }
-    
+        return {'columns': [], 'values': {}}
+
     columns = []
     columns = []
     values = {}
     values = {}
     for line in ret.splitlines():
     for line in ret.splitlines():
@@ -265,9 +245,9 @@ def vector_db_select(map, layer = 1, **kwargs):
             key_index = columns.index(key)
             key_index = columns.index(key)
             # discard key column
             # discard key column
             if not include_key:
             if not include_key:
-                 columns = columns[:-1]
+                columns = columns[:-1]
             continue
             continue
-        
+
         value = line.split('|')
         value = line.split('|')
         key_value = int(value[key_index])
         key_value = int(value[key_index])
         if not include_key:
         if not include_key:
@@ -275,60 +255,68 @@ def vector_db_select(map, layer = 1, **kwargs):
             values[key_value] = value[:-1]
             values[key_value] = value[:-1]
         else:
         else:
             values[key_value] = value
             values[key_value] = value
-    
-    return { 'columns' : columns,
-             'values' : values }
-
-# interface to v.what
-def vector_what(map, coord, distance = 0.0, ttype = None):
-    """!Query vector map at given locations
-    
+
+    return {'columns': columns, 'values': values}
+
+
+def vector_what(map, coord, distance=0.0, ttype=None):
+    """Query vector map at given locations
+
     To query one vector map at one location
     To query one vector map at one location
-    @code
-    print grass.vector_what(map = 'archsites', coord = (595743, 4925281), distance = 250)
 
 
-    [{'Category': 8, 'Map': 'archsites', 'Layer': 1, 'Key_column': 'cat',
-      'Database': '/home/martin/grassdata/spearfish60/PERMANENT/dbf/',
-      'Mapset': 'PERMANENT', 'Driver': 'dbf',
-      'Attributes': {'str1': 'No_Name', 'cat': '8'},
-      'Table': 'archsites', 'Type': 'Point', 'Id': 8}]
-    @endcode
+    ::
 
 
-    To query one vector map with multiple layers (no additional parameters required)
-    @code
-    for q in grass.vector_what(map = 'some_map', coord = (596532.357143,4920486.21429), distance = 100.0):
-        print q['Map'], q['Layer'], q['Attributes']
+        print grass.vector_what(map='archsites', coord=(595743, 4925281),
+                                distance=250)
 
 
-    new_bug_sites 1 {'str1': 'Beetle_site', 'GRASSRGB': '', 'cat': '80'}
-    new_bug_sites 2 {'cat': '80'}
-    @endcode
+        [{'Category': 8, 'Map': 'archsites', 'Layer': 1, 'Key_column': 'cat',
+          'Database': '/home/martin/grassdata/spearfish60/PERMANENT/dbf/',
+          'Mapset': 'PERMANENT', 'Driver': 'dbf',
+          'Attributes': {'str1': 'No_Name', 'cat': '8'},
+          'Table': 'archsites', 'Type': 'Point', 'Id': 8}]
+
+    To query one vector map with multiple layers (no additional parameters
+    required)
+
+    ::
+
+        for q in grass.vector_what(map='some_map', distance=100.0,
+                                   coord=(596532.357143,4920486.21429)):
+            print q['Map'], q['Layer'], q['Attributes']
+
+        new_bug_sites 1 {'str1': 'Beetle_site', 'GRASSRGB': '', 'cat': '80'}
+        new_bug_sites 2 {'cat': '80'}
 
 
     To query more vector maps at one location
     To query more vector maps at one location
-    @code
-    for q in grass.vector_what(map = ('archsites', 'roads'), coord = (595743, 4925281),
-                               distance = 250):
-        print q['Map'], q['Attributes']
-                            
-    archsites {'str1': 'No_Name', 'cat': '8'}
-    roads {'label': 'interstate', 'cat': '1'}
-    @endcode
+
+    ::
+
+        for q in grass.vector_what(map=('archsites', 'roads'),
+                                   coord=(595743, 4925281), distance=250):
+            print q['Map'], q['Attributes']
+
+        archsites {'str1': 'No_Name', 'cat': '8'}
+        roads {'label': 'interstate', 'cat': '1'}
 
 
     To query one vector map at more locations
     To query one vector map at more locations
-    @code
-    for q in grass.vector_what(map = 'archsites', coord = [(595743, 4925281), (597950, 4918898)],
-                               distance = 250):
-        print q['Map'], q['Attributes']
 
 
-    archsites {'str1': 'No_Name', 'cat': '8'}
-    archsites {'str1': 'Bob_Miller', 'cat': '22'}
-    @endcode
+    ::
+
+        for q in grass.vector_what(map='archsites', distance=250,
+                                   coord=[(595743, 4925281), (597950, 4918898)]):
+            print q['Map'], q['Attributes']
+
+        archsites {'str1': 'No_Name', 'cat': '8'}
+        archsites {'str1': 'Bob_Miller', 'cat': '22'}
 
 
-    @param map vector map(s) to query given as string or list/tuple
-    @param coord coordinates of query given as tuple (easting, northing) or list of tuples
-    @param distance query threshold distance (in map units)
-    @param ttype list of topology types (default of v.what are point, line, area, face)
+    :param map: vector map(s) to query given as string or list/tuple
+    :param coord: coordinates of query given as tuple (easting, northing) or
+                  list of tuples
+    :param distance: query threshold distance (in map units)
+    :param ttype: list of topology types (default of v.what are point, line,
+                  area, face)
 
 
-    @return parsed list
+    :return: parsed list
     """
     """
     if "LC_ALL" in os.environ:
     if "LC_ALL" in os.environ:
         locale = os.environ["LC_ALL"]
         locale = os.environ["LC_ALL"]
@@ -338,16 +326,16 @@ def vector_what(map, coord, distance = 0.0, ttype = None):
         map_list = [map]
         map_list = [map]
     else:
     else:
         map_list = map
         map_list = map
-    
+
     layer_list = ['-1'] * len(map_list)
     layer_list = ['-1'] * len(map_list)
-    
+
     coord_list = list()
     coord_list = list()
     if type(coord) is types.TupleType:
     if type(coord) is types.TupleType:
         coord_list.append('%f,%f' % (coord[0], coord[1]))
         coord_list.append('%f,%f' % (coord[0], coord[1]))
     else:
     else:
         for e, n in coord:
         for e, n in coord:
             coord_list.append('%f,%f' % (e, n))
             coord_list.append('%f,%f' % (e, n))
-    
+
     cmdParams = dict(quiet      = True,
     cmdParams = dict(quiet      = True,
                      flags      = 'ag',
                      flags      = 'ag',
                      map        = ','.join(map_list),
                      map        = ','.join(map_list),
@@ -359,14 +347,14 @@ def vector_what(map, coord, distance = 0.0, ttype = None):
 
 
     ret = read_command('v.what',
     ret = read_command('v.what',
                        **cmdParams)
                        **cmdParams)
-    
+
     if "LC_ALL" in os.environ:
     if "LC_ALL" in os.environ:
         os.environ["LC_ALL"] = locale
         os.environ["LC_ALL"] = locale
-        
+
     data = list()
     data = list()
     if not ret:
     if not ret:
         return data
         return data
-    
+
     # parse `v.what -g` output is a nightmare
     # parse `v.what -g` output is a nightmare
     # TODO: change `v.what -g` format or add parsable format (e.g. XML)
     # TODO: change `v.what -g` format or add parsable format (e.g. XML)
     dict_attrb = None
     dict_attrb = None
@@ -380,7 +368,7 @@ def vector_what(map, coord, distance = 0.0, ttype = None):
             continue
             continue
         if key in ('East', 'North'):
         if key in ('East', 'North'):
             continue
             continue
-        
+
         if key == 'Map':
         if key == 'Map':
             # attach the last one from the previous map
             # attach the last one from the previous map
             if dict_map is not None:
             if dict_map is not None:
@@ -388,7 +376,7 @@ def vector_what(map, coord, distance = 0.0, ttype = None):
                 if dict_layer is not None:
                 if dict_layer is not None:
                     dict_main.update(dict_layer)
                     dict_main.update(dict_layer)
                 data.append(dict_main)
                 data.append(dict_main)
-            dict_map  = { key : value }
+            dict_map = {key : value}
             dict_layer = None
             dict_layer = None
             dict_attrb = None
             dict_attrb = None
         elif key == 'Layer':
         elif key == 'Layer':
@@ -398,7 +386,7 @@ def vector_what(map, coord, distance = 0.0, ttype = None):
                     dict_main = copy.copy(dict_map)
                     dict_main = copy.copy(dict_map)
                     dict_main.update(dict_layer)
                     dict_main.update(dict_layer)
                     data.append(dict_main)
                     data.append(dict_main)
-                dict_layer = { key: int(value) }
+                dict_layer = {key: int(value)}
                 dict_attrb = None
                 dict_attrb = None
             else:
             else:
                 dict_attrb[key] = value
                 dict_attrb[key] = value
@@ -417,12 +405,12 @@ def vector_what(map, coord, distance = 0.0, ttype = None):
             dict_map[key] = value
             dict_map[key] = value
             # TODO: there are some keys which has non-string values
             # TODO: there are some keys which has non-string values
             # examples: Sq_Meters, Hectares, Acres, Sq_Miles
             # examples: Sq_Meters, Hectares, Acres, Sq_Miles
-    
+
     # attach the last one
     # attach the last one
     if dict_map is not None:
     if dict_map is not None:
         dict_main = copy.copy(dict_map)
         dict_main = copy.copy(dict_map)
         if dict_layer:
         if dict_layer:
             dict_main.update(dict_layer)
             dict_main.update(dict_layer)
         data.append(dict_main)
         data.append(dict_main)
-    
+
     return data
     return data