ipython: exit() statement not working as expected - python

I am running a script into ipython (1.2.1) and I need it to stop if a certain condition is not met. I tried to use the exit() statement, but it is not behaving as expected.
Take for example the following script which I called test.py:
if(True):
print('Error')
exit()
print('Still here!')
When I run it using python test.py, I get:
$python test.py
Error
And then the execution is terminated, as expected.
But if I run it from ipython using run -i test.py, then I get:
In [1]: run -i test.py
Error
Still here!
And finally the execution of ipython is terminated. The problem is that in this case the second print statement is still executed, while I would need the execution of the script to be terminated as soon as the exit() statement is encountered.
Why is this happening and how can I obtain the result I want? (I am running python 2.7.6)

exit() alone is meant for the REPL, not really meant to be used by scripts.
Try using sys.exit(0) after you import sys, of course

Related

AWS Batch job is marked as successful when in fact its log shows that it failed

I have a job in AWS Batch, which calls a .sh file which in turn executes a python script. The python script fails with an error that it does not find a specific file in a directory, but, the process in AWS Batch finishes successfully, which should be the other way around. Is there anything I should check?
Would need to see both of the scripts for a better understanding. But unless you have some specific catch exception methods in your python script to return an error to the shell script when faced with an error, your shell script will proceed to run normally even if your python script returns an error.
For example:
#!/bin/bash
python3 main.py # calls a python script
# python script returns an error
echo "Hellow World!" # The shell script does not know if your python script returned an error or not.
# So it continues running the shell script
So the output would most likely be something like below:
FileNotFoundError: [Errno 2] No such file or directory: 'C:/Users/User/Desktop/Python-stuff
Hello World!
Try passing along the exit status:
#!/bin/bash
python3 /path/to/script.py
exit $?
Add set -euxo pipefail in the first line after the shebang of your bash script and it will fail if any of your statements fail.
More information here about what those set flags mean.
Actually to solve your question just set -e could be enough in some cases, but the other additional flags are also nice to have in most cases (as in the example below which does not fail just with set -e, you need set -eu).
One example script below:
#!/usr/bin/env bash
set -euxo pipefail
echo $UNDECLARED VARIABLE
echo "Script does not reach here"
If you run above script you will get this error: UNDECLARED: unbound variable. However without set -euxo pipefail script will exit with success error code (echo $? will return zero because the last statement was executed without errors).

Running bash script within python and wait for shell command to complete

I have the same question as here with python 3.x. I tried the solution provided but it does not work for me.
Python does not wait bash script to finish and prints "end" before bash script to be terminated.
I am on windows and have cygwin isntalled.
callBash.py:
import subprocess
print("start")
subprocess.call("sleep.sh",shell=True)
print("end")
sleep.sh:
#!/bin/bash
sleep 10
You never check the return value of subprocess.call, so it's likely that your script doesn't even start properly, maybe because of invalid PATH / CWD or permissions or something else.
Use subprocess.check_call instead, so that an exception is raised if your script fails to run. Exceptions are not so easy to miss.
Also if you have Python 3, subprocess.run(..., check=True) is newer and generally easier to work with.

SyntaxError when running with Python 2

I have a Python script called "controlled_biomass_exp.py" that generates some data and plots it. Its over 100 lines long so I don't want to dump it all here.
I can run it from Ipython in the terminal once and it works fine. If I repeat the command to run the script again with:
In [3]: run controlled_biomass_exp.py
I get:
File "< ipython-input-3-3ec3d096e779>", line 1
run controlled_biomass_exp.py
^
SyntaxError: invalid syntax
(The carrot is pointing at the last letter of the filename, "p".)
I get the same problem if I run any other python script after running this one. If I quit Ipython in the terminal and restart it the problem "re-sets". I can run other scripts fine, until I run the broken one once. I haven't encountered a problem like this before. Any help directing me where to look for solutions much appreciated.
It appears that your script controlled_biomass_exp.py overwrites run in your current namespace.
This toy example will produce a similar problem:
# file: test.py
run = "hello world!"
print(run)
Calling run in IPython is just a shortcut for %run which is a built-in magic function. Once you overwrite run (e.g. as shown in my toy example) you cannot use the shortcut anymore.
However, %run controlled_biomass_exp.py should still work for you.

unittest.main() crashes python interpreter in Spyder

I have a python script containing a unittest.TestCase, with a setUp() function and a small number of test_foo_does_bar()-type functions.
The script ends as follows:
if __name__ == '__main__':
unittest.main()
When I run this script in Spyder (see below for config details) the interpreter stops at the following line:
----------------------------------------------------------------------
Ran x tests in x.xxxs
FAILED (failures=x)
No amount of Ctrl+C or Ctrl+D can rescue the interpreter and get me back to the prompt. The same script, run from the command prompt, terminates as normal.
Is this a bug in Spyder or am I missing something?
Setup info:
Spyder 2.2.3
Python 2.7.5 64bits. Qt 4.8.4, PyQt4 (API v2) 4.9.6 on Windows
It doesn't crash the Python interpreter, it terminates it. This is normal behavior for the script.
You can see it yourself: in main.py it is stated, main = TestProgram; this means that unittest.main() will call the TestProgram class, which in its __init__(self) calls self.runTests(), which ends with this:
if self.exit:
sys.exit(not self.result.wasSuccessful())
So it has a specific call to sys.exit(), which terminates the interpreter.
In fact, if you run it as command line, you return to the command line; and if you start command-line Python, import the module and call the function, you will see that you'll return to the command prompt - you don't stay in Python.
If you want the script to NOT terminate the interpreter, just state it when calling the funcion:
unittest.main(exit=False)

Python script embedded in bash, does not exit

I'm having a curious problem. I have a bash script that is calling a python script within it. The python script executes successfully, but never fully terminates
Content of Bash script:
#! /usr/bin/env bash
python python_script.py
echo "bar"
content of Python script:
#Much stuff
sys.exit("The python script just ended")
What I expect to see on termination would be:
>The python script just ended
>bar
What I instead get is:
>The python script just ended
If I keyboard interrupt, the bash continues as:
^C>bar
What gives? Clearly the exit is calling properly, and there is nothing between that and the output statement in the bash script that called the python script.
(I can't necessarily give specifics on the workings of the "Much stuff" in the python script, as I'm modifying existing code that I don't fully understand. I've mostly left the workings of the script alone, and modified output more than anything for formatting, but I'm happy to try and provide you with any additional information requested)
What sys.exit() does is throw an exception of type SystemExit. If your script were to catch this exception, it would continue executing past sys.exit().
Also, if you have non-daemon threads, these could be preventing the process from terminating.
If that's the case, you can either turn them into daemon threads, or somehow signal to them that you wish to exit the script, and let them shut themselves down.
Finally, there's os._exit(), but you should not have to resort to that.
The following also works:
import os
print('Hellow world')
os._exit(os.EX_OK)
In Ubuntu, it exits the terminal. See also the example in this link Program With the os.exit() Method

Categories