Emacs - Running current file in Python - python

I am using ELPY in emacs in Windows. How do I eval current file inside emacs using a Shortcut.
When I use eval-buffer.
I get below messages.
Flymake unable to run without a buffer file name
Removed if main == 'main' construct, use a prefix argument to evaluate.

There is a built in feature in emacs when working with the python (inferior) shell, to prevent people from running the whole script unintentionally, which is does by redefining (or removing) __name__ before it runs.
Your script does send __name__ = "__main__" but it is overwritten, due to this 'safety feature'.
To execute as you wish, running it as main, use the key binding:
`C-u C-c C-c`
If you would like to remap this to be something quicker or more familiar, try something like this:
(global-set-key (kbd "<f7>") (kbd "C-u C-c C-c"))
this was discussed in this thread here, where there is also some related extra information.

Related

Call a python script from a python script within the same context

There is a python script start_test.py.
There is a second python script siple_test.py.
# pseudo code:
start_test.py --calls--> subprocess(python.exe simple_test.py, args_simple_test[])
The python interpreter for both scripts is the same. So instead of opening a new instance, I want to run simple_test.py directly from start_test.py. I need to preserve the sys.args environment. A nice to have would be to actually enter following code section in simple_test.py:
# file: simple_test.py
if __name__ == '__main__':
some_test_function()
Most important is, that the way should be a universal one, not depending on the content of the simple_test.py.
This setup would provide two benefits:
The call is much less resource intensive
The whole stack of simple_test.py can be debugged with pycharm
So, how do I execute the call of a python script, from a python script, without starting a new subprocess?
"Executing a script" is a somewhat blurry term.
Typically the if __name__== "__main__": part does the argument (sys.argv) decoding and then calls a worker function with explicit parameters. For clarity: It should not do anything else, since this additional work can't be called without creating a new process causing all the overhead you are trying to avoid.
You simply bypass that and call this implementing routine directly.
So you end up with start_test.py containing something like:
from simple_test import worker
# ...
worker(typed_arg1, typed_arg2)

Why are os.system and subprocess.call spawning so many processes?

import os
import subprocess
import sys
import re
## fname_ext=sys.argv[1]
fname_ext=r"C:\mine\.cs\test.cs"
exe=os.path.splitext(fname_ext)[0]+".exe" # Executable
fdir=os.path.split(fname_ext)[0]
fcontent=open(fname_ext).read()
p_using=re.compile("\s*using\s+((\w+[.]*)+)")
p_namespace=re.compile("\s*namespace\s+(\w+)")
usings=p_using.findall(fcontent)
usings=[x[0] for x in usings]
references=[]
for i in os.listdir(fdir):
path=fdir+"\\"+i
try:
if os.path.isdir(path) or (not path.endswith('cs')):continue
with open(path) as fp:
content=fp.read()
namespaces=p_namespace.findall(content)
for n in namespaces:
if n in usings and 'System' not in n:
references+=[path]
except:
pass
command="csc /nologo "+" ".join(references)+" "+fname_ext
## command=" ".join(references)
#~ ---------------------------------------------------------
# Build:
option=1
if option==0:
# using os.system
print ">>",command
if os.system(command)==0:
os.system(exe)
else:
#~ Using subprocess module
## print type(references)
command=['csc']
## print command,references
command.extend(["/nologo","/out:"+exe])
command.extend(references)
command.append(fname_ext)
## print command
if subprocess.call(command,shell=True)==0:
## print "running %s"%exe
subprocess.call([exe],shell=True)
else:
pass
## print "Failed to run"
#~ ---------------------------------------------------------
I have this code above that is supposed to run a Csharp program from SciTE. It searches
every .cs file in the directory and finds the file with the namespace that the current
file has included. The command to run the file in SciTE is:
command.go.*.cs=python C:\mine\.py\csc.py $(FilePath)
command.go.subsystem.*.cs=0
That program logic part is okay.
The issue is that when hit F5 with sample Csharp code like this:
using System;
using System.Collections;
using MyNamespace;
class Test{
public static void Main(String[] args){
MyObject inst=new MyObject();
MyObject.self_destruct(inst);
}
}
it runs ok. But when I uncomment the second fname_ext and comment the first one
and run the csc.py file, a window opens and keeps running, printing command(this happens
using the os.system option). When you use the subprocess.call option, the same thing
happens but this time only when shell=True. It ran for only 15 seconds and there were 800+
cmd.exe and python.exe processes.I had to wait almost 5 minutes after killing cmd.exe
for the mouse to start responding and 2 minutes more for desktop peek to work.
When shell=False, it runs ok, the same way as when you hit the F5 key from the file.
What is happening here?
What is shell=True doing that makes it behave that way?
The problem is that your sys.argv looks something like this:
['python', r'C:\mine\.py\csc.py', 'whatever.cs']
So, with the fname_ext line uncommented, you set fname_ext to r'C:\mine\.py\csc.py'. Which means your script ends up just running itself—which again runs itself, etc., as fast as possible until your system chokes.
The reason it doesn't happen with shell=False is that you can't actually exec a Python script. Ultimately you end up calling CreateProcess with your script, which tries to interpret it as a .exe file, fails, and returns an error. But with shell=True, you pass your script to cmd.exe to run as a program, and it does the same thing an interactive prompt or Explorer would do: finds the right mapping to execute .py files and uses it. (And os.system does effectively the same thing as shell=True, but with a couple extra layers tossed in for good measure.)
Okay, I'll take a stab at this. If I understand the situation, this script is called csc.py and you want to call the csc c# compiler. When you run csc /nologo (etc...) through cmd.exe, it starts looking for something called 'csc' with a known extension. It finds csc.py in the current directory and since .py is a registered extension, that's what gets executed.
The solution is to rename your python file or call out 'csc.exe' explicitly.

