5
$\begingroup$

My add-on needs to run both inside and outside of Blender (I have unit tests that I run with a headless version of Blender to make sure everything continues to work).

How do I determine in my __init__.py file if my package is being loaded and ran in Blender versus being loaded in just normal Python?

What I've tried:

  • globals() does not seem to contain anything useful to check at least in a loaded Python file. It has quite a few things in the Python console as well as when running a file from the TextEditor in Blender.
  • sys.modules[__name__].__addon_enabled__ does not seem to work
  • try: import bpy work for my case as I have a module in my environment called bpy (headless Blender)
$\endgroup$
3
  • 1
    $\begingroup$ My workaround for now is that for my unit tests there's an environment variable set to tell it that's it shouldn't try to do normal Blender registration. $\endgroup$
    – Cobertos
    Commented Sep 15, 2018 at 0:06
  • 3
    $\begingroup$ What about sys.argv ? $\endgroup$
    – batFINGER
    Commented Sep 16, 2018 at 17:37
  • $\begingroup$ Damn, that's a clever idea... I'll have to try that. $\endgroup$
    – Cobertos
    Commented Sep 16, 2018 at 19:50

2 Answers 2

3
$\begingroup$

edit: This answer will not work since Blender 2.91 because the meaning of sys.executable changed, see https://developer.blender.org/rB04c5471ceefb41c9e49bf7c86f07e9e7b8426bb3.


I found an example of this on the "Blender as a python module" wiki: https://github.com/TylerGubala/blenderpy/wiki/Caveat---Importing-Addons#development-of-new-gui-addons

Their suggestion is to test os.path.basename(sys.executable) for a prefix of "blender" vs "python", eg.

in_blender = os.path.basename(sys.executable or '').lower().startswith('blender')

(Testing sys.executable is a little better than sys.argv[0]. A script with a shebang line called like ./blender-script.py will have a sys.argv[0] of "./blender_script.py" (giving a false positive), while its sys.executable will still be the path to the python interpreter.)

Another idea is to test that sys.executable is the same as bpy.app.binary_path

try:
    import bpy
    in_blender = (sys.executable == bpy.app.binary_path)
except ModuleNotFoundError:
    in_blender = False
$\endgroup$
1
  • $\begingroup$ Wouldn't os.path.samefile(sys.executable, bpy.app.binary_path) been more robust again file system? $\endgroup$
    – HikariTW
    Commented Aug 10, 2020 at 3:17
3
$\begingroup$

IS_RUNNING_IN_BLENDER: bool = not hasattr(__builtins__, 'print')

Blender's __builtins__ dict doesn't contain print, so you can check for its presence and assume that the file is running in Blender if print is not present, and running outside of Blender if print is present.

$\endgroup$
1
  • 1
    $\begingroup$ This is False in my copy of Blender (4.2, Linux). $\endgroup$
    – scurest
    Commented Jun 28 at 1:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .