diff --git a/notebooks/deepdive.ipynb b/notebooks/deepdive.ipynb index 67f708d0b..f61591d6a 100644 --- a/notebooks/deepdive.ipynb +++ b/notebooks/deepdive.ipynb @@ -524,7 +524,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:158: UserWarning: The channel run was not connected to ran, andthus could not disconnect from it.\n", + "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:159: UserWarning: The channel ran was not connected to run, andthus could not disconnect from it.\n", + " warn(\n", + "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:159: UserWarning: The channel run was not connected to ran, andthus could not disconnect from it.\n", " warn(\n" ] }, @@ -595,7 +597,7 @@ "source": [ "Next, lets see how to do this with a \"push\" paradigm.\n", "\n", - "Just like the data connections, we can connect the `.signals.inputs.run` and `.signals.output.ran` channels of two nodes, but we can also use the `>` operator as a syntactic sugar shortcut.\n", + "Just like the data connections, we can connect the `.signals.inputs.run` and `.signals.output.ran` channels of two nodes, but we can also use the `>>` operator as a syntactic sugar shortcut.\n", "\n", "Note how data connections can be made with keyword arguments just like other input data definitions.\n", "\n", @@ -619,7 +621,7 @@ "source": [ "l = linear(x=10)\n", "t2 = times_two(x=l.outputs.x)\n", - "l > t2 # Note: We can make arbitrarily long linear chains: l > t2 > something_else > another_node\n", + "l >> t2 # Note: We can make arbitrarily long linear chains: l >> t2 >> something_else >> another_node\n", "l.run()\n", "print(t2.inputs.x, t2.outputs.double)" ] @@ -750,13 +752,13 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:158: UserWarning: The channel run was not connected to ran, andthus could not disconnect from it.\n", + "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:159: UserWarning: The channel run was not connected to ran, andthus could not disconnect from it.\n", " warn(\n" ] }, { "data": { - "image/png": "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9ec//9kqLi4mjASRv+P1j3/8w3I6nVZHR0cwysMV/B2rv/zlL9b8+fO92nbv3m3NmzdvwmrET2OZJkRdunRJdXV1ys3N9WrPzc3VyZMnR/U7+vv71d3drdjY2IkoEf8V6Fi98cYbOnfunIqLiye6RFwhkPH68MMPlZmZqeeff15z587VwoULtXXrVv3www/BKDlsBTJWOTk5unDhgiorK2VZlr7++mu98847uueee4JRMkYQEl+Uh+Ha29vV19en+Ph4r/b4+Hi1traO6ne8+OKL+u6777R69eqJKBH/FchYffHFF9q2bZtqamoUGck/02AKZLzOnz+v48ePy+Fw6P3331d7e7seffRRdXZ28tzIBApkrHJycnT48GHl5+erp6dHly9f1r333quXX345GCVjBMyMhDibzeb12rKsYW2+HDlyRM8884zKy8sVFxc3UeXhCqMdq76+Pj3wwAMqKSnRwoULg1UeruLPv63+/n7ZbDYdPnxYWVlZWrlypXbu3KmDBw8yOxIE/oxVY2OjNm3apKefflp1dXWqqqpSU1OTCgoKglEqRsD/coWo2bNny263D0v/bW1tw/4v4Wrl5eVav3693n77bd11110TWSbk/1h1d3fr1KlTqq+v1+OPPy5p4I+dZVmKjIzU0aNHdeeddwal9nAUyL8tl8uluXPnen1VekpKiizL0oULF3TTTTdNaM3hKpCxKi0t1ZIlS/Tkk09Kkm699VbNmDFDS5cu1bPPPiuXyzXhdWM4ZkZCVFRUlDIyMlRdXe3VXl1drZycnBHvO3LkiB566CG99dZbrJEGib9jFRMTo08//VQNDQ1DV0FBgW6++WY1NDRo8eLFwSo9LAXyb2vJkiW6ePGivv3226G2zz//XBEREZo3b96E1hvOAhmr77//XhER3n/67Ha7pIEZFRhi7tlZjNXglrb9+/dbjY2N1ubNm60ZM2ZY//nPfyzLsqxt27ZZDz744FD/t956y4qMjLT27Nljud3uoeubb74x9RHChr9jdTV20wSXv+PV3d1tzZs3z/rd735nffbZZ9axY8esm266ydqwYYOpjxA2/B2rN954w4qMjLT27t1rnTt3zjp+/LiVmZlpZWVlmfoIsNjaG/L27NljJSUlWVFRUVZ6erp17NixoZ+tW7fOuv3224de33777ZakYde6deuCX3gY8mesrkYYCT5/x+vs2bPWXXfdZU2fPt2aN2+eVVhYaH3//fdBrjo8+TtWu3fvtlJTU63p06dbLpfL+v3vf29duHAhyFXjSjbLYl4KAACYwzMjAADAKMIIAAAwijACAACMIowAAACjCCMAAMAowggAADCKMAIAAIwijAAAAKMIIwAAwCjCCAAAMIowAgAAjCKMAAAAo/4fP1qoiEWh9PcAAAAASUVORK5CYII=", + "image/png": "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KSlRfn7+3FQOAADiguMwUllZqYGBAe3YsUOBQED5+flqbm6e3B0TCASm3HMkGAzq5Zdf1tNPPz03VQMAgLjh+D4jNnCfEQAAYs9sv795Ng0AALCKMAIAAKwijAAAAKsIIwAAwCrCCAAAsIowAgAArCKMAAAAqwgjAADAKsIIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijAAAAKsIIwAAwCrCCAAAsIowAgAArCKMAAAAqwgjAADAKsIIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijAAAAKsIIwAAwCrCCAAAsIowAgAArCKMAAAAqwgjAADAKsIIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijAAAAKsIIwAAwCrCCAAAsIowAgAArIoojDQ2NionJ0cej0eFhYVqbW2dsf/IyIi2b9+u7OxspaWlac2aNdqzZ09EBQMAgPiS7HTAgQMHVF1drcbGRq1bt04/+tGPtHHjRnV2duoLX/hC2DF33nmnPvzwQ+3evVu///u/r76+Pl24cOEzFw8AAGKfyxhjnAwoKSlRQUGBmpqaJttyc3O1adMmNTQ0TOnf0tKib3zjGzp58qSWLFkSUZGDg4Pyer0KBoNKT0+P6HcAAIDomu33t6PTNKOjo2pvb1d5eXlIe3l5uY4cORJ2zGuvvaaioiJ973vf08qVK3Xttdfqscce0+9+9zsnbw0AAOKUo9M0/f39GhsbU0ZGRkh7RkaGent7w445efKkDh8+LI/Ho1deeUX9/f166KGHdPbs2WmvGxkZGdHIyMjk68HBQSdlAgCAGBLRBawulyvktTFmStuE8fFxuVwu7d+/X8XFxbr99tu1c+dOvfDCC9OujjQ0NMjr9U4eWVlZkZQJAABigKMwsmzZMrnd7imrIH19fVNWSyb4fD6tXLlSXq93si03N1fGGJ06dSrsmNraWgWDwcmjp6fHSZkAACCGOAojqampKiwslN/vD2n3+/0qKysLO2bdunU6c+aMPv7448m29957T0lJSVq1alXYMWlpaUpPTw85AABAfHJ8mqampkY//vGPtWfPHr377rt69NFH1d3draqqKkkXVzXuueeeyf533XWXli5dqvvvv1+dnZ1688039fjjj+sv//IvtWjRorn7JAAAICY5vs9IZWWlBgYGtGPHDgUCAeXn56u5uVnZ2dmSpEAgoO7u7sn+v/d7vye/36+/+qu/UlFRkZYuXao777xTTzzxxNx9CgAAELMc32fEBu4zAgBA7JmX+4wAAADMNcIIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijAAAAKsIIwAAwCrCCAAAsIowAgAArCKMAAAAqwgjAADAKsIIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijAAAAKsIIwAAwCrCCAAAsIowAgAArCKMAAAAqwgjAADAKsIIAACwijACAACsIowAAACrCCMAAMCqZNsFIHaMjRu1dZ1V39Cwli/2qDhnidxJLttlAQBiHGEEs9JyIqD6g50KBIcn23xej+oq8rQh32exMgBArOM0DS6r5URAW/cdCwkiktQbHNbWfcfUciJgqTIAQDwgjGBGY+NG9Qc7ZcL8bKKt/mCnxsbD9QAA4PIII5hRW9fZKSsilzKSAsFhtXWdjV5RAIC4QhjBjPqGpg8ikfQDAODTCCOY0fLFnjntBwDApxFGMKPinCXyeT2abgOvSxd31RTnLIlmWQCAOEIYwYzcSS7VVeRJ0pRAMvG6riKP+40AACJGGMFlbcj3qenuAmV6Q0/FZHo9arq7gPuMAAA+E256hlnZkO/TrXmZ3IEVADDnCCOYNXeSS6VrltouAwAQZzhNAwAArIoojDQ2NionJ0cej0eFhYVqbW2dtu8bb7whl8s15fif//mfiIsGAADxw3EYOXDggKqrq7V9+3Z1dHRo/fr12rhxo7q7u2cc98tf/lKBQGDyuOaaayIuGgAAxA/HYWTnzp3asmWLHnjgAeXm5uqpp55SVlaWmpqaZhy3fPlyZWZmTh5utzviogEAQPxwFEZGR0fV3t6u8vLykPby8nIdOXJkxrFf/vKX5fP5dPPNN+vnP/+580oBAEBccrSbpr+/X2NjY8rIyAhpz8jIUG9vb9gxPp9Pu3btUmFhoUZGRvTP//zPuvnmm/XGG2/oj/7oj8KOGRkZ0cjIyOTrwcFBJ2UCAIAYEtHWXpcr9N4SxpgpbRPWrl2rtWvXTr4uLS1VT0+Pvv/9708bRhoaGlRfXx9JaQAAIMY4Ok2zbNkyud3uKasgfX19U1ZLZnLjjTfq/fffn/bntbW1CgaDk0dPT4+TMgEAQAxxFEZSU1NVWFgov98f0u73+1VWVjbr39PR0SGfb/pbiKelpSk9PT3kAAAA8cnxaZqamhpt3rxZRUVFKi0t1a5du9Td3a2qqipJF1c1Tp8+rb1790qSnnrqKa1evVrXXXedRkdHtW/fPr388st6+eWX5/aTAACAmOQ4jFRWVmpgYEA7duxQIBBQfn6+mpublZ2dLUkKBAIh9xwZHR3VY489ptOnT2vRokW67rrr9G//9m+6/fbb5+5TAACAmOUyxhjbRVzO4OCgvF6vgsEgp2wAAIgRs/3+5tk0AADAKsIIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijAAAAKsIIwAAwCrCCAAAsIowAgAArCKMAAAAqwgjAADAKsIIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijAAAAKsIIwAAwCrCCAAAsIowAgAArCKMAAAAqwgjAADAKsIIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijAAAAKsIIwAAwCrCCAAAsIowAgAArCKMAAAAqwgjAADAKsIIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKyKKIw0NjYqJydHHo9HhYWFam1tndW4t956S8nJybrhhhsieVsAABCHHIeRAwcOqLq6Wtu3b1dHR4fWr1+vjRs3qru7e8ZxwWBQ99xzj26++eaIiwUAAPHHZYwxTgaUlJSooKBATU1Nk225ubnatGmTGhoaph33jW98Q9dcc43cbrdeffVVHT9+fNbvOTg4KK/Xq2AwqPT0dCflAgAAS2b7/e1oZWR0dFTt7e0qLy8PaS8vL9eRI0emHff888/rgw8+UF1d3azeZ2RkRIODgyEHAACIT47CSH9/v8bGxpSRkRHSnpGRod7e3rBj3n//fW3btk379+9XcnLyrN6noaFBXq938sjKynJSJgAAiCERXcDqcrlCXhtjprRJ0tjYmO666y7V19fr2muvnfXvr62tVTAYnDx6enoiKRMAAMSA2S1VfGLZsmVyu91TVkH6+vqmrJZI0tDQkI4ePaqOjg5961vfkiSNj4/LGKPk5GS9/vrruummm6aMS0tLU1pampPSAABAjHK0MpKamqrCwkL5/f6Qdr/fr7Kysin909PT9Ytf/ELHjx+fPKqqqrR27VodP35cJSUln616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", "text/plain": [ "
" ] @@ -1343,7 +1345,7 @@ "\n" ], "text/plain": [ - "" + "" ] }, "execution_count": 32, @@ -1380,7 +1382,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "c53a726ba4dc472a9c0eabb8f1a39921", + "model_id": "a704c2ac96114ddf9a3710af377b0f6f", "version_major": 2, "version_minor": 0 }, @@ -1399,7 +1401,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 33, @@ -1464,27 +1466,27 @@ "clusterwith_prebuilt\n", "\n", "with_prebuilt: Workflow\n", - "\n", - "clusterwith_prebuiltOutputs\n", + "\n", + "clusterwith_prebuiltInputs\n", "\n", - "\n", + "\n", "\n", "\n", "\n", "\n", - "\n", - "Outputs\n", + "\n", + "Inputs\n", "\n", - "\n", - "clusterwith_prebuiltInputs\n", + "\n", + "clusterwith_prebuiltOutputs\n", "\n", - "\n", + "\n", "\n", "\n", "\n", "\n", - "\n", - "Inputs\n", + "\n", + "Outputs\n", "\n", "\n", "\n", @@ -1659,7 +1661,7 @@ "\n" ], "text/plain": [ - "" + "" ] }, "execution_count": 34, @@ -1717,7 +1719,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:158: UserWarning: The channel run was not connected to ran, andthus could not disconnect from it.\n", + "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:159: UserWarning: The channel run was not connected to ran, andthus could not disconnect from it.\n", " warn(\n" ] }, @@ -1749,7 +1751,7 @@ " # Just like workflows, for simple DAG macros we don't _need_\n", " # to set signals and starting nodes -- the macro will build them\n", " # automatically. But, if you do set both then the macro will use them\n", - " macro.add_one > macro.add_two > macro.add_three\n", + " macro.add_one >> macro.add_two >> macro.add_three\n", " macro.starting_nodes = [macro.add_one] \n", " \n", "macro = Macro(add_three_macro)\n", @@ -3133,7 +3135,7 @@ "\n" ], "text/plain": [ - "" + "" ] }, "execution_count": 40, @@ -3176,7 +3178,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:158: UserWarning: The channel ran was not connected to accumulate_and_run, andthus could not disconnect from it.\n", + "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:159: UserWarning: The channel ran was not connected to accumulate_and_run, andthus could not disconnect from it.\n", " warn(\n" ] }, @@ -3217,15 +3219,15 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:158: UserWarning: The channel job was not connected to job, andthus could not disconnect from it.\n", + "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:159: UserWarning: The channel job was not connected to job, andthus could not disconnect from it.\n", " warn(\n", - "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:158: UserWarning: The channel accumulate_and_run was not connected to ran, andthus could not disconnect from it.\n", + "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:159: UserWarning: The channel accumulate_and_run was not connected to ran, andthus could not disconnect from it.\n", " warn(\n", - "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:158: UserWarning: The channel element was not connected to user_input, andthus could not disconnect from it.\n", + "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:159: UserWarning: The channel element was not connected to user_input, andthus could not disconnect from it.\n", " warn(\n", - "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:158: UserWarning: The channel structure was not connected to structure1, andthus could not disconnect from it.\n", + "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:159: UserWarning: The channel structure was not connected to structure1, andthus could not disconnect from it.\n", " warn(\n", - "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:158: UserWarning: The channel energy was not connected to energy1, andthus could not disconnect from it.\n", + "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:159: UserWarning: The channel energy was not connected to energy1, andthus could not disconnect from it.\n", " warn(\n" ] } @@ -3255,7 +3257,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:158: UserWarning: The channel ran was not connected to accumulate_and_run, andthus could not disconnect from it.\n", + "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:159: UserWarning: The channel ran was not connected to accumulate_and_run, andthus could not disconnect from it.\n", " warn(\n" ] }, @@ -3285,7 +3287,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:158: UserWarning: The channel ran was not connected to accumulate_and_run, andthus could not disconnect from it.\n", + "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:159: UserWarning: The channel ran was not connected to accumulate_and_run, andthus could not disconnect from it.\n", " warn(\n" ] }, @@ -3354,7 +3356,7 @@ "output_type": "stream", "text": [ "None 1\n", - " \n" + " \n" ] } ], @@ -3440,7 +3442,7 @@ "output_type": "stream", "text": [ "None 1\n", - " \n", + " \n", "Finally 5\n", "b (AddNode) output single-value: 6\n" ] @@ -3502,7 +3504,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "6.01573434000602\n" + "6.010571043996606\n" ] } ], @@ -3513,7 +3515,7 @@ "wf.c = Wait(t)\n", "wf.d = wf.create.standard.UserInput(t)\n", "wf.automate_execution = False\n", - "wf.a > wf.b > wf.c > wf.d\n", + "wf.a >> wf.b >> wf.c >> wf.d\n", "wf.starting_nodes = [wf.a]\n", "t0 = perf_counter()\n", "out = wf()\n", @@ -3534,7 +3536,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "2.8263595339958556\n" + "3.023019565967843\n" ] } ], @@ -3667,9 +3669,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:158: UserWarning: The channel run was not connected to true, andthus could not disconnect from it.\n", + "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:159: UserWarning: The channel run was not connected to true, andthus could not disconnect from it.\n", " warn(\n", - "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:158: UserWarning: The channel run was not connected to ran, andthus could not disconnect from it.\n", + "/Users/huber/work/pyiron/pyiron_workflow/pyiron_workflow/channels.py:159: UserWarning: The channel run was not connected to ran, andthus could not disconnect from it.\n", " warn(\n" ] } @@ -3750,8 +3752,11 @@ "name": "stdout", "output_type": "stream", "text": [ - "0.196 <= 0.2\n", - "Finally 0.196\n" + "0.991 > 0.2\n", + "0.325 > 0.2\n", + "0.891 > 0.2\n", + "0.055 <= 0.2\n", + "Finally 0.055\n" ] } ], diff --git a/pyiron_workflow/channels.py b/pyiron_workflow/channels.py index d93e91368..068df7067 100644 --- a/pyiron_workflow/channels.py +++ b/pyiron_workflow/channels.py @@ -496,8 +496,8 @@ class SignalChannel(Channel, ABC): Inputs hold a callback function to call, and outputs call each of their connections. - Signal channels support `>` as syntactic sugar for their connections, i.e. - `some_output > some_input` is equivalent to `some_input.connect(some_output)`. + Signal channels support `>>` as syntactic sugar for their connections, i.e. + `some_output >> some_input` is equivalent to `some_input.connect(some_output)`. (This is also interoperable with `Node` objects, cf. the `Node` docs.) """ @@ -599,9 +599,9 @@ def __str__(self): f"{[f'{c.node.label}.{c.label}' for c in self.connections]}" ) - def __gt__(self, other: InputSignal | Node): + def __rshift__(self, other: InputSignal | Node): other._connect_output_signal(self) - return True + return other def _connect_accumulating_input_signal(self, signal: AccumulatingInputSignal): self.connect(signal) diff --git a/pyiron_workflow/function.py b/pyiron_workflow/function.py index 2c8989c9b..541cd4963 100644 --- a/pyiron_workflow/function.py +++ b/pyiron_workflow/function.py @@ -271,10 +271,9 @@ class Function(Node): >>> >>> adder = adder_node() >>> alpha = AlphabetModThree(i=adder.outputs.sum) - >>> adder > alpha # Ignore the `True`, this is just because we need it to chain - True - - >>> + >>> _ = adder >> alpha + >>> # We catch and ignore output -- it's needed for chaining, but screws up + >>> # doctests -- you don't normally need to catch it like this! >>> out = adder.run(x=1) >>> print(alpha.outputs.letter) b diff --git a/pyiron_workflow/macro.py b/pyiron_workflow/macro.py index f0ca0aecc..adf6a53b4 100644 --- a/pyiron_workflow/macro.py +++ b/pyiron_workflow/macro.py @@ -67,7 +67,7 @@ class Macro(Composite): ... macro.one = macro.create.SingleValue(add_one) ... macro.two = macro.create.SingleValue(add_one, macro.one) ... macro.three = macro.create.SingleValue(add_one, macro.two) - ... macro.one > macro.two > macro.three + ... macro.one >> macro.two >> macro.three ... macro.starting_nodes = [macro.one] In this case we had _no need_ to specify the execution order and starting nodes @@ -138,9 +138,9 @@ class Macro(Composite): signals, but beyond that the code doesn't hold our hands. Let's use this and then observe how the `a` sub-node no longer gets run: >>> m.starting_nodes = [m.b] # At least one starting node - >>> m.b > m.c # At least one run signal (ignore `True`, it's for chaining) - True - + >>> _ = m.b >> m.c # At least one run signal + >>> # We catch and ignore output -- it's needed for chaining, but screws up + >>> # doctests -- you don't normally need to catch it like this! >>> m(a__x=1000, b__x=2000, c__x=3000) {'a__result': 2, 'b__result': 2001, 'c__result': 3001} diff --git a/pyiron_workflow/meta.py b/pyiron_workflow/meta.py index 0e2980185..a861d5579 100644 --- a/pyiron_workflow/meta.py +++ b/pyiron_workflow/meta.py @@ -293,7 +293,7 @@ def make_loop(macro): for out_n, out_c, in_n, in_c in internal_connection_map: macro.nodes[in_n].inputs[in_c] = macro.nodes[out_n].outputs[out_c] - switch.signals.output.true > body_node > condition_node > switch + switch.signals.output.true >> body_node >> condition_node >> switch macro.starting_nodes = [body_node] macro.inputs_map = {} if inputs_map is None else inputs_map diff --git a/pyiron_workflow/node.py b/pyiron_workflow/node.py index e5a1d4fb9..8b7913825 100644 --- a/pyiron_workflow/node.py +++ b/pyiron_workflow/node.py @@ -735,12 +735,12 @@ def __str__(self): def _connect_output_signal(self, signal: OutputSignal): self.signals.input.run.connect(signal) - def __gt__(self, other: InputSignal | Node): + def __rshift__(self, other: InputSignal | Node): """ - Allows users to connect run and ran signals like: `first_node > second_node`. + Allows users to connect run and ran signals like: `first_node >> second_node`. """ other._connect_output_signal(self.signals.output.ran) - return True + return other def _connect_accumulating_input_signal(self, signal: AccumulatingInputSignal): self.signals.output.ran.connect(signal) diff --git a/pyiron_workflow/topology.py b/pyiron_workflow/topology.py index 5e6d5c75c..394dabad2 100644 --- a/pyiron_workflow/topology.py +++ b/pyiron_workflow/topology.py @@ -135,7 +135,7 @@ def _set_run_connections_according_to_linear_dag(nodes: dict[str, Node]) -> list for i, label in enumerate(execution_order[:-1]): next_node = execution_order[i + 1] - nodes[label] > nodes[next_node] + nodes[label] >> nodes[next_node] return [nodes[execution_order[0]]] diff --git a/tests/integration/test_parallel_speedup.py b/tests/integration/test_parallel_speedup.py index 1649605a8..c656af74a 100644 --- a/tests/integration/test_parallel_speedup.py +++ b/tests/integration/test_parallel_speedup.py @@ -24,7 +24,7 @@ def make_workflow(label): t = 2.5 wf = make_workflow("serial") - wf.a > wf.b > wf.c > wf.d + wf.a >> wf.b >> wf.c >> wf.d wf.starting_nodes = [wf.a] t0 = perf_counter() wf() diff --git a/tests/integration/test_workflow.py b/tests/integration/test_workflow.py index 521df150f..837be4481 100644 --- a/tests/integration/test_workflow.py +++ b/tests/integration/test_workflow.py @@ -73,8 +73,8 @@ def sqrt(value=0): wf.sqrt = sqrt() wf.sqrt.inputs.value = wf.rand - wf.gt_switch.signals.output.false > wf.rand > wf.gt_switch # Loop on false - wf.gt_switch.signals.output.true > wf.sqrt # On true break to sqrt node + wf.gt_switch.signals.output.false >> wf.rand >> wf.gt_switch # Loop on false + wf.gt_switch.signals.output.true >> wf.sqrt # On true break to sqrt node wf.starting_nodes = [wf.rand] wf.run() diff --git a/tests/unit/test_channels.py b/tests/unit/test_channels.py index 714a6c57b..66ab99ec8 100644 --- a/tests/unit/test_channels.py +++ b/tests/unit/test_channels.py @@ -374,7 +374,7 @@ def test_connections(self): with self.subTest("Test syntactic sugar"): self.out.disconnect_all() - self.out > self.inp + self.out >> self.inp self.assertIn(self.out, self.inp.connections) def test_calls(self): diff --git a/tests/unit/test_composite.py b/tests/unit/test_composite.py index 7c41aceec..ed6d16414 100644 --- a/tests/unit/test_composite.py +++ b/tests/unit/test_composite.py @@ -416,7 +416,7 @@ def test_run(self): self.comp.create.SingleValue(plus_one, label="n1", x=0) self.comp.create.SingleValue(plus_one, label="n2", x=self.comp.n1) self.comp.create.SingleValue(plus_one, label="n3", x=42) - self.comp.n1 > self.comp.n2 + self.comp.n1 >> self.comp.n2 self.comp.starting_nodes = [self.comp.n1] self.comp.run() diff --git a/tests/unit/test_function.py b/tests/unit/test_function.py index c70d9bb5f..5a993c18d 100644 --- a/tests/unit/test_function.py +++ b/tests/unit/test_function.py @@ -89,7 +89,7 @@ def test_instantiation(self): node.outputs.y, msg="Should be able to make a connection at initialization" ) - node > node2 + node >> node2 node.run() self.assertEqual(4, node2.outputs.y.value, msg="Initialize from connection") @@ -318,7 +318,7 @@ def test_copy_connections(self): upstream = Function(plus_one) to_copy = Function(plus_one, x=upstream.outputs.y) downstream = Function(plus_one, x=to_copy.outputs.y) - upstream > to_copy > downstream + upstream >> to_copy >> downstream wrong_io = Function( returns_multiple, x=upstream.outputs.y, y=upstream.outputs.y @@ -549,7 +549,7 @@ def test_easy_output_connection(self): "output and another node's input by passing themselves" ) - svn > regular + svn >> regular svn.run() self.assertEqual( regular.outputs.y.value, 3, diff --git a/tests/unit/test_io.py b/tests/unit/test_io.py index 7d6bd1f1b..efae3620d 100644 --- a/tests/unit/test_io.py +++ b/tests/unit/test_io.py @@ -163,10 +163,10 @@ def do_nothing(): signals.output.ran = OutputSignal("ran", node) signals.output.bar = OutputSignal("bar", node) - signals.output.ran > signals.input.run - signals.output.ran > signals.input.foo - signals.output.bar > signals.input.run - signals.output.bar > signals.input.foo + signals.output.ran >> signals.input.run + signals.output.ran >> signals.input.foo + signals.output.bar >> signals.input.run + signals.output.bar >> signals.input.foo self.signals = signals diff --git a/tests/unit/test_macro.py b/tests/unit/test_macro.py index fefbfeaa0..7b90fe86d 100644 --- a/tests/unit/test_macro.py +++ b/tests/unit/test_macro.py @@ -90,12 +90,12 @@ def test_execution_automation(self): def fully_defined(macro): add_three_macro(macro) - macro.one > macro.two > macro.three + macro.one >> macro.two >> macro.three macro.starting_nodes = [macro.one] def only_order(macro): add_three_macro(macro) - macro.two > macro.three + macro.two >> macro.three def only_starting(macro): add_three_macro(macro) @@ -198,7 +198,7 @@ def nested_macro(macro): add_one, x=macro.c.outputs.three__result, ) - macro.a > macro.b > macro.c > macro.d + macro.a >> macro.b >> macro.c >> macro.d macro.starting_nodes = [macro.a] # This definition of the execution graph is not strictly necessary in this # simple DAG case; we just do it to make sure nesting definied/automatic @@ -211,7 +211,7 @@ def nested_macro(macro): def test_with_executor(self): macro = Macro(add_three_macro) downstream = SingleValue(add_one, x=macro.outputs.three__result) - macro > downstream # Manually specify since we'll run the macro but look + macro >> downstream # Manually specify since we'll run the macro but look # at the downstream output, and none of this is happening in a workflow original_one = macro.one @@ -314,7 +314,7 @@ def cyclic_macro(macro): macro.one = SingleValue(add_one) macro.two = SingleValue(add_one, x=macro.one) macro.one.inputs.x = macro.two - macro.one > macro.two + macro.one >> macro.two macro.starting_nodes = [macro.one] # We need to manually specify execution since the data flow is cyclic @@ -395,7 +395,7 @@ def fail_at_zero(x): n1 = SingleValue(fail_at_zero, x=0) n2 = SingleValue(add_one, x=n1, label="n1") n_not_used = SingleValue(add_one) - n_not_used > n2 # Just here to make sure it gets restored + n_not_used >> n2 # Just here to make sure it gets restored with self.assertRaises( ZeroDivisionError, diff --git a/tests/unit/test_node.py b/tests/unit/test_node.py index 13257ac34..3c239d012 100644 --- a/tests/unit/test_node.py +++ b/tests/unit/test_node.py @@ -195,7 +195,7 @@ def test_force_local_execution(self): self.n2.executor_shutdown() def test_emit_ran_signal(self): - self.n1 > self.n2 > self.n3 # Chained connection declaration + self.n1 >> self.n2 >> self.n3 # Chained connection declaration self.n1.run(emit_ran_signal=False) self.assertFalse( @@ -213,7 +213,7 @@ def test_emit_ran_signal(self): def test_execute(self): self.n1.outputs.y = 0 # Prime the upstream data source for fetching - self.n2 > self.n3 + self.n2 >> self.n3 self.assertEqual( self.n2.run(fetch_input=False, emit_ran_signal=False, x=10) + 1, self.n2.execute(x=11), @@ -234,7 +234,7 @@ def test_execute(self): self.n2.execute() def test_pull(self): - self.n2 > self.n3 + self.n2 >> self.n3 self.n1.inputs.x = 0 by_run = self.n2.run( run_data_tree=True, @@ -256,7 +256,7 @@ def test_pull(self): def test___call__(self): # __call__ is just a pull that punches through macro walls, so we'll need to # test it again over in macro to really make sure it's working - self.n2 > self.n3 + self.n2 >> self.n3 self.n1.inputs.x = 0 by_run = self.n2.run( run_data_tree=True, diff --git a/tests/unit/test_workflow.py b/tests/unit/test_workflow.py index 0a1e1390c..e5aab2a2f 100644 --- a/tests/unit/test_workflow.py +++ b/tests/unit/test_workflow.py @@ -251,9 +251,9 @@ def matches_expectations(results): user = make_workflow() user.automate_execution = False - user.n1l > user.n1r > user.n2l - user.n1r > user.n2m - user.n1r > user.n2r + user.n1l >> user.n1r >> user.n2l + user.n1r >> user.n2m + user.n1r >> user.n2r user.starting_nodes = [user.n1l] self.assertTrue( matches_expectations(user()),