Addon error module has no attribute 'register'

Hi,

I’m making a simple script and trying to add it on to Blender. It works fine when run through the editor, but when I try to activate it as an addon, I get an error.

This is my script:

import bpy


bl_info = \
    {
        "name" : "Shadeless Setter",
        "author" : "snuffysam",
        "version" : (1, 0, 0),
        "blender" : (2, 7, 8),
        "location" : "Properties > Render > Shading",
        "description" :
            "Sets all materials to shadeless",
        "warning" : "",
        "wiki_url" : "",
        "tracker_url" : "",
        "category" : "Material",
    }


class MaterialShadelessPanel(bpy.types.Panel) :
    bl_space_type = "VIEW_3D"
    bl_region_type = "TOOLS"
    bl_context = "objectmode"
    bl_category = "Tools"
    bl_label = "Make Shadeless"


    def draw(self, context) :
        TheCol = self.layout.column(align = True)
        TheCol.operator("mesh.make_shadeless", text = "Set All Shadeless")
        TheCol.operator("mesh.make_shaded", text = "Set All Shaded")
    #end draw


#end MaterialShadelessPanel


class MakeShadeless(bpy.types.Operator):
    bl_idname = "mesh.make_shadeless"
    bl_label = "Set All Shadeless"
    bl_options = {"UNDO"}
    def invoke(self, context, event):
        for m in bpy.data.materials:
            m.use_shadeless = True;
        return {"FINISHED"}
    #end invoke
#end MakeShadeless


class MakeShaded(bpy.types.Operator):
    bl_idname = "mesh.make_shaded"
    bl_label = "Set All Shaded"
    bl_options = {"UNDO"}
    def invoke(self, context, event):
        for m in bpy.data.materials:
            m.use_shadeless = False;
        return {"FINISHED"}
    #end invoke
#end MakeShaded


bpy.utils.register_class(MakeShaded)
bpy.utils.register_class(MakeShadeless)
bpy.utils.register_class(MaterialShadelessPanel)

And here is the error:

Traceback (most recent call last):
  File "/private/var/folders/1w/wr7s_4s15dzbf2cn8gs87_rc0000gq/T/AppTranslocation/1519C7E6-7D56-4AE9-90DC-2B244B3945E6/d/blender.app/Contents/MacOS/../Resources/2.78/scripts/modules/addon_utils.py", line 349, in enable
    mod.register()
AttributeError: module 'setAllShadeless' has no attribute 'register'

I am incredibly confused by this error message. “Has no attribute” implies that I called a function or variable that does not exist, right? But I don’t call a function or variable called “register” anywhere in the script. I call a function called “register_class”, but that should have nothing to do with this. And I certainly don’t call such a function with the line “mod.register()” as the error message seems to be claiming.

What’s going on? Am I completely misinterpreting the error message?

shouldnt addons be in the addons folder?

You mean, on this site?
If I posted this on the wrong forum, then sorry about that. I couldn’t find anywhere else in the support section that made sense. If that is the case, I’ll report my post, and ask for it to be moved by a moderator.

If you mean the script in blender… no? Addons can be added from any folder, right? Or is there something in my error message implying the addon was added incorrectly?

no, im not talking about the forums, the placement seems fine to me.

i dont know much about addons, but usually if something cant be found, then it could be in the wrong place. just thought it would be something to try.

I checked in my install path’s addons folder, and a copy of the script file was already there- completely up to date, so no surprises there.

When I used the “Install from File” feature in user preferences and selected the file that was already in the addons folder instead of the one in my documents folder, Blender gave an error, saying the source file was already in the add-on search path.

My guess is that the “Install from File” button is meant to take a file from somewhere else, and place it in the add-ons folder automatically. In which case, the add-on functionality did its job perfectly.

Whatever the problem was, I don’t think that’s it.

I should mention if we are dealing with filesystems going forward that I am running macOS Sierra.

You should be posting this in the “Python Support” or “Beginning Blender Code and Development” forums.

I am incredibly confused by this error message. “Has no attribute” implies that I called a function or variable that does not exist, right? But I don’t call a function or variable called “register” anywhere in the script. I call a function called “register_class”, but that should have nothing to do with this. And I certainly don’t call such a function with the line “mod.register()” as the error message seems to be claiming.

You’re not calling it, Blender is calling it. There’s a convention for addons where it is expected that your module has register/unregister functions to be called when the addon is enabled/disabled. You should be calling register_class in register(), not at the module level.

Take a look at the “Addon Add Object” Template:


bl_info = {
    "name": "New Object",
    "author": "Your Name Here",
    "version": (1, 0),
    "blender": (2, 75, 0),
    "location": "View3D > Add > Mesh > New Object",
    "description": "Adds a new Mesh Object",
    "warning": "",
    "wiki_url": "",
    "category": "Add Mesh",
    }


import bpy
from bpy.types import Operator
from bpy.props import FloatVectorProperty
from bpy_extras.object_utils import AddObjectHelper, object_data_add
from mathutils import Vector


def add_object(self, context):
    scale_x = self.scale.x
    scale_y = self.scale.y

    verts = [Vector((-1 * scale_x, 1 * scale_y, 0)),
             Vector((1 * scale_x, 1 * scale_y, 0)),
             Vector((1 * scale_x, -1 * scale_y, 0)),
             Vector((-1 * scale_x, -1 * scale_y, 0)),
            ]

    edges = []
    faces = [[0, 1, 2, 3]]

    mesh = bpy.data.meshes.new(name="New Object Mesh")
    mesh.from_pydata(verts, edges, faces)
    # useful for development when the mesh may be invalid.
    # mesh.validate(verbose=True)
    object_data_add(context, mesh, operator=self)


class OBJECT_OT_add_object(Operator, AddObjectHelper):
    """Create a new Mesh Object"""
    bl_idname = "mesh.add_object"
    bl_label = "Add Mesh Object"
    bl_options = {'REGISTER', 'UNDO'}

    scale = FloatVectorProperty(
            name="scale",
            default=(1.0, 1.0, 1.0),
            subtype='TRANSLATION',
            description="scaling",
            )

    def execute(self, context):

        add_object(self, context)

        return {'FINISHED'}


# Registration

def add_object_button(self, context):
    self.layout.operator(
        OBJECT_OT_add_object.bl_idname,
        text="Add Object",
        icon='PLUGIN')


# This allows you to right click on a button and link to the manual
def add_object_manual_map():
    url_manual_prefix = "http://wiki.blender.org/index.php/Doc:2.6/Manual/"
    url_manual_mapping = (
        ("bpy.ops.mesh.add_object", "Modeling/Objects"),
        )
    return url_manual_prefix, url_manual_mapping


def register():
    bpy.utils.register_class(OBJECT_OT_add_object)
    bpy.utils.register_manual_map(add_object_manual_map)
    bpy.types.INFO_MT_mesh_add.append(add_object_button)


def unregister():
    bpy.utils.unregister_class(OBJECT_OT_add_object)
    bpy.utils.unregister_manual_map(add_object_manual_map)
    bpy.types.INFO_MT_mesh_add.remove(add_object_button)


if __name__ == "__main__":
    register()

Note the ‘name == “main”’ guard at the bottom. This allows you to register the addon from the text editor, as well.

Ok, that was the issue. For some reason, nothing I looked at mentioned you had to put the registration calls in a register function.

Thanks for your help!