2.80 Cheat Sheet for updating add-ons


(nBurn) #1

This is a cheat sheet I originally made for myself to keep track of the Python API changes between 2.79 and 2.80. My goal was was to have a “CTRL F” quick reference I could use to avoid having to dig through API docs and add-on updates every time I wasn’t sure on what code changes were needed for 2.80.

Please read the note at the top related to the ‘???’ and ‘***’ markers throughout the cheat sheet before using this. A large part of this cheat sheet was pulled from git diff reports, so the syntax may not be correct in some cases.

See also

Blender 2.80 add-on update cheat sheet
??? = not verified or not correct in many cases, but may work
*** = verified to work in most or all cases

???  alpha needed
-mat.diffuse_color = (red_v, grn_v, blu_v)  # viewport color
+mat.diffuse_color = (red_v, grn_v, blu_v, alp)  # viewport color

???  viewnumpad
-col.operator("view3d.viewnumpad", text="View Camera", icon='CAMERA_DATA').type = 'CAMERA'
+col.operator("view3d.view_camera", text="View Camera", icon='CAMERA_DATA')

???  viewnumpad

???  get_rna
-properties = op.get_rna().bl_rna.properties.items()
+properties = op.get_rna_type().properties.items()

???  viewport_shade
-pie.prop(context.space_data, "viewport_shade", expand=True)
+pie.prop(context.space_data.shading, "type", expand=True)
-if context.space_data.viewport_shade == 'RENDERED':
+if context.space_data.shading.type == 'RENDERED':

???  TOOLS
-bl_region_type = "TOOLS"
+bl_region_type = "UI"

???  View
-bl_region_type = 'View'
-bl_category = 'Tools'
+bl_region_type = 'UI'
+bl_category = 'View'
RuntimeError: Error: Registering panel class: 'view3d.blah' has category 'View'

???  Lamp

???  lamps

***  select (only changed for objects)
-obj.select = False
AttributeError: 'Object' object has no attribute 'select'
possible regex:
find: (\.select\s*=\s*)(True|False)
repl: .select_set\(\2\)

***  select (only changed for objects)
-if o.select:
+if o.select_get():
-if not obj.select:
+if not obj.select_get():
-if o.select is True:
+if o.select_get() is True:
possible regex:
find: (\.select)(\s*)(is|==)(\s*)(True|False)
repl: .select_get\(\)(\2)(\3)(\4)(\5)

???  backdrop_x / backdrop_y
-context.space_data.backdrop_x = 0
-context.space_data.backdrop_y = 0
+context.space_data.backdrop_offset[0] = 0
+context.space_data.backdrop_offset[1] = 0

???  tessface
-bmesh.update_edit_mesh(object.data, tessface=True, destructive=True)
+bmesh.update_edit_mesh(object.data, loop_triangles=True, destructive=True)

???  active
-plane = context.scene.objects.active
+plane = context.active_object

???  active
-bpy.context.scene.objects.active = obj
+bpy.context.view_layer.objects.active = obj
AttributeError: bpy_prop_collection: attribute "active" not found
#bpy.context.view_layer.objects.active = bpy.data.objects['Light'] ??
#bpy.context.view_layer.objects.active = None ??
#bpy.context.active_object ?

???  object_bases
+obj = context.view_layer.objects.active  ??? 

???  frame_set subframe
-context.scene.frame_set(int(frame[1]), frame[0])
+context.scene.frame_set(int(frame[1]), subframe=frame[0])

???  prop text
-row.prop(self, "filter_auto_focus", "", icon='VIEWZOOM')
+row.prop(self, "filter_auto_focus", text="", icon='VIEWZOOM')

???  text (label)
-box.label("From curve")
+box.label(text="From curve")

???  show_x_ray
-col.prop(context.active_object, 'show_x_ray', toggle=False, text='X Ray')
+col.prop(context.active_object, 'show_in_front', toggle=False, text='X Ray')

???  popup_menu title
-context.window_manager.popup_menu(self.menu, "Icon Viewer")
+context.window_manager.popup_menu(self.menu, title="Icon Viewer")

???  operator text
-row.operator(IV_OT_panel_menu_call.bl_idname, "", icon='COLLAPSEMENU')
+row.operator(IV_OT_panel_menu_call.bl_idname, text="", icon='COLLAPSEMENU')

***  operator text
-row.operator("wm.url_open", "Google", icon='SOLO_ON'
-            ).url = "https://www.google.com"
+row.operator("wm.url_open", text="Google", icon='SOLO_ON'
+            ).url = "https://www.google.com"

***  label text
TypeError: UILayout.label(): required parameter "text" to be a keyword argument!

