I am using emacs on a server so files in /tmp are not automatically cleared down. Every time inferior-python-mode runs, it leaves files in /tmp (e.g. /tmp/py15458epk).

I'm looking for a more elegant way to delete these temporary files when they're no longer needed. I assume these files are only needed by the shell to load and could, in theory, be deleted immediately afterwards but I don't know how to achieve this. As a compromise, I delete all my /tmp/py* files when I kill emacs:

;; cleanup on aisle 6
(add-hook 'kill-emacs-hook
  (lambda ()
    (shell-command "find /tmp -maxdepth 1 -name 'py*' -type f
                   -user \"$LOGNAME\" -print0 | xargs -0r rm -f")))

This seems a bit drastic and could very well delete a temporary file that is still needed by something else. How can I delete these files more precisely?

EDIT: Am using emacs 24.3, GNU tell me this is a known bug and does not exist after 25.1. Is anyone able to suggest a more elegant workaround until we upgrade?

  • Those temp files should not be left behind. Please report this is a bug via M-x report-emacs-bug. You might like to show the content of those temp files as well, if they're not just containing your own code. – Stefan Feb 25 '19 at 18:58

I think the bug was fixed already in 24.4, but python.el changed a lot between 24.3 and 24.4, so it's hard to say exactly when and where the fix was.

I guess an updated copy of python-shell-send-string in your init file with an added delete-file call should do the trick:

(when (version< emacs-version "24.4")
  (eval-after-load 'python ;; Fix Bug#34667.
    ;; From Emacs 24.3 lisp/progmodes/python.el.
    (defun python-shell-send-string (string &optional process msg)
      "Send STRING to inferior Python PROCESS.
When MSG is non-nil messages the first line of STRING."
      (interactive "sPython command: ")
      (let ((process (or process (python-shell-get-or-create-process)))
            (lines (split-string string "\n" t)))
        (and msg (message "Sent: %s..." (nth 0 lines)))
        (if (> (length lines) 1)
            (let* ((temporary-file-directory
                    (if (file-remote-p default-directory)
                        (concat (file-remote-p default-directory) "/tmp")
                   (temp-file-name (make-temp-file "py"))
                   (file-name (or (buffer-file-name) temp-file-name)))
              (with-temp-file temp-file-name
                (insert string)
              (python-shell-send-file file-name process temp-file-name)
              (delete-file temp-file-name)) ; <----------------- add this line
          (comint-send-string process string)
          (when (or (not (string-match "\n$" string))
                    (string-match "\n[ \t].*\n?$" string))
            (comint-send-string process "\n")))))))
| improve this answer | |

Your Answer

