3
$\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$
  • 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$ – Coburn Sep 15 '18 at 0:06
  • 3
    $\begingroup$ What about sys.argv ? $\endgroup$ – batFINGER Sep 16 '18 at 17:37
  • $\begingroup$ Damn, that's a clever idea... I'll have to try that. $\endgroup$ – Coburn Sep 16 '18 at 19:50
2
$\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$
  • $\begingroup$ Wouldn't os.path.samefile(sys.executable, bpy.app.binary_path) been more robust again file system? $\endgroup$ – HikariTW Aug 10 '20 at 3:17

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.