Custom Node with Multi or Single Inputs

I have an issue with Custom Nodes where I have a Python node doing exactly what I want, how I want it, without any errors from the node itself. My issue: IN[0] and IN[1] can both be either a single string or a list of strings, and I want to create a custom node. Once in Custom Node form, if both are a list, as is possible, it outputs a list the size of IN[1] . By changing lacing to “longest,” I was able to get the output I expected, but as soon as I added an additional item to the list for IN[1], it grew the size of the output list to IN[1], instead of keeping the size of IN[0]. Currently, I have the input nodes for IN[0] and IN[1] as “name : string,” expecting that it would automatically recognize if it were a list or not. I do not want to constrain either input to exclusively acting as a list by using “string[.]…[.]” (ignore the periods inside the brackets, formatting of site turns plain brackets into a check box), but am unsure how to get the expected behavior.

The Python node inside the Custom Node is properly handling if either input is a list or not. I would prefer to constrain the custom node inputs to strings in some way due to the inability of Dynamo to raise an internal node’s error to the Custom Node in the actual script, but am open to using alternate means of defining the inputs if need be.

It sounds like you need to use Cross Product lacing. You could also write your python code to always perform its actions on two lists so that the output is always the same.

1 Like

I recommend setting the Python node up to expect a list, and using a method like ‘list or single item’ (my name my be off on that), as used by many of the nodes in the clockwork package.

I tried the cross product, but the custom node output from that was every item in one list operating on every item in the other list. And while the python script is set up to accept two separate lists, they will likely always be of differing lengths, so that either of the other two lacings (short/long) produce erroneous outputs. If I feed them into the python node on its own, it works fine and produces the expected output. It’s just frustrating (coming from a more Grasshopper heavy background) that Dynamo doesn’t have the capacity to automatically elevate things into a list if the single element is of the same type as the list input, but then the management of inputs is a little clunkier in Dynamo, too.

I suspect my issue lies in how I’m pulling the information into the custom nodes, and I’m just not as familiar with what’s possible with that part of Dynamo. If I make IN[1] input : string I run into the same issue as stated above. If I use input : string[]..[] then it will not accept a single element. Is there no way to combine those at the input such that the node will accept either a string or list of strings as the input for IN[1]?

Can you share your custom node? If not we will need a functional mockup as the time to code up what you may have for a current working method is likely longer than the time to solve it by a large multiplication factor.

This is definitely doable, just a matter of setting it up to work that way.

I intended for this to be a good regex search tool, but unfortunately I had forgotten a previous lesson I learned about the difficulty of getting a proper negative lookahead/lookbehind into Dynamo working as expected, and since that was the main purpose of the node, I had to drastically rework it and I’m unsure of if and where I might have a copy of it as was when I posted the question.
The intent behind it was to be able to take either a single string or a list of strings as IN[0], and then filter those strings such that only the ones that had a match from IN[1] would be passed through, sort of like a list remove item node. IN[1] was supposed to take in either a list or single string, depending on how advanced someone would be with regex. Ideally, if IN[0] was set to list: string in the input of the custom node, that it would run on a single or list of type string, which worked, but as soon as I tried to setup IN[1] to do the same thing, the lacing of the node wouldn’t operate as expected. The code in the python node would have looked something like this:

import re

input = IN[0] if isinstance(IN[0], list) else [IN[0]]
pattern = '|'.join(IN[1]) if isinstance(IN[1], list) else IN[1]
result = []

for i in input:
    if re.search(pattern, i):
        result.append(re.search(pattern, i))
    else:
        result.append('')

OUT = result
1 Like