Recently D2774 was committed to master which replaces list lookups with a hash.
This exposed naming collisions in add-ons, at first I thought it reasonable to rename classes to account for this however considering how many 3rd party addons there are, it's not practical.
This raises the question of why we have a global name-space for registered classes at all (currently in bpy.types) at all.
This tasks outlines changes to registration that avoid problems with add-on naming collisions, and keeps class registration manageable.
Note: none of these changes apply to 2.7x releases.
- Only built-in (non STRUCT_RUNTIME) types are added to bpy.types. Scripts that need to access registered classes can:
- For known types - access them from the module that defines them (as you would in any other kind of class in Python).
- For introspection/scanning for all types use bpy.types.*.__subclasses__() (needed for generating docs for eg).
- No checks for naming collisions are performed but...
- Each type has a unique identifier that can collide. (for example, two operators can't have the same bl_idname, two RenderEngine's ... UIList's etc)
- On collision with dynamic types with matching ID's. The new types will overwrite the old ones.
While it might be good to change this to prevent accidents, it's been working for years, it's handy for Python developers who want to re-run their scripts to try modified behavior, we could make this more strict so scripts don't accidentally clobber eachother's ID's, this would be better to handle separately.
Option 1) Exception for Compatibility (now in master)
From searching over add-ons I only found only one case of an add-on referencing it's own class via bpy.types
so thats easily resolved.
The issue is there are classes that are accessed to extend Blender, mainly menu's but also panels and headers.
We could update scripts to replace bpy.types.INFO_MT_file_export with bl_ui.space_info.INFO_MT_file_export,
but this is going to break a lot of scripts and exposes Blender's internal module layout.
Currently register-able types are:
I'm proposing [Menu, Panel, Header, UIList, Operator] continue to be accessible from bpy.types under their bl_idname (not Python class-name).
so scripts can use them to manipulate the interface.
We'll have to ensure bl_idname conventions are followed *_MT_*, *_PT_*, *_HT_*, *_UL_*, *_OT_*.
(this is going to break some scripts, but means using a global name-space won't collide with different types).
Option 2) Expose general types via bpy.types.*.find(...)
Instead of keeping some classes in bpy.types, we could use an function. eg:
bpy.types.INFO_MT_file_export would be accessed as bpy.types.Menu.find("INFO_MT_file_export")
This has the advantage that we don't need to be strict about naming, it also simplifies the code (not having to track public/private structs).
The main disadvantage is scripts will need to be updated, however it will be quite straightforward and nearly all scripts will need some updates for 2.8x anyway.
Update: submitted patch: D2816 (option 1)