How to Delete a Directory Created with Tempfile.Mkdtemp

How to remove tempfile in python

Removing a temporary directory is the same as removing any other directory: just call os.rmdir if you're sure you've already emptied it out (and consider it an error if it's not empty), or shutil.rmtree if not.

If you're using 3.2 or later, it's much simpler to just create the temporary directory with TemporaryDirectory instead of mkdtemp. That takes care of all the fiddly edge cases, in a nicely cross-platform way, so you don't have to worry about them. (If you were creating a temporary file, as your question title suggests, it's even more worth using the higher-level APIs like TemporaryFile or NamedTemporaryFile.) For example:

with tempfile.TemporaryDirectory() as tempdir:
do_stuff_with(tempdir)
# deletes everything automatically at end of with

Or, if you can't put it inside a with statement:

def make_tempdir(self):
self.tempdir = tempfile.TemporaryDirectory()
def remove_tempdir(self):
self.tempdir.cleanup()

In fact, even for 2.7 or 3.1, you might want to consider borrowing the source to 3.5's TemporaryDirectory class and using that yourself (or looking for a backport on PyPI, if one exists).

Right way to clean up a temporary folder in Python class

Caveat: you can never guarantee that the temp folder will be deleted, because the user could always hard kill your process and then it can't run anything else.

That said, do

temp_dir = tempfile.mkdtemp()
try:
<some code>
finally:
shutil.rmtree(temp_dir)

Since this is a very common operation, Python has a special way to encapsulate "do something, execute code, clean up": a context manager. You can write your own as follows:

@contextlib.contextmanager
def make_temp_directory():
temp_dir = tempfile.mkdtemp()
try:
yield temp_dir
finally:
shutil.rmtree(temp_dir)

and use it as

with make_temp_directory() as temp_dir:
<some code>

