Skip to content

Commit

Permalink
pythonlib: add env variables to all relevant functions (#677)
Browse files Browse the repository at this point in the history
Passing environment is needed for some functions for fixes of r.import.
The rest of the functions get it for consistency.

The following functions have newly added env parameter:
* core.py: tempfile, tempdir, locn_is_latlong, find_file, list_strings, list_pairs, list_grouped, mapsets
* db.py: db_describe, db_table_exist, db_connection, db_select, db_table_in_vector
* raster.py: raster_history, raster_info
* raster3d.py: raster3d_info
* vector.py: vector_db, vector_layer_db, vector_columns, vector_history, vector_info_topo, vector_info, vector_db_select, vector_what
* array.py
  • Loading branch information
petrasovaa committed Aug 26, 2020
1 parent db1f158 commit dbeb5f3
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 78 deletions.
32 changes: 20 additions & 12 deletions lib/python/script/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,27 +124,28 @@
###############################################################################

class _tempfile(object):
def __init__(self):
self.filename = gcore.tempfile()
def __init__(self, env=None):
self.filename = gcore.tempfile(env=env)

def __del__(self):
try_remove(self.filename)

###############################################################################

class array(numpy.memmap):
def __new__(cls, mapname=None, null=None, dtype=numpy.double):
def __new__(cls, mapname=None, null=None, dtype=numpy.double, env=None):
"""Define new numpy array
:param cls:
:param dtype: data type (default: numpy.double)
:param env: environment
"""
reg = gcore.region()
reg = gcore.region(env=env)
r = reg['rows']
c = reg['cols']
shape = (r, c)

tempfile = _tempfile()
tempfile = _tempfile(env)
if mapname:
kind = numpy.dtype(dtype).kind
size = numpy.dtype(dtype).itemsize
Expand All @@ -167,7 +168,8 @@ def __new__(cls, mapname=None, null=None, dtype=numpy.double):
bytes=size,
null=null,
quiet=True,
overwrite=True)
overwrite=True,
env=env)

self = numpy.memmap.__new__(
cls,
Expand All @@ -178,6 +180,7 @@ def __new__(cls, mapname=None, null=None, dtype=numpy.double):

self.tempfile = tempfile
self.filename = tempfile.filename
self._env = env
return self

def read(self, mapname, null=None):
Expand Down Expand Up @@ -253,7 +256,7 @@ def write(self, mapname, title=None, null=None, overwrite=None, quiet=None):
else:
raise ValueError(_('Invalid kind <%s>') % kind)

reg = gcore.region()
reg = gcore.region(env=self._env)

try:
gcore.run_command(
Expand All @@ -271,7 +274,8 @@ def write(self, mapname, title=None, null=None, overwrite=None, quiet=None):
east=reg['e'],
west=reg['w'],
rows=reg['rows'],
cols=reg['cols'])
cols=reg['cols'],
env=self._env)
except CalledModuleError:
return 1
else:
Expand All @@ -281,11 +285,12 @@ def write(self, mapname, title=None, null=None, overwrite=None, quiet=None):


class array3d(numpy.memmap):
def __new__(cls, mapname=None, null=None, dtype=numpy.double):
def __new__(cls, mapname=None, null=None, dtype=numpy.double, env=None):
"""Define new 3d numpy array
:param cls:
:param dtype: data type (default: numpy.double)
:param env: environment
"""
reg = gcore.region(True)
r = reg['rows3']
Expand Down Expand Up @@ -316,7 +321,8 @@ def __new__(cls, mapname=None, null=None, dtype=numpy.double):
bytes=size,
null=null,
quiet=True,
overwrite=True)
overwrite=True,
env=env)

self = numpy.memmap.__new__(
cls,
Expand All @@ -327,6 +333,7 @@ def __new__(cls, mapname=None, null=None, dtype=numpy.double):

self.tempfile = tempfile
self.filename = tempfile.filename
self._env = env

return self

Expand Down Expand Up @@ -398,7 +405,7 @@ def write(self, mapname, null=None, overwrite=None, quiet=None):
else:
raise ValueError(_('Invalid kind <%s>') % kind)

reg = gcore.region(True)
reg = gcore.region(True, env=self._env)

try:
gcore.run_command(
Expand All @@ -418,7 +425,8 @@ def write(self, mapname, null=None, overwrite=None, quiet=None):
west=reg['w'],
depths=reg['depths'],
rows=reg['rows3'],
cols=reg['cols3'])
cols=reg['cols3'],
env=self._env)

except CalledModuleError:
return 1
Expand Down
57 changes: 40 additions & 17 deletions lib/python/script/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -904,23 +904,24 @@ def parser():
# interface to g.tempfile


def tempfile(create=True):
def tempfile(create=True, env=None):
"""Returns the name of a temporary file, created with g.tempfile.
:param bool create: True to create a file
:param env: environment
:return: path to a tmp file
"""
flags = ''
if not create:
flags += 'd'

return read_command("g.tempfile", flags=flags, pid=os.getpid()).strip()
return read_command("g.tempfile", flags=flags, pid=os.getpid(), env=env).strip()


def tempdir():
def tempdir(env=None):
"""Returns the name of a temporary dir, created with g.tempfile."""
tmp = tempfile(create=False)
tmp = tempfile(create=False, env=env)
os.mkdir(tmp)

return tmp
Expand Down Expand Up @@ -1144,13 +1145,13 @@ def gisenv(env=None):
# interface to g.region


