If I use tramp to open a remote file, and subsequently run run-python, it tries to execute in the remote context (which is not what I want and super slow).

Any way of specifying a local context or disabling this behaviour?

(defun run-python-locally (&rest args)
  (interactive (progn (require 'nadvice)
                       (cadr (interactive-form #'run-python)))))
  (let ((default-directory user-emacs-directory))
    (apply #'run-python args)))

(This uses the trick from this answer).

Additionally, if you'd like to use python-shell-send-string, python-shell-send-region and company, you'll need this fix:

(eval-when-compile (require 'cl-lib))
(defun nadvice/python-shell-send-string/fix-local-process
    (old-fun string &optional process)
  (cl-letf ((old-psstf (symbol-function #'python-shell--save-temp-file))
            ((symbol-function #'python-shell--save-temp-file)
             (lambda (string)
               (let ((default-directory
                       ;; if buffer is a remote file, but the process is not
                       ;; save the temp file locally, instead of remotely
                       (if (and buffer-file-name
                                (file-remote-p buffer-file-name)
                                (not (plist-get 'remote-tty
                                                (process-plist process))))
                 (funcall old-psstf string)))))
    (funcall old-fun string process)))

(advice-add 'python-shell-send-string :around
  • Nice! That automates what I was suggesting. – Daniel Mahler Mar 16 '16 at 21:10
  • I would probably make it a separate command though, rather then changing the behaviour of run-python itself. The default behaviour is useful most of the time. – Daniel Mahler Mar 16 '16 at 21:13
  • It may appear that I'm changing the definition of run-python because I'm using a function from nadvice, but I'm not. run-python-locally is a new, separate command, which doesn't modify the behavior of run-python. – PythonNut Mar 16 '16 at 21:15
  • Thanks. I thought nadvice was related to the advice mechanism. I will have to look it up. – Daniel Mahler Mar 16 '16 at 21:18
  • 1
    @DanielMahler this now works with the various process interaction functions. – PythonNut Mar 17 '16 at 0:00

You can start a local python console by executing run-python while in a local buffer (*scratch* will do). The problem is that python interaction will not work for remote files then without some additional hacking. Generally you need the python process to be running on the same machine that the files reside on since emacs communicates with the python process vial the file system.

For example python-shell-send-buffer saves a copy of the buffer in /tmp for the process to read. With a remote file and a local python process the buffer will get saved to on the remote machine and python will try to read from the same path on the local one and fail to find it.

To make python interaction work with files on a different machine from where the python shell is running would require tweaking the code to put temporary files on the machine where the python is running, regardless of where the file is, or where you are running emacs. I would be interested to know how to do that myself.

  • Sometimes I just want to dive into the Python console to use as a calculator. – EoghanM Mar 16 '16 at 14:35
  • @EoghanM executing run-python from *scratch* or another local buffer will give you that. You could even put (run-python) in your .emacs or init.el. For that use I also really recommend setting (custom-set-variables '(python-shell-interpreter "ipython") '(python-shell-interpreter-args "--pylab")) It will give you numpy and matplotlib.pyplot in your global namespace as well as all the benefits of IPython – Daniel Mahler Mar 16 '16 at 21:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.