Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

__name__ == '__main__' doesn't seem to be set #69

Closed
mankoff opened this issue Apr 28, 2013 · 19 comments
Closed

__name__ == '__main__' doesn't seem to be set #69

mankoff opened this issue Apr 28, 2013 · 19 comments

Comments

@mankoff
Copy link

mankoff commented Apr 28, 2013

I'm not sure if this is an elpy-bug or not, but I just switched to elpy and this appeared. When I used to load python-mode and ipython-mode and C-c !, the following code would run and print both statements:

if __name__ == "__main__":
    print "hello, world"

print "Goodbye, Cruel World"

When I run this through elpy, only Goodbye, Cruel World is printed, not Hello, World.

@jorgenschaefer
Copy link
Owner

What command does C-c ! run? That's not part of elpy.

What does print __name__ emit?

@mankoff
Copy link
Author

mankoff commented Apr 28, 2013

print __name__ returns __main__. So I'm a bit confused why "Hello, World" isn't printing when I C-c C-c.

Also, sorry for the confusion. I don't use C-!. I did yesterday (and before) with my previous emacs python setup, but now with elpy use C-c C-c.

@jorgenschaefer
Copy link
Owner

This is some seriously weird behavior:

print repr(__name__ == '__main__')

if __name__ == '__main__':
    print "Direct yep"
else:
    print "Direct nope"

cond = __name__ == '__main__'

if cond:
    print "Indirect yep"
else:
    print "Indirect nope"

Results in:

True
Direct nope
Indirect yep

wtf? :-D

@jorgenschaefer
Copy link
Owner

Heh. It seems python-shell-send-buffer in python.el actively replaces if __name__ == '__main__' statements so they are not evaluated when using C-c C-c … so that's a feature, not a bug.

I will have to think about that to figure out if I like that behavior.

@jorgenschaefer
Copy link
Owner

The fix should be for elpy-shell-send-region-or-buffer to accept a prefix argument like python-shell-send-buffer does and forward that when appropriate. Marked as bug, will fix in the next release.

Thank you for the report!

@mankoff
Copy link
Author

mankoff commented May 12, 2013

Hi Jorgen,

I just saw an update and the bug still remains. I'm using "elpy-20130511.2055". Is this the release that should contain the bug fix?

@jorgenschaefer
Copy link
Owner

Yes. You should be able to use C-u C-c C-c to send a buffer and have __name__ == "__main__" lines executed. By default, it won't (feature of python.el). Let me know if that does not work.

@mankoff
Copy link
Author

mankoff commented May 12, 2013

Ah. I was using C-c C-c. Adding C-u makes it work. Thanks.

@jorgenschaefer
Copy link
Owner

Quite often when writing a script, you want to test functions in the script instead of running it (which might even end up with calling exit()), so python.el prevents executing that "__main__" line by default. With the C-u it won't. I think that's quite a handy feature, all in all, so I left it in.

Glad it works :-)

@mankoff
Copy link
Author

mankoff commented May 12, 2013

I'm going to use this ticket to ask a semi-off-topic question. I hope that is OK. In the fix above you state

The new python.el's python-shell-send-buffer function is smart and
replaces if __name__ == '__main__' lines with something that does
not match, to avoid executing code that's meant to run only in a
script. You can force that to be executed by passing a prefix arg.

This is a nice idea, so elpy now does the same, passing the prefix
arg to the python.el function.

I'm fairly new to python development so I don't see why this is a nice idea. What else should I plan on running when I do C-c C-c? Maybe unit tests or something else for example? And if so, should that other code be in

if __name == '__main__':
   script_code ()
else:
   # HERE

# Or should I put it here, not indented, not part of the `if` clause?

@mankoff
Copy link
Author

mankoff commented May 12, 2013

Oh! You preemptively explained it to me and our comments crossed in the ether. THANK YOU!

@jorgenschaefer
Copy link
Owner

Oh. Ok :-D

Leaving the below as I already had typed it. Enjoy Python! :-)


You can run unittests with C-c C-t in elpy.

A scrip regularly looks something like this:

#!/usr/bin/env python

def main():
    do something

def foo(a, b):
    do something else

def bar(c):
    do yet another thing

if __name__ == '__main__':
    main()

You can then use C-c C-c to send the whole script to the inferior Python mode and test foo and bar, modifying the script, and sending it again, without it executing main() every time you send the file.

@mankoff
Copy link
Author

mankoff commented May 12, 2013

Still a little bit confused.

What you show is how I used to have my code, but now C-c C-c means nothing happens. So I'll start using C-u C-c C-c.

The new confusion is because you write above that I can used C-c C-c to send the whole script and test foo and bar. Where does this happen in a standard script? In the else section of the if __name__..., or just at the bottom of the file outside the of that if clause? Or when you say 'test' do you mean interactive test at the REPL?

Thanks again for the explanations. I'm just trying to get some best-practices down and haven't found this information elsewhere.

@jorgenschaefer
Copy link
Owner

Er, yes, I do mean interactive testing.

When you use C-c C-c, your current definitions of foo and bar are available in your inferior Python shell. You can simply use those functions interactively. Then you notice something isn't working as you'd like it to, so you edit the functions in your buffer, and use C-c C-c so you have the new definitions available.

If you want to automatically run tests, I really recommend using unittests and C-c C-t :-)

@mankoff
Copy link
Author

mankoff commented May 12, 2013

Ok. All clear. Thanks again. Sorry for hijacking the thread.

@jorgenschaefer
Copy link
Owner

No problem, it was yours to begin with. :-D

@jijiGuGu
Copy link

Hi Jorgen,

How do I bind 'C-u C-c C-c' into a hot key, for example, [f7], in my init.el file?

@jorgenschaefer
Copy link
Owner

This should work:

(global-set-key (kbd "<f7>") (kbd "C-u C-c C-c"))

@jijiGuGu
Copy link

It did. Thank you Jorgen. I appreciate it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants