funcnodes-core 0.2.0__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/PKG-INFO +1 -1
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/__init__.py +1 -1
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/config.py +1 -1
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/io.py +18 -10
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/lib/__init__.py +2 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/lib/lib.py +29 -14
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/node.py +2 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/nodemaker.py +22 -7
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/pyproject.toml +1 -1
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/LICENSE +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/README.md +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/_logging.py +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/_setup.py +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/data.py +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/decorator/__init__.py +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/eventmanager.py +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/exceptions.py +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/graph.py +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/lib/libfinder.py +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/lib/libparser.py +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/nodespace.py +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/triggerstack.py +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/utils/__init__.py +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/utils/data.py +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/utils/functions.py +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/utils/nodeutils.py +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/utils/plugins.py +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/utils/plugins_types.py +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/utils/saving.py +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/utils/serialization.py +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/utils/special_types.py +0 -0
- {funcnodes_core-0.2.0 → funcnodes_core-0.2.2}/funcnodes_core/utils/wrapper.py +0 -0
|
@@ -122,6 +122,9 @@ class NoValueType:
|
|
|
122
122
|
def __str__(self):
|
|
123
123
|
return "<NoValue>"
|
|
124
124
|
|
|
125
|
+
def __reduce__(self):
|
|
126
|
+
return (NoValueType, ())
|
|
127
|
+
|
|
125
128
|
|
|
126
129
|
NoValue: NoValueType = NoValueType()
|
|
127
130
|
|
|
@@ -494,10 +497,14 @@ class NodeIO(EventEmitterMixin, Generic[NodeIOType]):
|
|
|
494
497
|
return None
|
|
495
498
|
return f"{self.node.uuid}__{self.uuid}"
|
|
496
499
|
|
|
500
|
+
def get_value(self) -> NodeIOType | NoValueType:
|
|
501
|
+
"""Gets the current value of the NodeIO."""
|
|
502
|
+
return self._value
|
|
503
|
+
|
|
497
504
|
@property
|
|
498
505
|
def value(self) -> NodeIOType | NoValueType:
|
|
499
506
|
"""Gets the current value of the NodeIO."""
|
|
500
|
-
return self.
|
|
507
|
+
return self.get_value()
|
|
501
508
|
|
|
502
509
|
@value.setter
|
|
503
510
|
def value(self, value: NodeIOType) -> None:
|
|
@@ -570,6 +577,9 @@ class NodeIO(EventEmitterMixin, Generic[NodeIOType]):
|
|
|
570
577
|
def __gt__(self, other):
|
|
571
578
|
self.connect(other)
|
|
572
579
|
|
|
580
|
+
def __lt__(self, value):
|
|
581
|
+
return self.set_value(value)
|
|
582
|
+
|
|
573
583
|
@emit_before()
|
|
574
584
|
@emit_after()
|
|
575
585
|
def disconnect(self, other: Optional[NodeIO] = None):
|
|
@@ -795,15 +805,9 @@ class NodeInput(NodeIO, Generic[NodeIOType]):
|
|
|
795
805
|
self._forwards: weakref.WeakSet[NodeInput] = weakref.WeakSet()
|
|
796
806
|
self._forwards_from: weakref.WeakSet[NodeInput] = weakref.WeakSet()
|
|
797
807
|
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
return self._value if self._value is not NoValue else self._default
|
|
802
|
-
|
|
803
|
-
@value.setter
|
|
804
|
-
def value(self, value: NodeIOType) -> None:
|
|
805
|
-
"""Sets the value of the NodeIO."""
|
|
806
|
-
self.set_value(value)
|
|
808
|
+
def get_value(self):
|
|
809
|
+
v = super().get_value()
|
|
810
|
+
return v if v is not NoValue else self._default
|
|
807
811
|
|
|
808
812
|
def full_serialize(self, with_value=False) -> FullNodeInputJSON:
|
|
809
813
|
return FullNodeInputJSON(
|
|
@@ -1007,6 +1011,7 @@ class NodeInput(NodeIO, Generic[NodeIOType]):
|
|
|
1007
1011
|
raise MultipleConnectionsError("Can only forward to unconnected inputs")
|
|
1008
1012
|
|
|
1009
1013
|
self._forwards_from.add(other)
|
|
1014
|
+
self.set_default(NoValue) # set default to class default upon connection
|
|
1010
1015
|
|
|
1011
1016
|
return other.forward(self, replace=replace)
|
|
1012
1017
|
|
|
@@ -1068,11 +1073,14 @@ class NodeInput(NodeIO, Generic[NodeIOType]):
|
|
|
1068
1073
|
def connect(self, other, replace=False):
|
|
1069
1074
|
if isinstance(other, NodeInput):
|
|
1070
1075
|
return self.forward(other, replace=replace)
|
|
1076
|
+
self.set_default(NoValue) # set default to class default upon connection
|
|
1071
1077
|
con = super().connect(other, replace)
|
|
1072
1078
|
if con and self._forwards_from:
|
|
1073
1079
|
for f in list(self._forwards_from):
|
|
1074
1080
|
self.unforward_from(f)
|
|
1075
1081
|
|
|
1082
|
+
return con
|
|
1083
|
+
|
|
1076
1084
|
|
|
1077
1085
|
class NodeOutput(NodeIO):
|
|
1078
1086
|
"""
|
|
@@ -8,6 +8,7 @@ from .lib import (
|
|
|
8
8
|
flatten_shelf,
|
|
9
9
|
flatten_shelves,
|
|
10
10
|
check_shelf,
|
|
11
|
+
ShelfReferenceLost,
|
|
11
12
|
)
|
|
12
13
|
|
|
13
14
|
from .libparser import module_to_shelf
|
|
@@ -28,4 +29,5 @@ __all__ = [
|
|
|
28
29
|
"flatten_shelf",
|
|
29
30
|
"flatten_shelves",
|
|
30
31
|
"check_shelf",
|
|
32
|
+
"ShelfReferenceLost",
|
|
31
33
|
]
|
|
@@ -70,6 +70,10 @@ class Shelf:
|
|
|
70
70
|
self.subshelves.append(shelf)
|
|
71
71
|
|
|
72
72
|
|
|
73
|
+
class ShelfReferenceLost(ReferenceError):
|
|
74
|
+
pass
|
|
75
|
+
|
|
76
|
+
|
|
73
77
|
@dataclass
|
|
74
78
|
class _InnerShelf:
|
|
75
79
|
nodes_ref: List[ReferenceType[Type[Node]]]
|
|
@@ -107,7 +111,11 @@ class _InnerShelf:
|
|
|
107
111
|
def _check_shelf(self):
|
|
108
112
|
if self.shelf is not None:
|
|
109
113
|
if self.shelf() is None:
|
|
110
|
-
raise
|
|
114
|
+
raise ShelfReferenceLost(
|
|
115
|
+
"Shelf reference is lost\n"
|
|
116
|
+
"This could happen if the shelf is not permanently stored e.g. if its added to the library "
|
|
117
|
+
"as a dictionary and the returned Shelf object is not referenced"
|
|
118
|
+
)
|
|
111
119
|
|
|
112
120
|
def to_shelf(self) -> Shelf:
|
|
113
121
|
self._check_shelf()
|
|
@@ -122,18 +130,23 @@ class _InnerShelf:
|
|
|
122
130
|
)
|
|
123
131
|
|
|
124
132
|
def add_node(self, node: Type[Node]):
|
|
125
|
-
self.
|
|
126
|
-
if self.shelf is None:
|
|
127
|
-
self.nodes_ref.append(ref(node))
|
|
128
|
-
else:
|
|
129
|
-
self.shelf().add_node(node)
|
|
133
|
+
self.nodes_ref.append(ref(node))
|
|
130
134
|
|
|
131
135
|
def add_subshelf(self, shelf: Shelf):
|
|
132
136
|
self._check_shelf()
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
+
self.inner_subshelves.append(_InnerShelf.from_shelf(shelf))
|
|
138
|
+
|
|
139
|
+
def update(self, shelf: Shelf):
|
|
140
|
+
for node in shelf.nodes:
|
|
141
|
+
if node not in self.nodes:
|
|
142
|
+
self.add_node(node)
|
|
143
|
+
|
|
144
|
+
subshelves = {subshelf.name: subshelf for subshelf in self.inner_subshelves}
|
|
145
|
+
for subshelf in shelf.subshelves:
|
|
146
|
+
if subshelf.name in subshelves:
|
|
147
|
+
subshelves[subshelf.name].update(subshelf)
|
|
148
|
+
else:
|
|
149
|
+
self.add_subshelf(subshelf)
|
|
137
150
|
|
|
138
151
|
|
|
139
152
|
class SerializedShelf(TypedDict):
|
|
@@ -264,10 +277,12 @@ class Library(EventEmitterMixin):
|
|
|
264
277
|
def add_shelf(self, shelf: Shelf):
|
|
265
278
|
shelf = check_shelf(shelf)
|
|
266
279
|
shelf_dict = {s.name: s for s in self._shelves}
|
|
267
|
-
if shelf.name in shelf_dict
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
280
|
+
if shelf.name in shelf_dict:
|
|
281
|
+
shelf_dict[shelf.name].update(shelf)
|
|
282
|
+
return shelf_dict[shelf.name].to_shelf()
|
|
283
|
+
else:
|
|
284
|
+
self._shelves.append(_InnerShelf.from_shelf(shelf))
|
|
285
|
+
return shelf
|
|
271
286
|
|
|
272
287
|
@emit_after()
|
|
273
288
|
def remove_shelf(self, shelf: Shelf):
|
|
@@ -148,6 +148,7 @@ def _parse_nodeclass_io(node: Node):
|
|
|
148
148
|
node.add_input(
|
|
149
149
|
NodeInput(
|
|
150
150
|
**ser,
|
|
151
|
+
class_default=ip.default,
|
|
151
152
|
)
|
|
152
153
|
)
|
|
153
154
|
|
|
@@ -802,6 +803,7 @@ class Node(EventEmitterMixin, ABC, metaclass=NodeMeta):
|
|
|
802
803
|
kwargs = {
|
|
803
804
|
ip.uuid: ip.value for ip in self._inputs if ip.value is not NoValue
|
|
804
805
|
}
|
|
806
|
+
|
|
805
807
|
err = None
|
|
806
808
|
if "_triggerinput" in kwargs:
|
|
807
809
|
del kwargs["_triggerinput"]
|
|
@@ -23,7 +23,7 @@ from .utils.functions import (
|
|
|
23
23
|
)
|
|
24
24
|
|
|
25
25
|
from weakref import WeakValueDictionary
|
|
26
|
-
|
|
26
|
+
import warnings
|
|
27
27
|
|
|
28
28
|
try:
|
|
29
29
|
from typing import Unpack
|
|
@@ -37,7 +37,7 @@ def node_class_maker(
|
|
|
37
37
|
id: Optional[str] = None,
|
|
38
38
|
func: Callable[..., ReturnType] = None,
|
|
39
39
|
superclass: Type[Node] = Node,
|
|
40
|
-
|
|
40
|
+
separate_thread: bool = False,
|
|
41
41
|
separate_process: bool = False,
|
|
42
42
|
**kwargs: Unpack[NodeClassDict],
|
|
43
43
|
) -> Type[Node]:
|
|
@@ -67,8 +67,8 @@ def node_class_maker(
|
|
|
67
67
|
kwargs["node_id"] = id
|
|
68
68
|
in_func = assure_exposed_method(func)
|
|
69
69
|
|
|
70
|
-
if separate_process and
|
|
71
|
-
raise ValueError("
|
|
70
|
+
if separate_process and separate_thread:
|
|
71
|
+
raise ValueError("separate_thread and separate_process cannot both be True")
|
|
72
72
|
|
|
73
73
|
inputs = [
|
|
74
74
|
NodeInput.from_serialized_input(ip)
|
|
@@ -81,7 +81,7 @@ def node_class_maker(
|
|
|
81
81
|
|
|
82
82
|
if separate_process:
|
|
83
83
|
asyncfunc = make_run_in_new_process(in_func)
|
|
84
|
-
elif
|
|
84
|
+
elif separate_thread:
|
|
85
85
|
asyncfunc = make_run_in_new_thread(in_func)
|
|
86
86
|
else:
|
|
87
87
|
asyncfunc = make_async_if_needed(in_func)
|
|
@@ -91,6 +91,13 @@ def node_class_maker(
|
|
|
91
91
|
"""
|
|
92
92
|
A wrapper for the exposed function that sets the output values of the node.
|
|
93
93
|
"""
|
|
94
|
+
print(
|
|
95
|
+
"BBBtriggering",
|
|
96
|
+
self,
|
|
97
|
+
{ip.name: ip.value for ip in self.inputs.values()},
|
|
98
|
+
args,
|
|
99
|
+
kwargs,
|
|
100
|
+
)
|
|
94
101
|
outs = await asyncfunc(*args, **kwargs)
|
|
95
102
|
if len(outputs) > 1:
|
|
96
103
|
for op, out in zip(outputs, outs):
|
|
@@ -143,7 +150,7 @@ class NodeDecoratorKwargs(ExposedMethodKwargs, NodeClassDict, total=False):
|
|
|
143
150
|
"""
|
|
144
151
|
|
|
145
152
|
superclass: Optional[Type[Node]]
|
|
146
|
-
|
|
153
|
+
separate_thread: Optional[bool]
|
|
147
154
|
separate_process: Optional[bool]
|
|
148
155
|
|
|
149
156
|
|
|
@@ -184,12 +191,20 @@ def NodeDecorator(
|
|
|
184
191
|
|
|
185
192
|
func = assure_exposed_method(func, **exposed_method_kwargs)
|
|
186
193
|
|
|
194
|
+
if "seperate_thread" in kwargs:
|
|
195
|
+
warnings.warn(
|
|
196
|
+
"The 'seperate_thread' argument is deprecated (typo), use 'separate_thread' instead.",
|
|
197
|
+
DeprecationWarning,
|
|
198
|
+
)
|
|
187
199
|
# Create the node class
|
|
188
200
|
return node_class_maker(
|
|
189
201
|
id,
|
|
190
202
|
func,
|
|
191
203
|
superclass=kwargs.get("superclass", Node),
|
|
192
|
-
|
|
204
|
+
separate_thread=kwargs.get(
|
|
205
|
+
"separate_thread",
|
|
206
|
+
kwargs.get("seperate_thread", False),
|
|
207
|
+
), # fallback for typo in old versions
|
|
193
208
|
separate_process=kwargs.get("separate_process", False),
|
|
194
209
|
**node_class_kwargs,
|
|
195
210
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|