# How to import from subdirectories?

I try to import from the file "boolean_2d_union" the function but fail to be able to get this right.

I have the following structure

add-on folder:
__init__.py
boolean_2d_union.py


Here is the script of my ini file.

   bl_info = {
"author": "Claas Kuhnen",
"version": (1, 0),
"blender": (2, 75, 0),
"description": "Pie Menus for Modeling and Object Properties",
"warning": "Beta - Concepy Study",
"category": "User Interface",
}
import math
import bmesh
import bpy, os
from bpy.props import IntProperty, FloatProperty, BoolProperty,EnumProperty,StringProperty
from mathutils import *

from boolean_2d_union import Boolean2DUnion

bl_idname = "pie.test"
bl_label = "Pie Test"

def draw(self, context):
layout = self.layout
#4
pie.operator("bpt.boolean_2d_union", text="Import Test")

def register():
bpy.utils.register_module(__name__)

wm = bpy.context.window_manager

km = wm.keyconfigs.addon.keymaps.new(name = 'Object Non-modal')
kmi = km.keymap_items.new('wm.call_menu_pie', "RIGHTMOUSE", "PRESS", shift=True, ctrl=True)
kmi.properties.name = "pie.test"

def unregister():
bpy.utils.unregister_module(__name__)

wm = bpy.context.window_manager

for kmi in km.keymap_items:
km.keymap_items.remove(kmi)

# clear the list

if __name__ == "__main__":
register()


I always get a syntax error:

Inside the file boolean_2d_union.py this is the following code:

class Boolean2DUnion(bpy.types.Operator):
bl_idname = "bpt.boolean_2d_union"
bl_label = "Boolean 2D Union"
bl_options = {'REGISTER', 'UNDO'}

• this snippet also has a problem with the addon_keymaps, but it's a different matter with a working example already Jan 18 '16 at 22:40

To learn more about importing from subdirs, you should be reading Stackoverflow and googling stuff like 'how to import from sub directories in Python : python-import-a-file-from-a-subdirectory , this is a general Python question and has many good answers and links.

I'll answer the Blender specifics (reduced version) of this code. no pie, no keymaps. We can test if a class/Operator was correctly imported and registered by using the spacebar menu and search for the operator's bl_label ( here Boolean 2D Union ) , and launch it from there.

That operator has a poll to test if at least two faces are selected before showing up in the menu or spacebar search. Here you can see we successfully imported that class and registered it.

### Importing from sub directories

I've prepared a small zip at this repostory : https://github.com/zeffii/some_test_addon , which you can Install from File.

addon_name     <-- avoid spaces in the add-on folder names
|
+ __init__.py
|
+ __init__.py   <---  (often empty) tells Python that this folder is a module.
+ boolean_2d_union.py


it should work this way, from the top level __init__.py

bl_info = {
"author": "----",
"version": (0, 1),
"blender": (2, 76, 0),
"category": "User Interface",
}

import bpy

def register():
# this line will throw an exception if you press F8 and don't
# have any classes defined in this __init__.py file, but usually
# this file has at least some classes either for a property collection
bpy.utils.register_module(__name__)

def unregister():
bpy.utils.unregister_module(__name__)


### Registration

When boolean_2d_union.py is imported, Boolean2DUnion is registered for you by bpy.utils.register_module(__name__).

There are many subtleties attached to multi-file addons regarding reload code and I think this is outside of the scope of your question, but further reading is suggested.

some insight

Does this work if I hit F8 (accidentally or intentionally). You might temporarily add some print events into __init__.py to get a sense of what's happening during that reload event, and get an idea of what has been loaded when.

bl_info = {
"author": "----",
"version": (0, 1),
"blender": (2, 76, 0),
"category": "User Interface",
}

import bpy

if 'boolean_2d_union' in locals():
print("don't need to reload an unchanged file")
else:
print('2')

def register():
print('3')
bpy.utils.register_module(__name__)
if 'bpt' in dir(bpy.ops):
print(dir(bpy.ops.bpt))  # will show   ['boolean_2d_union']
print('4')
print('5')

def unregister():
print('6')
bpy.utils.unregister_module(__name__)
`

Read the source of any of the multifile add-ons to see how they deal (or don't deal) with the F8 reload event. As a developer it's handy to have reload handling code so you don't have to keep closing/reopening Blender. Sometimes it is inevitable to have to close/reload, but get F8 working first and then if the reload didn't pick up your changes

• either fix the reload to take new files into account
• or restart
• Sometimes I think I do not know how to write the question right when searching in Google. Thank you for the explanation! Jan 20 '16 at 15:35
• As you start with Blender's Python API without prior Python experience I can imagine it's difficult to get a sense of how general some scripting questions are. Often the hardest part of finding solutions to obstacles is the lack of the correct terminology -- for this reason alone many people tend to focus more on learning Python after a while, then bpy API becomes less of an enigma, and you learn new ways to approach solutions. Jan 20 '16 at 17:31
• I think you are quite right. If you would have a moment, I have to question I would like to run by you. I do not know how to do this via a chat. The chat button seems only to appear if there is plenty of comments. Jan 20 '16 at 17:34
• you can go into the existing chat chat.stackexchange.com/rooms/34313/… ask away, i'll be back soon Jan 20 '16 at 17:37