def locn_is_latlong():
def locn_is_latlong(env=None):
"""Tests if location is lat/long. Value is obtained
by checking the "g.region -pu" projection code.
:return: True for a lat/long region, False otherwise
"""
s = read_command("g.region", flags='pu')
s = read_command("g.region", flags='pu', env=env)
kv = parse_key_val(s, ':')
if kv['projection'].split(' ')[0] == '3':
return True
Expand Down Expand Up @@ -1295,7 +1296,7 @@ def del_temp_region():
# interface to g.findfile


def find_file(name, element='cell', mapset=None):
def find_file(name, element='cell', mapset=None, env=None):
"""Returns the output from running g.findfile as a
dictionary. Example:
Expand All @@ -1309,6 +1310,7 @@ def find_file(name, element='cell', mapset=None):
:param str name: file name
:param str element: element type (default 'cell')
:param str mapset: mapset name (default all mapsets in search path)
:param env: environment
:return: parsed output of g.findfile
"""
Expand All @@ -1319,14 +1321,15 @@ def find_file(name, element='cell', mapset=None):
# se we ignore return code and just focus on stdout
process = start_command('g.findfile', flags='n',
element=element, file=name, mapset=mapset,
stdout=PIPE)
stdout=PIPE, env=env)
stdout = process.communicate()[0]
return parse_key_val(stdout)

# interface to g.list


def list_strings(type, pattern=None, mapset=None, exclude=None, flag=''):
def list_strings(type, pattern=None, mapset=None, exclude=None,
flag='', env=None):
"""List of elements as strings.
Returns the output from running g.list, as a list of qualified
Expand All @@ -1338,6 +1341,7 @@ def list_strings(type, pattern=None, mapset=None, exclude=None, flag=''):
:param str exclude: pattern string to exclude maps from the research
:param str flag: pattern type: 'r' (basic regexp), 'e' (extended regexp),
or '' (glob pattern)
:param env: environment
:return: list of elements
"""
Expand All @@ -1351,13 +1355,15 @@ def list_strings(type, pattern=None, mapset=None, exclude=None, flag=''):
type=type,
pattern=pattern,
exclude=exclude,
mapset=mapset).splitlines():
mapset=mapset,
env=env).splitlines():
result.append(line.strip())

return result


def list_pairs(type, pattern=None, mapset=None, exclude=None, flag=''):
def list_pairs(type, pattern=None, mapset=None, exclude=None,
flag='', env=None):
"""List of elements as pairs
Returns the output from running g.list, as a list of
Expand All @@ -1369,16 +1375,17 @@ def list_pairs(type, pattern=None, mapset=None, exclude=None, flag=''):
:param str exclude: pattern string to exclude maps from the research
:param str flag: pattern type: 'r' (basic regexp), 'e' (extended regexp),
or '' (glob pattern)
:param env: environment
:return: list of elements
"""
return [tuple(map.split('@', 1)) for map in list_strings(type, pattern,
mapset, exclude,
flag)]
flag, env)]


def list_grouped(type, pattern=None, check_search_path=True, exclude=None,
flag=''):
flag='', env=None):
"""List of elements grouped by mapsets.
Returns the output from running g.list, as a dictionary where the
Expand All @@ -1395,6 +1402,7 @@ def list_grouped(type, pattern=None, check_search_path=True, exclude=None,
:param str exclude: pattern string to exclude maps from the research
:param str flag: pattern type: 'r' (basic regexp), 'e' (extended regexp),
or '' (glob pattern)
:param env: environment
:return: directory of mapsets/elements
"""
Expand All @@ -1411,15 +1419,16 @@ def list_grouped(type, pattern=None, check_search_path=True, exclude=None,
types[i] = 'raster'
result = {}
if check_search_path:
for mapset in mapsets(search_path=True):
for mapset in mapsets(search_path=True, env=env):
if store_types:
result[mapset] = {}
else:
result[mapset] = []

mapset = None
for line in read_command("g.list", quiet=True, flags="m" + flag,
type=types, pattern=pattern, exclude=exclude).splitlines():
type=types, pattern=pattern,
exclude=exclude, env=env).splitlines():
try:
name, mapset = line.split('@')
except ValueError:
Expand Down Expand Up @@ -1546,7 +1555,7 @@ def find_program(pgm, *args):
# interface to g.mapsets


def mapsets(search_path=False):
def mapsets(search_path=False, env=None):
"""List available mapsets
:param bool search_path: True to list mapsets only in search path
Expand All @@ -1560,7 +1569,8 @@ def mapsets(search_path=False):
mapsets = read_command('g.mapsets',
flags=flags,
sep='newline',
quiet=True)
quiet=True,
env=env)
if not mapsets:
fatal(_("Unable to list mapsets"))

Expand Down Expand Up @@ -1767,6 +1777,17 @@ def legal_name(s):
return True


def sanitize_mapset_environment(env):
"""Remove environmental variables relevant only
for a specific mapset. This should be called
when a copy of environment is used with a different mapset."""
if "WIND_OVERRIDE" in env:
del env["WIND_OVERRIDE"]
if "GRASS_REGION" in env:
del env["GRASS_REGION"]
return env


def create_environment(gisdbase, location, mapset):
"""Creates environment to be passed in run_command for example.
Returns tuple with temporary file path and the environment. The user
Expand All @@ -1778,6 +1799,8 @@ def create_environment(gisdbase, location, mapset):
f.write('GUI: text\n')
env = os.environ.copy()
env['GISRC'] = f.name
# remove mapset-specific env vars
env = sanitize_mapset_environment(env)
return f.name, env


Expand Down

0 comments on commit dbeb5f3

Please sign in to comment.