(Note that this uses the @contextlib.contextmanager shortcut to make a context manager. If you want to implement one the original way, you need to make a custom class with __enter__ and __exit__ methods; the __enter__ would create and return the temp directory and the __exit__ delete it.

In Python, how do I make a temp file that persists until the next run?

Creating the folder with a 4-digit random number is insecure, and you also need to worry about collisions with other instances of your program.

A much better way is to create the folder using tempfile.mkdtemp, which does exactly what you want (i.e. the folder is not deleted when your script exits). You would then pass the folder name to the second Popen'ed script as an argument, and it would be responsible for deleting it.

python tempfile.mkdtemp with everyone permission

You want to change permissions with os.chmod:

>>> import tempfile
>>> t = tempfile.mkdtemp()
>>> import os
>>> os.chmod(t, 0o444)
>>> t
'/var/folders/pg/j27n0zds1bq9pzgl9g6bm9yw0000gn/T/tmpgbuhokn7'

In bash:

dr--r--r--    2 me  staff    64 21 Nov 17:48 tmpgbuhokn7

If you want other permissions, read the docs

How do you manage a temporary directory such that it is guaranteed to be deleted on program close?

I wouldn't use a __del__ method, the semantics are unreliable, and could interfere with garbage collection. Use a context manager: define a __enter__ and __exit__ method, and put your use of the object in a with statement. It's clear, it's explicit, and it will work without worry.

Or, another way to make a context manager:

@contextlib.contextmanager
def tempdir(prefix='tmp'):
"""A context manager for creating and then deleting a temporary directory."""
tmpdir = tempfile.mkdtemp(prefix=prefix)
try:
yield tmpdir
finally:
shutil.rmtree(tmpdir)

What happens to tempfiles created with tempfile() in R?

(All this assumes you are using the default argument for tmpdir and the TEMP environment variable is set normally for your operating system.)

tl;dr Temporary files are deleted whenever R_CleanTempDir runs (as when the R session terminates)

The temporary files are deleted by deleting the temporary directory tempdir(). This occurs via the internal function R_CleanTempDir (link points to a unix implementation). This can be invoked through a variety of instances, but the most usual case is via quit (see below for the full chain). To answer your question, the temporary files will be deleted under a "normal" quit of the R session. (The "normal" is there to avoid things like a power failure at an inopportune time, plus "suicides".)

Indeed this is mentioned in the helpfile for ?quit:

Exactly what happens at termination of an R session depends on the platform and GUI interface in use. A typical sequence is to run .Last() and .Last.sys() (unless runLast is false), to save the workspace if requested (and in most cases also to save the session history: see savehistory), then run any finalizers (see reg.finalizer) that have been set to be run on exit, close all open graphics devices, remove the session temporary directory and print any remaining warnings (e.g., from .Last() and device closure).

As suggested in that helpfile, you may want to see if reg.finalizer would be helpful for your issue.

In some circumstances tempdir() may be deleted during long-running R session, but to guarantee deletion of temporary files you must explicitly remove them in the session or quit the session.


do_quit

SEXP attribute_hidden do_quit(SEXP call, SEXP op, SEXP args, SEXP rho)
{
const char *tmp;
SA_TYPE ask=SA_DEFAULT;
int status, runLast;

checkArity(op, args);
/* if there are any browser contexts active don't quit */
if(countContexts(CTXT_BROWSER, 1)) {
warning(_("cannot quit from browser"));
return R_NilValue;
}
if( !isString(CAR(args)) )
error(_("one of \"yes\", \"no\", \"ask\" or \"default\" expected."));
tmp = CHAR(STRING_ELT(CAR(args), 0)); /* ASCII */
if( !strcmp(tmp, "ask") ) {
ask = SA_SAVEASK;
if(!R_Interactive)
warning(_("save=\"ask\" in non-interactive use: command-line default will be used"));
} else if( !strcmp(tmp, "no") )
ask = SA_NOSAVE;
else if( !strcmp(tmp, "yes") )
ask = SA_SAVE;
else if( !strcmp(tmp, "default") )
ask = SA_DEFAULT;
else
error(_("unrecognized value of 'save'"));
status = asInteger(CADR(args));
if (status == NA_INTEGER) {
warning(_("invalid 'status', 0 assumed"));
status = 0;
}
runLast = asLogical(CADDR(args));
if (runLast == NA_LOGICAL) {
warning(_("invalid 'runLast', FALSE assumed"));
runLast = 0;
}
/* run the .Last function. If it gives an error, will drop back to main
loop. */
R_CleanUp(ask, status, runLast);
exit(0);
/*NOTREACHED*/
}

invokes R_CleanUp which invokes R_CleanTempDir:

void R_CleanUp(SA_TYPE saveact, int status, int runLast)
{
if(saveact == SA_DEFAULT) /* The normal case apart from R_Suicide */
saveact = SaveAction;

if(saveact == SA_SAVEASK) {
if(R_Interactive) {
switch (R_YesNoCancel(G_("Save workspace image?"))) {
case YES:
saveact = SA_SAVE;
break;
case NO:
saveact = SA_NOSAVE;
break;
case CANCEL:
// There might be residual events with destroyed handles
R_ProcessEvents();
jump_to_toplevel();
break;

}
} else saveact = SaveAction;
}

switch (saveact) {
case SA_SAVE:
if(runLast) R_dot_Last();
if(R_DirtyImage) R_SaveGlobalEnv();
if (CharacterMode == RGui) {
R_setupHistory(); /* re-read the history size and filename */
wgl_savehistory(R_HistoryFile, R_HistorySize);
} else if(R_Interactive && CharacterMode == RTerm) {
R_setupHistory(); /* re-read the history size and filename */
gl_savehistory(R_HistoryFile, R_HistorySize);
}
break;
case SA_NOSAVE:
if(runLast) R_dot_Last();
break;
case SA_SUICIDE:
default:
break;
}
R_RunExitFinalizers();
editorcleanall();
CleanEd();
KillAllDevices(); /* Unix does not do this under SA_SUICIDE */
AllDevicesKilled = TRUE; /* used in devWindows.c to inhibit callbacks */
R_CleanTempDir(); /* changes directory */
if (R_Interactive && CharacterMode == RTerm)
SetConsoleTitle(oldtitle);
if (R_CollectWarnings && saveact != SA_SUICIDE
&& CharacterMode == RTerm) /* no point in doing this for Rgui
as the console is about to close */
PrintWarnings(); /* from device close and (if run) .Last */
app_cleanup();
RConsole = NULL;
// Add some protection against calling this more than once:
// caused by signals on Unix, so maybe cannot happen here.
if(ifp) {
fclose(ifp); /* input file from -f or --file= */
ifp = NULL;
}
if(ifile[0]) {
unlink(ifile); /* input file from -e */
ifile[0] = '\0';
}
exit(status);
}


Related Topics



Leave a reply



Submit