***  prop text
-row.prop(self, "ctrl", "Ctrl", toggle=True)
+row.prop(self, "ctrl", text="Ctrl", toggle=True)

***  prop text
-col.prop(self.overlay, "alignment", "")
+col.prop(self.overlay, "alignment", text="")

???  hide

???  Group

???  groups

???  dupli_group

???  link
+coll = context.view_layer.active_layer_collection.collection

???  link
AttributeError: 'bpy_prop_collection' object has no attribute 'link'

???  unlink

???  draw_type
-bpy.context.object.data.draw_type = 'BBONE'
+bpy.context.object.data.display_type = 'BBONE'

???  draw_size
-bpy.data.cameras[cam_data_name].draw_size = 1.0
+bpy.data.cameras[cam_data_name].display_size = 1.0

???  uv_textures name

???  transform_apply location rotation scale
-bpy.ops.object.transform_apply(rotation=True, scale=True)
+bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)

???  ops _add layers
-bpy.ops.mesh.primitive_cube_add(view_align=False, enter_editmode=False, 
-    location=(0.0, 0.0, 0.0), rotation=(0.0, 0.0, 0.0), layers=current_layers)
+bpy.ops.mesh.primitive_cube_add(view_align=False, enter_editmode=False, 
+    location=(0.0, 0.0, 0.0), rotation=(0.0, 0.0, 0.0))

???  space_data orientation
-orientation = bpy.context.space_data.transform_orientation
-custom = bpy.context.space_data.current_orientation
+orient_slot = bpy.context.scene.transform_orientation_slots[0]
+custom = orient_slot.custom_orientation

???  constraint_orientation
-bpy.ops.transform.resize('INVOKE_DEFAULT', constraint_axis = axis, constraint_orientation = 'GLOBAL')
+bpy.ops.transform.resize('INVOKE_DEFAULT', constraint_axis = axis, orient_type = 'GLOBAL')

***  user_preferences
-addons = bpy.context.user_preferences.addons
+addons = bpy.context.preferences.addons

???  user_preferences
"system.use_weight_color_range", "view.use_weight_color_range"
"system.weight_color_range", "view.weight_color_range"
"system.color_picker_type", "view.color_picker_type"
"view.use_quit_dialog", "view.use_save_prompt"
"view.use_mouse_depth_navigate", "input.use_mouse_depth_navigate"
"view.use_mouse_depth_cursor", "input.use_mouse_depth_cursor"
"view.use_cursor_lock_adjust", "input.use_cursor_lock_adjust"
"view.use_camera_lock_parent", "input.use_camera_lock_parent"
"view.use_zoom_to_mouse", "input.use_zoom_to_mouse"
"view.use_auto_perspective", "input.use_auto_perspective"
"view.use_rotate_around_active", "input.use_rotate_around_active"
"system.use_text_antialiasing", "view.use_text_antialiasing"
"system.text_hinting", "view.text_hinting"
"system.font_path_ui", "view.font_path_ui"
"system.font_path_ui_mono", "view.font_path_ui_mono"
"system.use_international_fonts", "view.use_international_fonts"
"system.language", "view.language"
"system.use_translate_tooltips", "view.use_translate_tooltips"
"system.use_translate_interface", "view.use_translate_interface"
"system.use_translate_new_dataname", "view.use_translate_new_dataname"
"input.show_ui_keyconfig", "keymap.show_ui_keyconfig"
"input.active_keyconfig", "keymap.active_keyconfig"
"system.author", "filepaths.author"
"system.use_scripts_auto_execute", "filepaths.use_scripts_auto_execute"
"system.use_tabs_as_spaces", "filepaths.use_tabs_as_spaces"

???  wm.addon_enable

???  wm.addon_userpref_show

???  select_mouse
-mouse_right = context.user_preferences.inputs.select_mouse
+wm = context.window_manager
+keyconfig = wm.keyconfigs.active
+mouse_right = getattr(keyconfig.preferences, "select_mouse", "LEFT")

***  percentage
-split = row.split(percentage=0.10, align=True)
+split = row.split(factor=0.10, align=True)

***  row align
-row = col.row(True)
+row = col.row(align=True)
TypeError: UILayout.row(): required parameter "align" to be a keyword argument!

***  scene_update_pre

***  scene_update_post

???  use_occlude_geometry
AttributeError: 'SpaceView3D' object has no attribute 'use_occlude_geometry'

???  Matrix Multiplication
-normal = rotation * mathutils.Vector((0.0, 0.0, 1.0))
+normal = rotation @ mathutils.Vector((0.0, 0.0, 1.0))

