Context hidden states - Can't make sense of them, working Python scripts either stop working or crash when I try adding UIs for them

Hello there. I’m working on some Python addons for Blender, but I’m having a lot of problem understanding the hidden states. I have working scripts but whenever I try to add UIs for them, simply to run the functions, they stop working. I’ve been struggling with that for a week and have asked a number of times on BlenderArtists and IRC (both #blender and #blenderpython) but nobody was able to help so far, so someone told me I should ask here and try to reach “Campbell Barton”. I’m not sure if that’s fine because I guess it’s probably something really stupid I’m doing it’s just not a well documented behavior, but here we go:
From here:

import bpy

class SimpleOperator(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.simple_operator"
    bl_label = "Simple Object Operator"

    @classmethod
    def poll(cls, context):
        return context.active_object is not None

    def execute(self, context):
        context = bpy.context
        scene = context.scene

        selected_objs = context.selected_objects[:] #copy just in case

        print("\nstarting")
        for obj in selected_objs:
            bpy.ops.object.select_all(action='DESELECT')
            obj.select = True
            scene.objects.active = obj
            print("current",obj.name,"selected",context.selected_objects[0].name,"active",scene.objects.active.name)
            bpy.ops.object.shade_smooth()
            bpy.ops.object.modifier_add(type='TRIANGULATE')
        return {"FINISHED"}


class LayoutDemoPanel(bpy.types.Panel):
    """Creates a Panel in the scene context of the properties editor"""
    bl_label = "Layout Demo"
    bl_idname = "SCENE_PT_layout"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"

    def draw(self, context):
        self.layout.operator("object.simple_operator")


def register():
    bpy.utils.register_class(SimpleOperator)
    bpy.utils.register_class(LayoutDemoPanel)


def unregister():
    bpy.utils.unregister_class(SimpleOperator)
    bpy.utils.unregister_class(LayoutDemoPanel)

if __name__ == "__main__":
    register()

bpy.ops.object.shade_smooth() works while bpy.ops.object.modifier_add() doesn’t do anything. I recently figured that the ‘scene’ context works almost as the context (/hidden state) the bpy.ops.text.run_script() uses, but it’s not exactly the same:
From here: /t/script-crashes-blender-is-there-a-way-to-somehow-bypass-the-hidden-states-set-by-ui-widgets/1117157:

import bpy

def selectAndActivate(obj, select_children = False):
    bpy.ops.object.select_all(action='DESELECT')
    obj.select = True
    bpy.context.scene.objects.active = obj
    if select_children:
        bpy.ops.object.select_grouped(extend=True, type='CHILDREN_RECURSIVE')
        
def TestObj():
    selectAndActivate(bpy.context.selected_objects[0])
    bpy.ops.mesh.customdata_custom_splitnormals_clear()
    
class TestItOp(bpy.types.Operator):
    bl_idname = "object.test_selection"
    bl_label = "Test Selection"

    @classmethod
    def poll(cls, context):
        return True

    def execute(self, context):
        TestObj()
        return {'FINISHED'}
        
class TestPanel(bpy.types.Panel):
    bl_label = "Test It!"
    bl_idname = "TEST_it_panel"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "scene"

    def draw(self, context):
        layout = self.layout
        layout.row().operator("object.test_selection")
        
if __name__ == "__main__":
    bpy.utils.register_class(TestItOp)
    bpy.utils.register_class(TestPanel)

(Needs to select something e.g. default cube)
Blender simply crashes and there’s no debug info other than an access exception error.
Please note that both scripts run fine in a plain python file, but it’s not convenient to switch scripts in the text editor, so I just want to add some UI buttons for them, but no matter what I do that changes some hidden state so the scripts either stop working or simply crash Blender. I’m a total noob but those scripts seem legit to me. What am I doing wrong?
I am using the other API and it works fine, for example custom object properties and such. I’m only having problem running the logic.
I’m using latest 2.79 on Windows 7 (both 64-bit).

Thank you in advance.

PS: This forum says errors with the message: new users can have 2 links in a post when I try to submit this, but I have only 2 links :confused:

Create your panel right in the 3d view instead of PROPERTIES WINDOW.
Use VIEW_3D and either UI or TOOLS so your operators run in the right context out of the box.

Thank you for your reply. The problem is I would like to call an external tool that process the geometry and creates some other objects, and then I have to modify those objects in Blender. There are some settings for the tool and I think the best place for these settings in my opinion is the ‘object’ tab in the properties window, so you have the settings there and you can adjust and click a button to process the object. That way both the settings and the action button are on the same place and you don’t need the 3D tools panel open to perform the actions.