How to get output from gdb.execute in PythonGDB (GDB 7.1)?

I'm currently writing a Python GDB script. The problem is that it has to be compatible with GDB 7.1. So I first wrote the script for GDB 7.3.1 and used the following function to receive the output of an gdb command (GDB 7.3.1):
myvar = gdb.execute("info target", False, True)
The last parameter of this function is that it should return the result as a string (which makes perfectly sense; why else would I execute such a command ;) )
In GDB Version 7.1 though it seems that the last parameter isn't available thus this line(GDB 7.1):
myvar = gdb.execute("info target", False)
returns None.
Is there any chance to retrieve the output of this command? I already tried to redirect the standard output of my python script into a file, then loading this file but apparently the standard input and output of my python script is overwritten by the gdb environment so the output from the gdb.execute command is not be written to my file.
The only thing I could think of now is to wrap my script up with a bash script that first opens gdb with a python script that executes various commands and then pipe that into a file. Then open gdb again but with another python script that loads the file, parses it and then executes other commands based on the input from the file and so on. But this is a really the ugliest solution I can think of.
So is there a way to receive the output of an gdb.execute in GDB 7.1?
So is there a way to receive the output of an gdb.execute in GDB 7.1?
No.
Your best bet is to arrange for GDB-7.3 to be available. Since GDB doesn't usually use shared libraries (beyond libc and perhaps libpython), you can just copy gdb binary with your script. That will be much easier and more maintainable solution than the alternative you proposed.
You can write to a file, then read the file, for example:
os.system("rm tmp.txt")
gdb.execute("set logging file tmp.txt")
gdb.execute("set logging on")
mainsec=gdb.execute("info proc mappings")
gdb.execute("set logging off")
mainsec = open("tmp.txt").read()
The old version of gdb.execute was far superior though.
FYI now (tested with gdb 8.1) you can use the to_string parameter
https://sourceware.org/gdb/onlinedocs/gdb/Basic-Python.html
gdb.execute (command [, from_tty [, to_string]])
By default, any output produced by command is sent to GDB’s standard output (and to the log output if logging is turned on). If the to_string parameter is True, then output will be collected by gdb.execute and returned as a string. The default is False, in which case the return value is None.

