Skip to content

fix(select_nodes): log error when a previously selected node cannot be reselected - #331

Open
vincentullmann wants to merge 1 commit into
ynput:developfrom
straylondon:fix/select_nodes_on_deleted_nodes
Open

fix(select_nodes): log error when a previously selected node cannot be reselected#331
vincentullmann wants to merge 1 commit into
ynput:developfrom
straylondon:fix/select_nodes_on_deleted_nodes

Conversation

@vincentullmann

Copy link
Copy Markdown
Contributor

Changelog Description

avoid crashing if a node cannot be selected

Additional review information

as mentioned in #329, there can be cases where select_nodes may get called with a list of invalid nodes. For example when using a maintained_selection context manager and one of the previous selected nodes got deleted within the block.

Testing notes:

from ayon_nuke.api.lib import maintained_selection, reset_selection, select_nodes


nuke.scriptClear(force=True)

# create some test nodes
grade = nuke.createNode("Grade")
blur = nuke.createNode("Blur")
read = nuke.createNode("Read")
write = nuke.createNode("Write")

# preprare a selection
reset_selection()
select_nodes([grade, blur, read])  # select a subset

with maintained_selection():
    select_nodes([write])  # change the selection
    nuke.delete(blur)  # delete one of the selected nodes


selected_nodes = nuke.selectedNodes()
print("selected_nodes", selected_nodes)  # should be grade + read
assert len(selected_nodes) == 2
assert grade in selected_nodes
assert read in selected_nodes
assert write not in selected_nodes

@iLLiCiTiT

iLLiCiTiT commented Jul 20, 2026

Copy link
Copy Markdown
Member

I would do explicit ValueError capture and not log it out, just add comment why the error can happen, and move it to maintain selection as it probably should fail if happens with invalid nodes during other operations.


QUESTION: Could we do something like this?

@contextlib.contextmanager
def maintained_selection(exclude_nodes=None):
    """Maintain selection during context

    Maintain selection during context and unselect
    all nodes after context is done.

    Arguments:
        exclude_nodes (list[nuke.Node]): list of nodes to be unselected
                                         before context is done

    Example:
        >>> with maintained_selection():
        ...     node["selected"].setValue(True)
        >>> print(node["selected"].value())
        False
    """
    if exclude_nodes:
        for node in exclude_nodes:
            node["selected"].setValue(False)

    selected_nodes = nuke.selectedNodes()
    node_ids = set()
    for node in selected_nodes:
        node["selected"].setValue(False)
        node_ids.add(id(node))

    try:
        yield
    finally:
        # unselect all selection in case there is some
        reset_selection()

        # and select all previously selected nodes if were not removed
        for node in nuke.allNodes()
            if not node_ids:
                break
            if id(node) in node_ids:
                node_ids.discard(id(node))
                node["selected"].setValue(True)

Not sure how slower this might be...

@iLLiCiTiT iLLiCiTiT added the type: bug Something isn't working label Jul 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants