Opened 6 years ago
Last modified 5 years ago
#3845 new defect
pygrass + mapset resolution
Reported by: | pmav99 | Owned by: | |
---|---|---|---|
Priority: | normal | Milestone: | 7.8.3 |
Component: | PyGRASS | Version: | svn-trunk |
Keywords: | Cc: | ||
CPU: | Unspecified | Platform: | Unspecified |
Description
I am not sure if this is a bug or just lack of understanding from my part.
The following function:
- Creates a new (temporary) mapset (e.g. named A)
- Makes A the current mapset
- Creates a map inside A
- Confirms that the map exists
- Tries to open the map using RasterRow
- On exit, restores PERMANENT as the current mapset and deletes A
You may call this function as many times as you want and it will work as long as you use the same mapset name. As soon as you change the mapset name though it will fail with the rather confusing exception:
grass.exceptions.OpenError: The map does not exist, I can't open in 'r' mode
Note: The function has confirmed that the map exists before the exception
This is the code:
import grass.script as gscript import grass.pygrass as pygrass import grass.pygrass.raster import grass.pygrass.gis # import grass.lib.gis as libgis # libgis.G_gisinit("asdf") gscript.run_command("g.region", n=10, s=0, e=10, w=0, res=1) def test(mapset_name, map_name): # create a new mapset and make it the current one pygrass.gis.make_mapset(mapset_name) pygrass.gis.set_current_mapset(mapset_name) # Create a map inside the new mapset and try to open it using pygrass methods try: mapset = pygrass.gis.Mapset(mapset_name) assert mapset.glist("raster") == [] gscript.run_command("r.mapcalc", expression=f"{map_name}=1", quiet=True) assert mapset.glist("raster") == [map_name] # OK we've proved that the map exists and that the mapset object can see it # Let's now try to open the map though. As we will see, opening the map will fail r = pygrass.raster.RasterRow(map_name) r.open() # you will get an exception here assert r.is_open() finally: # cleanup pygrass.gis.set_current_mapset("PERMANENT") mapset.delete() # (Re-)create and delete the "aaa" mapset as many times as you want. # Everything will be working just fine. test("aaa", "m1") test("aaa", "m1") test("aaa", "m1") test("aaa", "m2") test("aaa", "m2") test("aaa", "m1") # But as soon as you try to create a mapset with a different name # pygrass will no longer be able to resolve map names. test("bbb", "m1") # this will fail
As soon as you figure out what the problem is, it is not difficult to work around it. In this case You just need to specify the mapset name when you create the RasterRow
instance. I.e. if you apply the following patch, the function will no longer raise an Exception:
- r = pygrass.raster.RasterRow(map_name) + r = pygrass.raster.RasterRow(map_name, mapset_name)
I guess that the same is true for pygrass.utils.get_mapset_raster()
and possible other similar function and classes.
If I have understood this correctly, the problem seems to be in the G_find_raster*()
functions which for some reason seem to "get stuck" to the initial mapset name.
- Is this documented and I somehow completely missed that?
- When creating a new mapset, do we need to call some function from e.g.
grass.lib.gis
in order to get name resolution working? - If not, should we make
get_mapset_raster
and friends explicitly pass the current mapset toG_find_raster*()
if a mapset has not been specified?