Developers of Add-Ons :: How do you find the API change for 2.8?

I understand we are not the one making the change, I am just watching how for the past versions, old add-ons would still work for generations of Blender and now this 2.8 API made enough changes that developers like you have to make a clean break, make two versions…or just plain forced to focus on 2.8 in the future.

In your opinion…was the changes justifiable ? Was it THAT necessary ?
Or do you think it was just change for the sake of change ?

I develop the FLIP Fluids addon, which is a tool for liquid simulations. The codebase for the addon is quite large, but I didn’t find it too difficult to update to Blender 2.80. My process was to try to load the addon into 2.80 and check the console errors, fix, and repeat.

Many of our users prefer 2.79 over 2.80, or are not able or ready to switch over to 2.80, so I knew we needed to support both versions of Blender. I also did not want to maintain two separate code bases as this would take more time to continue development. It ended up not being too difficult to support both 2.79 and 2.80 in a single code base.

Both versions are supported in a single code base by designing a module/file that handles all of the differences between 2.79 and 2.80.

For example, setting an object to be hidden within the viewport requires setting the object.hide parameter in 2.79, but 2.80 changes the API to name this parameter object.hide_viewport. This would be handled in the compatibility module with a function:

def is_blender_28():
    return bpy.app.version >= (2, 80, 0)

def set_object_hide_viewport(obj, display_bool):
    if is_blender_28():
        obj.hide_viewport = display_bool
    else:
        obj.hide = display_bool


def get_object_hide_viewport(obj):
    if is_blender_28():
        return obj.hide_viewport
    else:
        return obj.hide

The most difficult change to handle was that in Blender 2.80, operator properties need to be registered as Python annotations. This is syntax that is only available in 2.80 Python version (I think Python 3.6?), so using an if statement was not enough and would result in a syntax error in 2.79. The only solution I could think of to handle this change was to use python’s exec() function which interprets a string as Python code. If anyone has a better solution to this, I’d like to know.

Example:

def register_property(property_group, property_name_string, property_definition):
    if is_blender_28():
        # must use exec as the statement will result in invalid syntax
        # if script is run in Python versions that do nupport annotation syntax
        exec("property_group[property_name_string]: property_definition")
    else:
        property_group[property_name_string] = property_definition

I think that many of the changes made the API more clear/readable/consistent and were justified. Some of the changes are required to support new functionality or improve existing functionality/performance.

1 Like

Updating the average an addon with 300 to 500 lines of code takes 10 minutes. The first time.

For backwards compatibility you can set annotated props like this:

instead of having this on the class:

some_prop: bpy.props.BoolProperty()

you can do this:

ann = __annotations__ = dict()

ann['some_prop'] = bpy.props.BoolProperty()

The colon is just syntactic sugar for storing the prop in the dictionary __class__.__annotations__.

1 Like