Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#3637 closed defect (fixed)

Use the system temporary directory for all GUI rendering files

Reported by: wenzeslaus Owned by: grass-dev@…
Priority: minor Milestone: 8.0.0
Component: wxGUI Version: svn-trunk
Keywords: rendering PPM g.pnmcomp tempfile NamedTemporaryFile Cc:
CPU: Unspecified Platform: Unspecified


wxGUI uses standard Python tempfile.NamedTemporaryFile for rendering a single layer (GRASS_RENDER_FILE):

            mapfile = tempfile.NamedTemporaryFile(
                suffix=tempfile_sfx, delete=False)
            # we don't want it open, we just need the name
            self.mapfile =
            os.remove(self.mapfile)  # remove empty file

        self.maskfile = self.mapfile.rsplit(".", 1)[0] + ".pgm"

However, it uses GRASS GIS grass.script.tempfile for vector legend files and g.pnmcomp output:

        if self.type in ('vector', 'thememap'):
            self._legrow = grass.tempfile(create=True)
        # generated file for g.pnmcomp output for rendering the map
        self.legfile = grass.tempfile(create=False) + '.leg'
        self.tmpdir = os.path.dirname(self.legfile)  # looks unused (?)
        self.mapfile = grass.tempfile(create=False) + '.ppm'


The render command (from WX_DEBUG, edited):

GUI D1/5: RenderLayerMgr.Render(d.rast map=boundary_county_500m@PERMANENT):
          force=1 img=/tmp/grass7-vpetras-23526/tmpNqGsdb.ppm

GUI D1/5: gcmd.RunCommand(): g.pnmcomp --o opacity=1.0 width=823
          height=502 bgcolor=255:255:255:255

tempfile.NamedTemporaryFile refers to tempfile.TemporaryFile which refers to tempfile.mkstemp which says:

The default directory is chosen from a platform-dependent list, but the user of the application can control the directory location by setting the TMPDIR, TEMP or TMP environment variables.

The order is not explicitly guaranteed in the documentation, but the behavior on Linux with Python 2.7 is that TMPDIR is picked over TMP which is the behavior we want. If that would change, but we wanted to preserve the same behavior, there is a dir parameter which specified the directory.

My intention is to use tempfile.NamedTemporaryFile for everything.

Change History (2)

comment:1 by wenzeslaus, 5 years ago

Resolution: fixed
Status: assignedclosed

In 73334:

wxGUI/core: replace grass.script.tempfile by tempfile.NamedTemporaryFile (fixes #3637)

Switches from mapset temporary directory to system temporary
directory which was previously set up for the session for
all GUI rendering files.

This also refactors and unifies handling of the temporary files related
to rendering, although on error and when removing/deleting the layers
removing of the files happens in the same way as before.

All files are now using NamedTemporaryFile instead of some using
g.tempfile and some NamedTemporaryFile. This means that when mapset
is switched, files are present in the (correct) session directory,
not incorrect mapset directory and then not deleted later.
(Deleting these files could cause rendering errors, while not deleting
them would lead to accumulating of files in mapset temporary directory).

See also:

  • r28605 which adds glob for one delete when core.utils.GetTempfile(), i.e., g.tempfile was still used (the glob part is still there)
  • r56444 which adds mkstemp() for some of the files
  • r60947 attempt to fix cleaning of deleting temporary files (#560) which changes mkstemp to NamedTemporaryFile (still used now)
  • r69085 which checked legend row file (legrow) name of last character being digit (isdigit()) which was true for files from g.tempfile but does not seem to have a reason (removed now)
  • #3635 which investigates a suspicious cleanups of mapset temporary directory which at this point seemed to be cleaning rendering files from GUI (r37863, r21048)

comment:2 by wenzeslaus, 5 years ago

I tested the rendering with rasters, vectors and vector legend and it works including checking and unchecking. A debug output (WX_DEBUG=5, edited) after pressing Render map button is below showing only files in the session temporary directory which is in the system temporary directory (here /tmp).

GUI D3/5: Layer.Render(): type=overlay, name=vectleg,
GUI D1/5: RenderLayerMgr.Render(d.legend.vect at=20.0,80.0):
          force=0 img=/tmp/grass7-$USER-11834/tmp0v6vpY.png
GUI D3/5: Layer.Render(): type=raster, name=aspect@PERMANENT,
GUI D1/5: RenderLayerMgr.Render(d.rast map=aspect@PERMANENT):
          force=0 img=/tmp/grass7-$USER-11834/tmpmpjTAK.ppm
GUI D3/5: Layer.Render(): type=vector, name=bridges@PERMANENT,
GUI D1/5: RenderLayerMgr.Render(d.vect map=bridges@PERMANENT width=1):
          force=0 img=/tmp/grass7-$USER-11834/tmpY1Ns6j.ppm
GUI D1/5: gcmd.RunCommand(): g.pnmcomp --o opacity=1.0,1.0 width=825
          height=572 bgcolor=255:255:255
Note: See TracTickets for help on using tickets.