Compositor node type-string inconsistency and problematic API changes #35336

Closed
opened 2013-05-13 10:29:02 +02:00 by Tamir Lousky · 6 comments

%%%--- Operating System, Graphics card ---
Tested on:
Ubuntu 13 with Nvidia GeForce 9600GT
Windows7 with AMD Readon HD 6800

- Blender version with error, and version that worked ---

Bug on 2.67
Works on 2.66

- Short description of error ---

There have been API changes in the type property of compositor nodes.
For instance, what used to be 'R_LAYERS' is now 'CompositorNodeRLayers'.

So using the old type string fails with an obscure error:
Traceback (most recent call last):

File "<blender_console>", line 1, in <module>

RuntimeError: Error: Node type R_LAYERS undefined

That by itself isn't a bug I guess, though it breaks backward compatibility with scripts such as my render layer and pass file saver:
https://github.com/Tlousky/production_scripts/blob/master/save_all_renderlayers_and_passes.py

But when you check the type of an existing render layers node, you get back the old string, instead of the new one:
This one is a bug I assume, as it doesn't enable you to check the new type string of a node you created manually.

tree.nodes[0]

bpy.data...nodes["Render Layers"]

tree.nodes- [x].type

'R_LAYERS'

There's also no direct way to see all the new type strings. These should probably be documented here:
http://www.blender.org/documentation/blender_python_api_2_67_release/bpy.types.Node.html

The API also doesn't inform on the new types in any way, when you use autocomplete to create a new node:

