17

I have been using Emacs to write Python 2 code. Now I have both Python 2.6 and 3.0 installed on my system, and I need to write Python 3 code as well.

Here is how the different versions are set up in /usr/bin:

python -> python2.6*
python2 -> python2.6*
python2.6*

python3 -> python3.0*
python3.0*

Is there any way to set this up so that Emacs uses the correct version of Python, depending on which language I am using? For instance, C-c C-c currently runs the buffer, but it always calls python2.6, even if I am writing Python 3 code.

  • 1
    Are you wondering how to get Emacs to automatically detect whether you are writing Python 2 code or Python 3 code, and to call the correct Python version? Or are you asking how to change Emacs so that it calls a different command (ie. python3) in all cases when Python code is loaded into the buffer? – Greg Hewgill Feb 01 '09 at 22:29
  • Obviously the first would be ideal, but that seems pretty hard, as the syntactic differences between Python 2 and Python 3 are minor. It looks like the answers to this question take care of the second case. Thanks for clarifying. –  Feb 03 '09 at 22:48

5 Answers5

10

If you are using python-mode.el you can try to change py-which-shell. In order to do this on a per-file basis you can put

# -*- py-which-shell: "python3"; -*-

at the first line of your file - or at the second line if the first line starts with #!. Another choice is to put

# Local Variables:
# py-which-shell: "python3" 
# End: 

at the end of your file. Perhaps you should give the full path to python3 instead of just "python3".

cefstat
  • 2,336
  • 1
  • 18
  • 25
  • The file local variable doesn't work for me. It seems the py-python-command should be set with setq in dotemacs to take effect. I'll elaborate in my other answer to the original question. – Yoo Sep 22 '09 at 15:24
  • I had suggested setting py-python-command but python-mode.el uses internally py-which-shell and sets py-which-shell to the value of py-python-command *before* it sees the file-local value. I have edited the answer to suggest changing directly py-which-shell. – cefstat Nov 12 '09 at 11:35
  • I suspect this would be more useful for `C-h i g (emacs) Directory Variables` than for `(emacs) File Variables` – phils Dec 23 '14 at 03:24
4

The answer is yes. If you can distinguish Python 2 from Python 3, then it is a Simple Matter Of Programming to get emacs to do what you want.

(define run-python (&optional buffer)
    (with-current-buffer (or buffer (current-buffer))
        (if (is-python3-p)
              (run-python3)
            (run-python2))))

(define-key python-mode-map (kbd "C-c C-c") #'run-python)

All that's left to do is implement is-python3-p and run-python3 (etc.)

jrockway
  • 42,082
  • 9
  • 61
  • 86
3

My comment on this answer.

I wrote /t/min.py which will run fine in python3 but not in python2 (dictionary comprehension works in python3)

Contents of /t/min.py

#!/usr/bin/python3
# -*- py-python-command: "/usr/bin/python3"; -*-
a = {i:i**2 for i in range(10)}
print(a)

Note that the shebang indicates python3 and the file local variable py-python-command too.

I also wrote /t/min-py.el which makes sure that python-mode.el (ver 5.1.0)is used instead of python.el.

Contents of /t/min-py.el

(add-to-list 'load-path "~/m/em/lisp/")
(autoload 'python-mode "python-mode" "Python Mode." t)
;; (setq py-python-command "python3")

Note that the last line is commented out.

I start emacs with the following command:

emacs -Q -l /t/min-py.el /t/min.py &

Now emacs is started with my alternate dotemacs /t/min-py.el and it opens /t/min.py.

When I press C-c C-c to send the buffer to python, it says the "for" part is wrong and that indicates that python2 is being used instead of python3. When I press C-c ! to start the python interpreter, it says python 2.5 is started.

I can even change the second line of /t/min.py to this:

# -*- py-python-command: "chunkybacon"; -*-

and do this experiment again and emacs still uses python2.

If the last line of /t/min-py.el is not commented out, then C-c C-c and C-c ! both use python3.

Community
  • 1
  • 1
Yoo
  • 17,526
  • 6
  • 41
  • 47
  • It seems that your local variables are not evaluated. Do you see the message asking for confirmation before evaluation? otherwise what is the value of `enable-local-variables`, if it is not `t` your local variables are ignored! – marcz Jan 23 '13 at 20:52
2

regarding jrockway's comment:

(defun is-python3-p () "Check whether we're running python 2 or 3."
  (setq mystr (first (split-string (buffer-string) "\n" t)))
  (with-temp-buffer
    (insert mystr)
    (goto-char 0)
    (search-forward "python3" nil t)))
(defun run-python () "Call the python interpreter."
  (interactive)
  (if (is-python3-p)
      (setq py-python-command "/usr/bin/python3")
    (setq py-python-command "/usr/bin/python"))
  (py-execute-buffer))

This will call python3 if "python3" is in the top line of your buffer (shebang, usually). For some reason the (setq py-pyton-command ...) doesn't let you change versions once you've run py-execute-buffer once. That shouldn't be an issue unless you change your file on the same buffer back and forth.

Felipe
  • 3,003
  • 2
  • 26
  • 44
1

With current python-mode.el shebang is honored.

Interactively open a Python shell just with

M-x pythonVERSION    
M-x python

will call the installed default.

http://launchpad.net/python-mode

chiwangc
  • 3,566
  • 16
  • 26
  • 32
Andreas Röhler
  • 4,804
  • 14
  • 18