Below is the code written in a script say test_atexit.py
def exit_function():
print "I am in exit function"
import atexit
atexit.register(exit_function)
print "I am in main function"
When i run the function using python2.4 then exit_function is being called
$python2.4 test_atexit.py
I am in main function
I am in exit function
When i run the same using ipython then exit_function is not being called
$ ipython
In [1]: %run test_atexit.py
I am in main function
In [2]:
why exit_function is not called when running script using Ipython and how can i make ipython to call exit_function
atexit functions are called when the Python interpreter exits, not when your script finishes. When you %run something in IPython, the interpreter is still running until you quit IPython. When you do that, you should see the output from your exit_function().
Possibly what you want is a try/finally, which ensures that the finally code is run after the try block, even if an exception occurs:
try:
print("Doing things...")
raise Exception("Something went wrong!")
finally:
print("But this will still happen.")
If you really need to make atexit functions run, then you can call atexit._run_exitfuncs. However, this is undocumented, and it may do unexpected things, because anything can register atexit functions - IPython itself registers half a dozen, so you're likely to break things if you do it in IPython.
(Also, Python 2.4? For the sanity of developers everywhere, if it's possible to upgrade, do so ;-) )
Related
I am on windows 11
I executed rustup-init.exe
Create a main.rs file with
fn main() {
println!("Hello, world!");
}
I then executed rustc main.rs from Windows Power Shell to compile the program
Then, from Power Shell, i executed main
I got nothing at all on console. The prompt simply goes to new lines.
Then without any apparent reason, the following setting window of windows 11 will popup.
What damn is happening ?!?!
This happens only from Power Shell
From cmd it works
As suggested from #JeroenMostert in the comment
Executing from Power Shell the command main will execute automatically the .cpl.
Indeed, executing main.exe will execute my executable.
Damn.
This question has been asked before, but I have tried the solutions in related questions such as this to no avail.
I am having problems with Python's exit command, and I have ruled out a problem with my code as run by vanilla Python 3. The problem comes when I run it with iPython or in Spyder's iPython console.
When I use just a simple exit command, I get the error:
NameError: name 'exit' is not defined
I have already imported sys as suggested by the other link. The only thing that kind of works is to try sys.exit() in which case I get:
An exception has occurred, use %tb to see the full traceback.
SystemExit
C:\Users\sdewey\AppData\Local\Continuum\Anaconda3\lib\site-
packages\IPython\core\interactiveshell.py:2870: UserWarning: To exit: use
'exit', 'quit', or Ctrl-D.
warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
I only say that that "kind of works" because the error message is smaller so it's less annoying :).
Any ideas? Seems like an issue with iPython. I have encountered a different issue in Jupyter (which uses iPython) where quit was ignored entirely, which I posted about separately here
I've run into the same issue while running scripts containing exit() in Pycharm's IPython shell.
I learned here, that exit is intended for interactive shells, so behaviour will vary depending on how the shell implements it.
I could figure out a solution which would...
not kill the kernel on exit
not display a traceback
not force you to entrench code with try/excepts
work with or without IPython, without changes in code
Just import 'exit' from the code beneath into scripts you also intend to run with IPython and calling 'exit()' should work. You can use it in jupyter as well (instead of quit, which is just another name for exit), where it doesn't exit quite as silent as in the IPython shell, by letting you know that...
An exception has occurred, use %tb to see the full traceback.
IpyExit
"""
# ipython_exit.py
Allows exit() to work if script is invoked with IPython without
raising NameError Exception. Keeps kernel alive.
Use: import variable 'exit' in target script with 'from ipython_exit import exit'
"""
import sys
from io import StringIO
from IPython import get_ipython
class IpyExit(SystemExit):
"""Exit Exception for IPython.
Exception temporarily redirects stderr to buffer.
"""
def __init__(self):
# print("exiting") # optionally print some message to stdout, too
# ... or do other stuff before exit
sys.stderr = StringIO()
def __del__(self):
sys.stderr.close()
sys.stderr = sys.__stderr__ # restore from backup
def ipy_exit():
raise IpyExit
if get_ipython(): # ...run with IPython
exit = ipy_exit # rebind to custom exit
else:
exit = exit # just make exit importable
You can use system warnings to set those warning that you do not need as ignored. Example:
the function that you call from somewhere else:
def my_function:
statements
if (something happened that you want to exit):
import warnings
warnings.filterwarnings("ignore")
sys.exit('exiting...')
I'm relatively new to NumPy/SciPy and IPython.
To execute a python script in the python interactive mode, we may use the following commands.
>>> import os
>>> os.system('executable.py')
Then the print outputs can be seen from the python prompt.
But the same idea doesn't work with IPython notebook.
In [64]:
import os
os.system('executable.py')
Out[64]:
0
In this case, I cannot see any print outputs. The notebook only tells weather execution was successful or not. Are there any ways to see the outputs when I use IPython notebook?
Use the magic function %run:
%run executable.py
This properly redirects stdout to the browser and you will see the output from the program in the notebook.
It gives you both, the typical features of running from command line plus Python tracebacks if there is exception.
Parameters after the filename are passed as command-line arguments to
the program (put in sys.argv). Then, control returns to IPython's
prompt.
This is similar to running at a system prompt python file args,
but with the advantage of giving you IPython's tracebacks, and of
loading all variables into your interactive namespace for further use
(unless -p is used, see below).
The option -t times your script. With -d it runs in the debugger pdb. More nice options to explore.
Using python 3.2, and the following code snippet:
p = subprocess.Popen(['../start_server.sh'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out,err = p.communicate()
if out != None :
out = out.decode('utf-8')
if err != None :
err = err.decode('utf-8')
print('out ',out)
print('err ',err)
on some shell scripts, it works just fine and I get my output. on others it just hangs. but in every case the shell script runs from the command line with no errors. The only commonality i can see is (usually) the ones that hang have zero output. When stuff fails, I check running processes and i see my shell script is not listed and the python script is still running
Whats a reliable way to call a shell script and always return control to my python program?
Edit:
Using pipes Popen and such is not a requirement, the only requirement is that control is returned to my python script when the shell script exits. If the shell script never returns to the command prompt, then my python script will also never return.
So assuming the shell script(s) I am calling always return to the command prompt, how can I get control back to my python program?
If theres a better way that what ive listed above -- please enlighten me
One additional bit ive found is the shell scripts that "hang" seem to end with a call to 'nohup' Ye they return to the command prompt with no issues.
Whats a reliable way to call a shell script and always return control
to my python program?
If you are using pipes, this will depend on your scripts; a more general answer is essentially the halting problem and even the mighty StackOverflow can't help you with that.
I would encourage you to dig deeper and try to create a reproducible case so that we can help you solve the particular problem you're seeing.
Edit
If you don't need pipes, then just omit the stdout and stderr parameters (or set them to something other than PIPE). See python subprocess management.
I have some scripts that I have started unit-testing using the "modulino" idea. I have encountered a problem in that when the script is called with "perl -d" the script does not run as caller() returns a true value.
I have the main body of the script wrapped in a main() and some subroutines being slowly pulled out of the main() into their own subroutines.
At the top of the script I have:
main(#ARGS) unless caller();
When called in .t tests it works as I want, not running main() so I can test the subroutines. When I call the script from CLI it works great calling main().
The problem occurs when I call it from the CLI with:
perl -d myscript.pl
At this stage caller returns a valid value (rather than undef) and main is not called.
Suggestions would be much appreciated about how to approach this one.
The situation with -d switch is similar as with testing - your code is executed by something else, in this case the debugger.
You can either run main yourself by calling it in the debugger manually or you have to detect if caller is debugger. Something like:
main(#ARGS) if !caller() || (caller)[0] eq 'DB';