tree.nodes.new(

autocomplete with ctrl + space only outputs this:

new()
Nodes.new(type)
Add a node to this node tree

It would be useful if both the autocomplete and the error of using a wrong type string will output a list of the existing types.

It would also be nice to have some backward compatibility. I assume the new changes are because of the new possibilities brought by python nodes, but maybe some way around this is possible.

- Steps for others to reproduce the error (preferably based on attached .blend file) ---
  1. Open a node editor and a python console and tick "use_nodes":

  2. Reference the node tree in the console with:
    tree = bpy.context.scene.node_tree

  3. Try to create a new render layers node with:
    tree.nodes.new('R_LAYERS')
    or:
    tree.nodes.new(type='R_LAYERS')

  4. Manually create a new render layers input node through the node editor.

  5. Access it in the python console through the tree object, and print its type:
    tree.nodes[use_node_name_or_index].type

Thank you!%%%

%%%--- Operating System, Graphics card --- Tested on: Ubuntu 13 with Nvidia GeForce 9600GT Windows7 with AMD Readon HD 6800 - Blender version with error, and version that worked --- Bug on 2.67 Works on 2.66 - Short description of error --- There have been API changes in the type property of compositor nodes. For instance, what used to be 'R_LAYERS' is now 'CompositorNodeRLayers'. So using the old type string fails with an obscure error: Traceback (most recent call last): ``` File "<blender_console>", line 1, in <module> ``` RuntimeError: Error: Node type R_LAYERS undefined That by itself isn't a bug I guess, though it breaks backward compatibility with scripts such as my render layer and pass file saver: https://github.com/Tlousky/production_scripts/blob/master/save_all_renderlayers_and_passes.py But when you check the type of an existing render layers node, you get back the old string, instead of the new one: This one is a bug I assume, as it doesn't enable you to check the new type string of a node you created manually. >>> tree.nodes[0] bpy.data...nodes["Render Layers"] >>> tree.nodes- [x].type 'R_LAYERS' There's also no direct way to see all the new type strings. These should probably be documented here: http://www.blender.org/documentation/blender_python_api_2_67_release/bpy.types.Node.html The API also doesn't inform on the new types in any way, when you use autocomplete to create a new node: >>> tree.nodes.new( # autocomplete with ctrl + space only outputs this: new() Nodes.new(type) Add a node to this node tree It would be useful if both the autocomplete and the error of using a wrong type string will output a list of the existing types. It would also be nice to have some backward compatibility. I assume the new changes are because of the new possibilities brought by python nodes, but maybe some way around this is possible. - Steps for others to reproduce the error (preferably based on attached .blend file) --- 1. Open a node editor and a python console and tick "use_nodes": 2. Reference the node tree in the console with: tree = bpy.context.scene.node_tree 3. Try to create a new render layers node with: tree.nodes.new('R_LAYERS') or: tree.nodes.new(type='R_LAYERS') 4. Manually create a new render layers input node through the node editor. 5. Access it in the python console through the tree object, and print its type: tree.nodes[use_node_name_or_index].type Thank you!%%%
Author

Changed status to: 'Open'

Changed status to: 'Open'
Author

%%%I amended my addon
https://github.com/Tlousky/production_scripts/blob/master/save_all_renderlayers_and_passes.py

It now supports both blender 2.67 and 2.66, so it won't be helpful to test it in case you were planning to.
But the changes in this script reflect the API changes and the problem they could represent.%%%

%%%I amended my addon https://github.com/Tlousky/production_scripts/blob/master/save_all_renderlayers_and_passes.py It now supports both blender 2.67 and 2.66, so it won't be helpful to test it in case you were planning to. But the changes in this script reflect the API changes and the problem they could represent.%%%
Member

%%%This is indeed an API change: the nodes.new() function now expects the node.bl_idname string, which is a generic type identifier like those used for other registerable blender types (operators, menu, etc.). The "type" property otoh is an enum identifier based on the old hardcoded integer identifiers, which are not suitable for dynamically regsitering nodes. It is basically deprecated now, it only still exists for the purpose of keeping existing scripts working and should be avoided (so replace nodes.new(somenode.type) with nodes.new(somenode.bl_idname)).

A possible solution for backward compatibility could be to use the old enum "type" property as a fallback: if the given bl_idname string is not found it could try the enum identifier instead. But this could lead to unforeseen problems with ambiguous names too and just pollutes the API further, so i'd rather not do that unless it's absolutely necessary.

Displaying a set of possible choices with autocomplete is also difficult. For enums it only works with fixed enum items lists, so using a dynamically generated enum won't be any help (the enum generator callback depends on context, which generally doesn't match for plain api calls).%%%

%%%This is indeed an API change: the nodes.new() function now expects the node.bl_idname string, which is a generic type identifier like those used for other registerable blender types (operators, menu, etc.). The "type" property otoh is an enum identifier based on the old hardcoded integer identifiers, which are not suitable for dynamically regsitering nodes. It is basically deprecated now, it only still exists for the purpose of keeping existing scripts working and should be avoided (so replace nodes.new(somenode.type) with nodes.new(somenode.bl_idname)). A possible solution for backward compatibility could be to use the old enum "type" property as a fallback: if the given bl_idname string is not found it could try the enum identifier instead. But this could lead to unforeseen problems with ambiguous names too and just pollutes the API further, so i'd rather not do that unless it's absolutely necessary. Displaying a set of possible choices with autocomplete is also difficult. For enums it only works with fixed enum items lists, so using a dynamically generated enum won't be any help (the enum generator callback depends on context, which generally doesn't match for plain api calls).%%%
Author

%%%Thanks for your reply, Lukas.

The important thing for me was to have a consistent way to know what string to use to create a node through the nodes.new() function.
Since checking a node's bl_idname does that, it solves my problem, at least for the next versions (for backward compatibility, I just check the
version and use a string to match).

The reasons for the change make a lot of sense.
Your explanation, or the essence of it, should probably be documented somewhere (nodes.new() docs probably?).

Cheers%%%

%%%Thanks for your reply, Lukas. The important thing for me was to have a consistent way to know what string to use to create a node through the nodes.new() function. Since checking a node's bl_idname does that, it solves my problem, at least for the next versions (for backward compatibility, I just check the version and use a string to match). The reasons for the change make a lot of sense. Your explanation, or the essence of it, should probably be documented somewhere (nodes.new() docs probably?). Cheers%%%
Member

%%%Added a hint in the doc string for nodetree.nodes.new() now, consider this fixed.%%%

%%%Added a hint in the doc string for nodetree.nodes.new() now, consider this fixed.%%%
Member

Changed status from 'Open' to: 'Resolved'

Changed status from 'Open' to: 'Resolved'
Sign in to join this conversation.
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender-addons#35336
No description provided.