3
$\begingroup$

Where do I put the Python packages my addon imports so Blender can find them? (There are some questions on this topic already but I can't find what I'm doing wrong.)

It works fine on my Linux system where I can install the dependencies to a standard Python path. But I understand Blender often comes with its own Python installation, and besides I want a way to bundle all the code together for a one-click install from zip file.

First I tried making it into a single package, that is scripts/addons/my_addon/ containing my code in __init__.py and subdirectories for the dependencies. Blender finds __init__.py fine, but import fails even though the modules are right there in the same place.

So I tried putting the dependencies in scripts/addons/modules/, though I don't like that because they could clobber different versions installed by another addon, and they stay there even if the user removes my addon through User Preferences. But this still isn't working.

For example: "six" is a module that helps with python 2/3 portability; it's contained in a single file six.py. From the Blender Python console on Windows:

>>> print(sys.path[-1])
C:\Users\jwelsh\AppData\Roaming\Blender Foundation\Blender\2.70\scripts\addons\modules

>>> print(imp.find_module('six')[1])
C:\Users\jwelsh\AppData\Roaming\Blender Foundation\Blender\2.70\scripts\addons\modules\six.py

>>> import six
Traceback (most recent call last):
  File "<blender_console>", line 1, in <module>
ImportError: No module named 'six'
$\endgroup$
  • $\begingroup$ This looks like it should work, debugging this remotely is near impossible, on Linux I use strace to find which paths are searched for Python module loading. you could try find an strace equivalent for Windows. $\endgroup$ – ideasman42 Jun 17 '14 at 11:05
2
$\begingroup$

You can convert your single file based addon into to a module by creating a folder with the name of the intended module, ie six and renaming six.py to __init__.py. This folder will be now recognised as a python module and loaded as an add-on because of the bl_info in the __init__.py.

With this setup, you can use it to store and segregate your add-on dependencies from other addons that you have installed. This also has the added benefit of keeping things as you manage the contents of this folder and should not rely/assume other dependencies exist.

Generally you will want to use ..\scripts\addons\ folder as the root directory for your add-on as the ..\scripts\addons\modules folder can be used to install shared dependencies by authors of modules, which you allured to could have conflicting versions. Also this folder may not exist if you have some custom install scripts and you will have to ensure its created.

If you have the above setup then all you need to do is zip up the folder and it should be installable via Blender's addon installer.

Edit: Didn't realise six.py was your dependancy. In which case the above will work for your main addon. Assuming that you have your dependency stored in a modules folder the following sample code will add it to the sys path.

# Python dependencies are bundled inside the io_scene_nif/modules folder
_modules_path = os.path.join(os.path.dirname(__file__), "modules")
if not _modules_path in sys.path:
    sys.path.append(_modules_path)
del _modules_path
$\endgroup$

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.