Problem Testing Scripts from the Text Editor

Hi all,

As the title suggests, I’m having trouble testing the scripts I’m developing from the Text Editor window. I’m developing an exporter script as an Add-On which of course drops an entry into the File > Export menu. Everything works fine when I simply enable the addon from the preferences window, but as soon as I run the script from the Text Editor and open the File > Export menu, I get the following error in the console:

AttributeError: 'NoneType' object has no attribute 'path'

The offending line of code is

default_path = os.path.splitext(bpy.data.filepath)[0] + ".x"

which suggests that the os module has not been loaded despite the “import os” statement at the top of the script.

I’ve tried this on two computers with the same result. The first computer was running 32-bit Windows 7 with Blender 2.53 r31485, and the second was running 64-bit Windows Vista with Blender 2.53 r31482. I am out of town and away from my main dev computer which runs 32-bit Windows XP. I have never encountered this problem before, but I suspect it has to do with very recent changes in the way python types are registered (now implicitly, as opposed to explicitly with register() in the past).

Here, as everyone has a copy of the script I am developing (I wrote the DirectX Exporter Add-On script), you can all follow along.

First, make sure you are running Blender r31485 or higher (this is the highest at this writing).
Second, open Blender and change the default 3D View window into a Text Editor.
Third, load io_export_directx_x.py from the 2.53/scripts/addons folder into the Text Editor and press Run Script (or Alt+P).
Fourth, open the File menu at the top of the screen and just hover over the Export menu.

Doing the above steps gives me this.

I can’t imagine that I’m the only one that has this problem, but if this is how it’s gonna be from here on out, how am I supposed to test my scripts? The only solution I’ve been able to do is to edit the script, save it, restart Blender, and then enable the addon from the preferences window. There has to be a better way. How do all of you test your scripts?

Any help would be greatly appreciated. :slight_smile:

I’ve encountered the same problem while developing. It seems that a simple import statement at the top of a script won’t do anymore. You have to do a seperate import in each panel or operator class. Besides that you can’t reference “def” functions anymore either from within an operator class.

Here’s a fix that should make your script work again (replacing the current menu_func):

def menu_func(self, context):
    import os, bpy
    default_path = os.path.splitext(bpy.data.filepath)[0] + ".x"
    self.layout.operator("export.directx", text="DirectX (.x)").filepath = default_path

It would be nice though if we could get back to the old-fashioned way, before the automatic registering. Right now we save some lines and effort by not having to register classes ourselves, but it comes at a high cost. Perhaps someone else knows how to make things work easier?

in the templates the opereator simple calls a def … main form out a Class.

In an ‘own’ addon I can call (several) def’ s …!!!:confused:

PKHG: I’m probably doing something wrong then. Take a look at this:

import bpy

def myFunc():
    print("Calling def worked correctly")

class myPanel(bpy.types.Panel):
    bl_space_type = "PROPERTIES"
    bl_region_type = "WINDOW"
    bl_context = "object"
    bl_label = "My Panel"
    
    def draw(self, context):
        self.layout.operator("my_operator")

class myOperator(bpy.types.Operator):
    bl_label = "Test"
    bl_idname = "my_operator"
    bl_description = "Click to test"

    def invoke(self, context, event):
        myFunc()
        return{"FINISHED"}

It creates a button at the bottom of the Properties window (object tab). When you press it, it should print “Calling def worked correctly” to the console, but instead gives an error:
line21, TypeError: ‘NoneType’ object is not callable

Kira Vakaan: sorry for hijacking your thread, but this problem is probably based on the same issue you’re having trouble with.

this works:


import bpy
#look for: BGL copyright by PKHG , connectV_1_0.py
bl_addon_info = {
    'name': 'Crouch test',
    'author': 'PKHG for Crouch',
    'version': '0.1',
    'blender': (2, 5, 3),
    'location': 'oject panel',
    'description': '================ts of connected vertices and try to connect them!',
    'warning': 'test?', # ???used for warning icon and text in addons panel
    'wiki_url': 'http://petertregarg.host22.com/pmwiki/pmwiki.php/Api/ConnectTwoComponents',
    'tracker_url': 'http://petertregarg.host22.com/pmwiki/pmwiki.php/Api/ConnectTwoComponents',
    'category': 'Abracadabra'} #works ;-)



