views:

975

answers:

3

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.

+3  A: 

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
+5  A: 

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
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.
RamyenHead
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
A: 

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.

RamyenHead