Subject: bug#6782: python.el's run-python removes current directory from sys.path

From: Jim Blandy <[email-masked]>
Date: Mon, 2 Aug 2010 11:11:48 -0700

Please write in English if possible, because the Emacs maintainers
usually do not have translators to read other languages for them.

Your bug report will be posted to the [email-masked] mailing list.

Please describe exactly what actions triggered the bug
and the precise symptoms of the bug:

Suppose I have a directory set up as follows:

  $ ls
  a.py  b.py
  $ cat a.py
  import b
  b.hello()
  $ cat b.py
  def hello():
      print "Hello!"

In most normal ways of running Python, a.py is able to find b.py, even
though PYTHONPATH is not set:

  $ python
  Python 2.6.4 (r264:75706, Dec  7 2009, 18:45:15)
  [GCC 4.4.1] on linux2
  Type "help", "copyright", "credits" or "license" for more information.
  >>> import a
  Hello!
  $ python a.py
  Hello!
  $ echo $PYTHONPATH

  $

However, if I visit a.py in Emacs, and then hit `C-c C-c'
(python-send-buffer), I get the following error:

  >>> Traceback (most recent call last):
    File "/tmp/py6932ha1", line 1, in <module>
      import b
  ImportError: No module named b

I think the problem is in the way Emacs' python-mode runs Python. If I
type M-x run-python, then I see this:

  >>> import sys
  >>> '' in sys.path
  False

whereas if I run the python interpreter from the shell, I see:

  >>> import sys
  >>> '' in sys.path
  True

This seems to be due to the following code in run-python from
progmodes/python.el:

  (let* ((cmdlist
      (append (python-args-to-list cmd)
          '("-i" "-c" "import sys; sys.path.remove('')")))

which has no comment, and the following helpful ChangeLog entry:

2008-08-24  Romain Francoise  <[email-masked]>

        * progmodes/python.el (run-python): Remove '' from sys.path.

Here's a workaround that one can put in one's .emacs file:

(defun python-reinstate-current-directory ()
  "When running Python, add the current directory ('') to the head of sys.path.
For reasons unexplained, run-python passes arguments to the
interpreter that explicitly remove '' from sys.path. This means
that, for example, using `python-send-buffer' in a buffer
visiting a module's code will fail to find other modules in the
same directory.

Adding this function to `inferior-python-mode-hook' reinstates
the current directory in Python's search path."
  (python-send-string "sys.path[0:0] = ['']"))

(add-hook 'inferior-python-mode-hook 'python-reinstate-current-directory)

In GNU Emacs 23.0.91.2 (i686-pc-linux-gnu, GTK+ Version 2.14.4)
 of 2009-03-20 on frida
Windowing system distributor `The X.Org Foundation', version 11.0.10604000
configured using `configure  '--prefix=/home/jimb/emacs''

Important settings:
  value of $LC_ALL: nil
  value of $LC_COLLATE: nil
  value of $LC_CTYPE: nil
  value of $LC_MESSAGES: nil
  value of $LC_MONETARY: nil
  value of $LC_NUMERIC: nil
  value of $LC_TIME: nil
  value of $LANG: en_US.UTF-8
  value of $XMODIFIERS: nil
  locale-coding-system: utf-8-unix
  default-enable-multibyte-characters: t

Major mode: Inferior Python

Minor modes in effect:
  compilation-shell-minor-mode: t
  erc-list-mode: t
  erc-menu-mode: t
  erc-autojoin-mode: t
  erc-ring-mode: t
  erc-networks-mode: t
  erc-pcomplete-mode: t
  erc-track-mode: t
  erc-track-minor-mode: t
  erc-match-mode: t
  erc-button-mode: t
  erc-fill-mode: t
  erc-stamp-mode: t
  erc-netsplit-mode: t
  erc-irccontrols-mode: t
  erc-noncommands-mode: t
  erc-move-to-prompt-mode: t
  erc-readonly-mode: t
  tooltip-mode: t
  mouse-wheel-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  global-auto-composition-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  line-number-mode: t
  transient-mark-mode: t

Recent input:
e s d <backspace> <backspace> <backspace> s e n d -
s t r i n g SPC " s y s . p a t h [ : 0 <backspace>
<backspace> : 0 <backspace> <backspace> 0 : 0 ] SPC
= SPC [ ' ' ] " C-b \ n <backspace> <backspace> C-e
C-a M-f M-f M-f C-e C-M-b C-M-f ) <return> <tab> (
C-a C-k C-M-b C-M-f M-> <backspace> ) <return> <return>
( a d d - h o o k SPC ' p y t h n <backspace> o n M-b
C-b C-h f <return> C-e M-b i n e f i o r <M-backspace>
i n f e r i o r - C-e / m o <backspace> <backspace>
<backspace> <M-tab> <M-tab> m <M-tab> - h <M-tab> C-h
f <return> SPC ' p y t h o n - i <backspace> r e i
M-/ ) C-j C-p C-k C-p C-p C-p C-p C-p C-M-x C-n C-n
C-n C-n C-e M-> <switch-frame> C-x b * <backspace>
* p <backspace> P t h <tab> <backspace> <backspace>
y t h <tab> <return> C-x k <return> M-x r u n - p y
t h <tab> <return> s y s . p a t h <return> C-x k <return>
M-x r u n - p y t h <tab> <return> s y s . p a t h
<return> C-x k <return> C-x b a . p <tab> <return>
C-c C-c C-x o C-x b * P T <backspace> y <tab> <return>
<help-echo> <switch-frame> <backspace> C-SPC C-p C-p
C-p C-p C-p C-p C-p C-p C-p C-p C-p C-p C-p M-w C-x
C-x C-4 C-x <tab> C-x C-x M-w <help-echo> <switch-frame>
<help-echo> M-x r e p o r t - e m a c s - b u g <r
eturn>

Recent messages:
Fontifying *Python*... (regexps...........)
Mark set
Making completion list...done
Type C-x 4 C-o RET to restore the other window.
python-reinstate-current-directory
Mark set
Fontifying *Python*... (regexps...........)
Fontifying *Python*... (regexps...........)
Fontifying *Python*... (regexps...........)
Mark set