def myFunc():
    print("Calling def worked correctly")

class myPanel(bpy.types.Panel):
    bl_space_type = "PROPERTIES"
    bl_region_type = "WINDOW"
    bl_context = "object"
    bl_label = "My Panel"
    
    def draw(self, context):
        self.layout.operator("my_operator")

class myOperator(bpy.types.Operator):
    bl_label = "Test"
    bl_idname = "my_operator"
    bl_description = "Click to test"

    def invoke(self, context, event):
        myFunc()
        return{"FINISHED"}

def register():
    pass
#    km = bpy.context.manager.active_keyconfig.keymaps['3D View']
#    kmi = km.items.add('wm.call_menu', 'Q', 'PRESS')
#    kmi.properties.name = "VIEW3D_MT_pkhg_master_connect"

def unregister():
    pass
#    km = bpy.

if __name__ == "__main__":
    register()

It seem necessary to use it as addon :slight_smile:

@Crouch: Thanks for the response. :slight_smile:
It would seem that anything from the global namespace is lost to menu_func after it gets added to the Export list. Even after the menu item that calls the operator is properly added to the menu, the operator itself can’t find the container class (DirectXExporterSettings) I wrote and I get the same error:

TypeError: 'NoneType' object is not callable

And you haven’t hijacked it really. :stuck_out_tongue: I’m positive the problems come from the same source.

@PKHG: I’m not sure I understand what you’re saying. When you say

It seem necessary to use it as addon
do you mean it’s necessary to enable the script as an addon from the preferences menu? Because this is exactly what I am trying to avoid. The only way I could get my script to update properly was to restart Blender and re-enable it from the preferences. I’m looking for a way to make it all work just from the Text Editor like it did in the past.

Any more ideas anyone? Perhaps it is necessary to somehow import the entire script at menu_func and the operator?

hey guys, we also encountered both of these problems after automatic registration was introduced (forgetting the imports, ie the ‘NoneType’ error, and not being able to call global namespace defs). on the tube project we’re using a mix of linux and mac machines (and our own windows laptops) and we noticed that on certain python installs the problem didn’t occur.

Oddly enough it did occur with blender’s bundled python (which seemed to be a few revisions out of date even if you svn up the libs in your blender build folders). The solution that we found was to install the latest system python and then change the python path in the scons configuration to point to the system python. If you’re not building blender yourself then this workaround can be a bit annoying. I was writing all our add-ons to workaround by putting all the needed defs inside the class ie…

def new_function(self, …)
then calling self.new_function(…)

and importing bpy and whatever else inside each def.

another problem with automatic registration was with classes generated on the fly (ie by returning a type() from a def run at script main), whereby they get registered but are inaccessible from the operator menu. The workaround here was to unregister then register each generated class.

https://projects.blender.org/tracker/index.php?func=detail&aid=23346&group_id=9&atid=498

its already on the bug report list…

If you want a quick fix and don’t need debug libraries on Windows, you can download the Python 3.1.2 distribution and from that use the libraries and headers to link against. The Python modules you can also use from that. If you look for the dll, after installing it’s in Windows\System32

/Nathan

Ah, thanks guys. That’s very helpful. I suppose I’ll build a fixed Blender when I get back to my dev computer.

@Nathan: Do you think this will be fixed in the svn in the near future? I’m sure you have a mountain of other issues to attend to, but I just thought I’d ask. :slight_smile:

Yes, make it an addon and activate via Ctrl-Alt U (e.g.)

Because this is exactly what I am trying to avoid

I was looking for a different way. The script is already an addon, and I’m looking for a method that doesn’t involve restarting Blender every time I edit the script.

Anyhoo, it appears that I should be able to build a copy of Blender using a fresh Python install to solve the problem when I get home.