???  viewport_shade
-self.snap_face = context.space_data.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'}
-self.sctx.set_snap_mode(True, True, self.snap_face)
+shading = context.space_data.shading
+self.snap_face = not (snap_edge_and_vert and
+                     (shading.show_xray or shading.type == 'WIREFRAME'))

***  Property (annotations, class def only, not in methods)
-operator = bpy.props.BoolProperty(name="Operator Name", default=True)
+operator: bpy.props.BoolProperty(name="Operator Name", default=True)
"BoolProperty", "CollectionProperty", "EnumProperty", 
"FloatVectorProperty", "FloatProperty", "IntProperty", 

???  time_step
-self.timer = wm.event_timer_add(0.05, bpy.context.window)
+self.timer = wm.event_timer_add(time_step=0.05, window=bpy.context.window)

???  subframe
-context.scene.frame_set(10, 0.25)
+context.scene.frame_set(10, subframe=0.25)

???  INFO_MT_
-box.menu("INFO_MT_file_import", icon='IMPORT')
+box.menu("TOPBAR_MT_file_import", icon='IMPORT')

???  _specials
-scene = context.scene.mat_specials
+scene = context.scene.mat_context_menu

???  tweak_threshold
-tt = context.preferences.inputs.tweak_threshold
+tt = context.preferences.inputs.drag_threshold
rna_uiItemR: property not found: PreferencesInput.tweak_threshold

???  cursor_location
-endvertex = bpy.context.scene.cursor_location
+endvertex = bpy.context.scene.cursor.location

???  register_module
+for cls in classes:
+    bpy.utils.register_class(cls)

???  icon
-row.label(text="Use Properties panel", icon='SMOOTH')
+row.label(text="Use Properties panel", icon='SHADING_RENDERED')
"EDIT", ??
"GAME", ??
"RADIO", ??
"DOTSUP", ??
"LINK",  #  (maybe use DOT, LAYER_ACTIVE or LAYER_USED)
"INLINK", ??
"GO_LEFT", ??
"MAN_ROT", ??
"BBOX", ??
"ALIGN", ??
"SPACE2", ??
"ROTATE", ??
"SAVE_AS", ??
"ORTHO", ??
"OOPS", ??

Updating Built In Addons to Blender 2.8
List of addons that work with 2.8
Import/Export Script
(nBurn) #2

Placeholder post.

(nBurn) #3

Placeholder post 2

(Meta-Androcto) #4

Thanks very much, these are very helpful

(Jason van Gumster) pinned #6

(nBurn) #7

The first 3 posts in this thread are now editable, thanks mods!

Make sure to do a search before doing any edits to avoid adding something that is already there.

(fin.eskimo) #8

Great idea…

(Hiisi) #9
  1. 2.8 API introduces new way of class registration. Instead of module registration now one has to register classes directly.
  2. The redesigned interfaces has some window’ names changed. For instance, INFO_MT_file_import has became TOPBAR_MT_file_import.
  3. bpy.context.user_preferences -> bpy.context.preferences
  4. bpy.ops.wm.addon_enable -> bpy.ops.preferences.addon_enable
  5. bpy.context.scene.objects.active = obj now became bpy.context.view_layer.objects.active = obj
  6. obj.select = True now became obj.select_set(state = True)

(nBurn) #10

Thanks, didn’t have this one in the list.

(Blended_Blue) #11

Nice little list you have created, thanks for posting it!

Recently I have been updating my own legacy code while attempting to maintain support for both versions in a single file.

I have declared LEGACY_MODE as the switch that toggles between the two command sets based on the version tuple provided by bpy.app.version.


LEGACY_MODE = bpy.app.version < (2, 80, 0) #Switch based on version for Blender 2.8+ or legacy support.

o = byp.data.object[0]
    o.hide = False #unhide object using legacy commands
    o.hide_viewport = 0 #unhide object using modern commands

Anyways, just felt like sharing something :slight_smile:

(kkar) #12

I do that in a similar way too, but it is very tedious :frowning: I now maintain a huge module just for that.

This is especially a big issue with annotations inside classes. I am for now pretending that I do not get those messages.

(nBurn) #13

The World Blender Meetup had a presentation dedicated to this as well. It looked interesting, but I haven’t tried this with my own add-ons. Just getting them running in 2.80 is has been enough of job, maybe once the release candidate is out I might give this a try.

(kkar) #14

Thanks for the link. Useful presentation. He has a dedicated page about it.

(Blended_Blue) #15

Looks like he and I had a very similar approach! I remember theDuckCow from some years ago, back when I programmed Blender/Python as a piano playing robot. He gave compliments to the project.

Thanks for the link!