pythonrc in interactive code

I have a .pythonrc in my path, which gets loaded when I run python:
python
Loading pythonrc
>>>
The problem is that my .pythonrc is not loaded when I execute files:
python -i script.py
>>>
It would be very handy to have tab completion (and a few other things) when I load things interactively.
From the Python documentation for -i:
When a script is passed as first argument or the -c option is used, enter interactive mode after executing the script or the command, even when sys.stdin does not appear to be a terminal. The PYTHONSTARTUP file is not read.
I believe this is done so that scripts run predictably for all users, and do not depend on anything in a user's particular PYTHONSTARTUP file.
As Greg has noted, there is a very good reason why -i behaves the way it does. However, I do find it pretty useful to be able to have my PYTHONSTARTUP loaded when I want an interactive session. So, here's the code I use when I want to be able to have PYTHONSTARTUP active in a script run with -i.
if __name__ == '__main__':
#do normal stuff
#and at the end of the file:
import sys
if sys.flags.interactive==1:
import os
myPythonPath = os.environ['PYTHONSTARTUP'].split(os.sep)
sys.path.append(os.sep.join(myPythonPath[:-1]))
pythonrcName = ''.join(myPythonPath[-1].split('.')[:-1]) #the filename minus the trailing extension, if the extension exists
pythonrc = __import__(pythonrcName)
for attr in dir(pythonrc):
__builtins__.__dict__[attr] = getattr(pythonrc, attr)
sys.path.remove(os.sep.join(myPythonPath[:-1]))
del sys, os, pythonrc
Note that this is fairly hacky and I never do this without ensuring that my pythonrc isn't accidentally clobbering variables and builtins.
Apparently the user module provides this, but has been removed in Python 3.0. It is a bit of a security hole, depending what's in your pythonrc...
In addition to Chinmay Kanchi and Greg Hewgill's answers, I'd like to add that IPython and BPython work fine in this case. Perhaps it's time for you to switch? :)

How can I add a command to the Python interactive shell?

I'm trying to save myself just a few keystrokes for a command I type fairly regularly in Python.
In my python startup script, I define a function called load which is similar to import, but adds some functionality. It takes a single string:
def load(s):
# Do some stuff
return something
In order to call this function I have to type
>>> load('something')
I would rather be able to simply type:
>>> load something
I am running Python with readline support, so I know there exists some programmability there, but I don't know if this sort of thing is possible using it.
I attempted to get around this by using the InteractivConsole and creating an instance of it in my startup file, like so:
import code, re, traceback
class LoadingInteractiveConsole(code.InteractiveConsole):
def raw_input(self, prompt = ""):
s = raw_input(prompt)
match = re.match('^load\s+(.+)', s)
if match:
module = match.group(1)
try:
load(module)
print "Loaded " + module
except ImportError:
traceback.print_exc()
return ''
else:
return s
console = LoadingInteractiveConsole()
console.interact("")
This works with the caveat that I have to hit Ctrl-D twice to exit the python interpreter: once to get out of my custom console, once to get out of the real one.
Is there a way to do this without writing a custom C program and embedding the interpreter into it?
Edit
Out of channel, I had the suggestion of appending this to the end of my startup file:
import sys
sys.exit()
It works well enough, but I'm still interested in alternative solutions.
You could try ipython - which gives a python shell which does allow many things including automatic parentheses which gives you the function call as you requested.
I think you want the cmd module.
See a tutorial here:
http://wiki.python.org/moin/CmdModule
Hate to answer my own question, but there hasn't been an answer that works for all the versions of Python I use. Aside from the solution I posted in my question edit (which is what I'm now using), here's another:
Edit .bashrc to contain the following lines:
alias python3='python3 ~/py/shellreplace.py'
alias python='python ~/py/shellreplace.py'
alias python27='python27 ~/py/shellreplace.py'
Then simply move all of the LoadingInteractiveConsole code into the file ~/py/shellreplace.py Once the script finishes executing, python will cease executing, and the improved interactive session will be seamless.

Categories

Resources