3
$\begingroup$

When using the Text Editor, what is the best command to include inside a script which will abort the script at that line?

quit() and sys.exit() stop the script, but also kill Blender.

$\endgroup$
  • $\begingroup$ raise RuntimeError("Stopping the script here") $\endgroup$ – Garrett Feb 5 '14 at 11:17
  • $\begingroup$ Obviously, this is not pretty. I'd like to hear other ideas. $\endgroup$ – Garrett Feb 5 '14 at 11:18
  • $\begingroup$ Running the script with this gives the message, Python script fail, look in the console for now... even though the script ran as expected (but exited because certain conditions were met) $\endgroup$ – Garrett Feb 5 '14 at 12:02
  • $\begingroup$ Can you move the content of your comments to the answer? The answer is getting flagged for low quality because it's so short. $\endgroup$ – CharlesL Feb 5 '14 at 14:18
8
$\begingroup$

I believe the answer to How to break out of multiple loops in python? applies here too:

Refactor your script!

Don't run all your code in the global scope, but organize everything in functions.

This is how your script might look at the moment:

def process(val):
    return val * 2

for i in range(5):
    print(process(i))

If you already use some def's and call them from a small portion of code, which resides in the global scope (no indentation), make this portion another function and only place the call to this function in the global scope. If no, wrap your entire code into a function main() (you may use any name here actually):

def process(val):
    return val * 2

def main():
    # This code used to be in the global scope...
    for i in range(5):
        print(process(i))

# ... but now, only the call to our 'main' function resides in global scope!
main()

What do we gain?

Now it's easy to raise an exception at any level of your script, and catch it at the highest level, so no error is printed or otherwise shown to the user:

class ExitOK(Exception):
    pass

def process(var):
    raise ExitOK # quit script immediately
    return val * 2

def main():
    for i in range(5):
        print(process(i))

try:
    main()
except ExitOK:
    print("OK")

I derived the class ExitOK from the Exception class to create a new exception, so we can raise and catch a distinct one. This means the script can still error out on other exceptions and show a traceback.

No need to code anything for our ExitOK exception for our purposes, we just use pass, 'cause every class needs a body.

You could also define another exception, e.g. ExitError, to stop your script at any level and print a different message (to inform about the error without the Blender popup thing):

class ExitError(Exception):
    pass

# ...

try:
    main()
except ExitOK:
    print("OK")
except ExitError:
    print("Failed")

You could also give more detailed information about the exit reason like so:

def process(val):
    raise ExitError("quit process() with value %i" % val)

# ...

try:
    main()
except ExitError as e:
    print("Failed:", e)
$\endgroup$
10
$\begingroup$

If it is meant to be temporary while drafting the script, raising an exception is probably the easiest solution.

raise Exception()

If it is not meant to be temporary you may consider reorganizing your code using additional functions or logic/control flow. Python actually runs faster if the code is wrapped in functions. (see this post on stackoverflow)

The equivalent to running the code from the text editor is (see api docs)

filename = "/full/path/to/myscript.py"
exec(compile(open(filename).read(), filename, 'exec'))

Calling sys.exit() raises an exception which is allowed to propagate and thus exits blender. (see SystemExit, exit(), exec() )

You may run your script manually with exec and catch an exception, i.e. SystemExit, with try ... except.

$\endgroup$
1
$\begingroup$

Open the python console before running the script. If you want to stop the script click on the python console and press control-C.

$\endgroup$
  • 1
    $\begingroup$ how will this work, ctrl C is "copy to Clipboard"? $\endgroup$ – David Jun 26 '16 at 16:48
  • 1
    $\begingroup$ Think he means system console, rather than python console. $\endgroup$ – batFINGER Aug 15 '17 at 5:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.