Question

I am coding python in emacs. However, somehow the python interpreter running in emacs manages to surprise me.

If I write

print()
print(__name__)
print(__name__=='__main__')
if __name__ == '__main__':
    print("indeed")

in an emacs buffer, and tell emacs to start an interpreter and run the content of this buffer, I get a buffer containing

Python 3.3.5 (default, Mar 18 2014, 02:00:02) 
[GCC 4.2.1 20070831 patched [FreeBSD]] on freebsd9
Type "help", "copyright", "credits" or "license" for more information.
>>> 
__main__
True
>>> 

(Both __main__ and True are the outputs from the print statement; the python buffer always displays the >>> and prints immediately after it. I am aware of this, this is not a problem.)

From the command line, both python and python -i show the 'indeed', as expected.

How is Emacs able to the inconsistency of evaluating __name__=='__main__' to True, while not executing things inside if __name__ == '__main__':? And how do reconfigure it so it does not do so any more?

Was it helpful?

Solution

As @Wooble mentioned in the comment, it might be python.el issue: C-c C-c runs
python-shell-send-buffer function:

python-shell-send-buffer is an interactive compiled Lisp function in `python.el'.

(python-shell-send-buffer &optional ARG)

Send the entire buffer to inferior Python process. With prefix ARG allow execution of code inside blocks delimited by "if __name__=='__main__':"

i.e., to print "indeed", add prefix C-u C-c C-c.

Q: I have tried to dig through python.el, and I am still not sure how and where it does this. Can you explain, so I can modify the default behaviour?

To find out what C-c C-c does in your case open a python file and type M-x describe-key RET followed by C-c C-c (actually press the keys). By default it runs python-shell-send-buffer function in python.el. You could redefine the keys to call the function with an argument so that C-c C-c would behave like C-u C-c C-c that enables running "if __name__=='__main__':" part:

;; Make C-c C-c behave like C-u C-c C-c in Python mode
(require 'python)
(define-key python-mode-map (kbd "C-c C-c")
  (lambda () (interactive) (python-shell-send-buffer t)))

OTHER TIPS

This 'Feature' gets never old. Try using

__name__=='__main__':

without the whitespace between the opperator.

Then python.el will not bypass it. So look at your code formater.

Once you have started the python shell, you can simply override the variable:

__name__ = 'repl' 

This prevents any if __name__=='__main__': blocks from running on any subsequent C-c C-c invocations.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top