metaflow 2.17.1__py2.py3-none-any.whl → 2.17.3__py2.py3-none-any.whl

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.
@@ -52,6 +52,15 @@ class CatchDecorator(StepDecorator):
52
52
  "split steps." % step
53
53
  )
54
54
 
55
+ # Do not support catch on switch steps for now.
56
+ # When applying @catch to a switch step, we can not guarantee that the flow attribute used for the switching condition gets properly recorded.
57
+ if graph[step].type == "split-switch":
58
+ raise MetaflowException(
59
+ "@catch is defined for the step *%s* "
60
+ "but @catch is not supported in conditional "
61
+ "switch steps." % step
62
+ )
63
+
55
64
  def _print_exception(self, step, flow):
56
65
  self.logger(head="@catch caught an exception from %s" % flow, timestamp=False)
57
66
  for line in traceback.format_exc().splitlines():
@@ -53,6 +53,13 @@ class ParallelDecorator(StepDecorator):
53
53
  def step_init(
54
54
  self, flow, graph, step_name, decorators, environment, flow_datastore, logger
55
55
  ):
56
+ # TODO: This can be supported in the future, but for the time being we disable the transition as it leads to
57
+ # a UBF exception during runtime when the actual parallel-join step is conditional (switching between different join implementations from the @parallel step).
58
+ if graph[step_name].type == "split-switch":
59
+ raise MetaflowException(
60
+ "A @parallel step can not be a conditional switch step. Please add a join step after *%s*"
61
+ % step_name
62
+ )
56
63
  self.environment = environment
57
64
  # Previously, the `parallel` property was a hardcoded, static property within `current`.
58
65
  # Whenever `current.parallel` was called, it returned a named tuple with values coming from
metaflow/runtime.py CHANGED
@@ -820,9 +820,11 @@ class NativeRuntime(object):
820
820
  # matching_split is the split-parent of the finished task
821
821
  matching_split = self._graph[self._graph[next_step].split_parents[-1]]
822
822
  _, foreach_stack = task.finished_id
823
- index = ""
823
+
824
+ direct_parents = set(self._graph[next_step].in_funcs)
825
+
826
+ # next step is a foreach join
824
827
  if matching_split.type == "foreach":
825
- # next step is a foreach join
826
828
 
827
829
  def siblings(foreach_stack):
828
830
  top = foreach_stack[-1]
@@ -831,29 +833,46 @@ class NativeRuntime(object):
831
833
  yield tuple(bottom + [top._replace(index=index)])
832
834
 
833
835
  # required tasks are all split-siblings of the finished task
834
- required_tasks = [
835
- self._finished.get((task.step, s)) for s in siblings(foreach_stack)
836
- ]
836
+ required_tasks = list(
837
+ filter(
838
+ lambda x: x is not None,
839
+ [
840
+ self._finished.get((p, s))
841
+ for p in direct_parents
842
+ for s in siblings(foreach_stack)
843
+ ],
844
+ )
845
+ )
846
+ required_count = task.finished_id[1][-1].num_splits
837
847
  join_type = "foreach"
838
848
  index = self._translate_index(task, next_step, "join")
839
849
  else:
840
850
  # next step is a split
841
- # required tasks are all branches joined by the next step
842
- required_tasks = [
843
- self._finished.get((step, foreach_stack))
844
- for step in self._graph[next_step].in_funcs
845
- ]
851
+ required_tasks = list(
852
+ filter(
853
+ lambda x: x is not None,
854
+ [
855
+ self._finished.get((p, foreach_stack))
856
+ for p in direct_parents
857
+ ],
858
+ )
859
+ )
860
+ required_count = len(matching_split.out_funcs)
846
861
  join_type = "linear"
847
862
  index = self._translate_index(task, next_step, "linear")
848
-
849
- if all(required_tasks):
850
- # all tasks to be joined are ready. Schedule the next join step.
863
+ if len(required_tasks) == required_count:
864
+ # We have all the required previous tasks to schedule a join
851
865
  self._queue_push(
852
866
  next_step,
853
867
  {"input_paths": required_tasks, "join_type": join_type},
854
868
  index,
855
869
  )
856
870
 
871
+ def _queue_task_switch(self, task, next_steps):
872
+ chosen_step = next_steps[0]
873
+ index = self._translate_index(task, chosen_step, "linear")
874
+ self._queue_push(chosen_step, {"input_paths": [task.path]}, index)
875
+
857
876
  def _queue_task_foreach(self, task, next_steps):
858
877
  # CHECK: this condition should be enforced by the linter but
859
878
  # let's assert that the assumption holds
@@ -930,7 +949,28 @@ class NativeRuntime(object):
930
949
  next_steps = []
931
950
  foreach = None
932
951
  expected = self._graph[task.step].out_funcs
933
- if next_steps != expected:
952
+ if self._graph[task.step].type == "split-switch":
953
+ if len(next_steps) != 1:
954
+ msg = (
955
+ "Switch step *{step}* should transition to exactly "
956
+ "one step at runtime, but got: {actual}"
957
+ )
958
+ raise MetaflowInternalError(
959
+ msg.format(step=task.step, actual=", ".join(next_steps))
960
+ )
961
+ if next_steps[0] not in expected:
962
+ msg = (
963
+ "Switch step *{step}* transitioned to unexpected "
964
+ "step *{actual}*. Expected one of: {expected}"
965
+ )
966
+ raise MetaflowInternalError(
967
+ msg.format(
968
+ step=task.step,
969
+ actual=next_steps[0],
970
+ expected=", ".join(expected),
971
+ )
972
+ )
973
+ elif next_steps != expected:
934
974
  msg = (
935
975
  "Based on static analysis of the code, step *{step}* "
936
976
  "was expected to transition to step(s) *{expected}*. "
@@ -954,6 +994,9 @@ class NativeRuntime(object):
954
994
  elif foreach:
955
995
  # Next step is a foreach child
956
996
  self._queue_task_foreach(task, next_steps)
997
+ elif self._graph[task.step].type == "split-switch":
998
+ # Next step is switch - queue the chosen step
999
+ self._queue_task_switch(task, next_steps)
957
1000
  else:
958
1001
  # Next steps are normal linear steps
959
1002
  for step in next_steps:
metaflow/task.py CHANGED
@@ -62,8 +62,17 @@ class MetaflowTask(object):
62
62
  def _exec_step_function(self, step_function, orig_step_func, input_obj=None):
63
63
  wrappers_stack = []
64
64
  wrapped_func = None
65
- do_next = False
65
+
66
+ # Will set to non-Falsy if we need to fake calling `self.next`
67
+ # This is used when skipping the step.
68
+ # If a dictionary, it will
69
+ # contain the arguments to pass to `self.next`. If
70
+ # True, it means we are using whatever the usual
71
+ # arguments to `self.next` are for this step.
72
+ fake_next_call_args = False
66
73
  raised_exception = None
74
+ had_raised_exception = False
75
+
67
76
  # If we have wrappers w1, w2 and w3, we need to execute
68
77
  # - w3_pre
69
78
  # - w2_pre
@@ -80,41 +89,66 @@ class MetaflowTask(object):
80
89
  wrapped_func = w.pre_step(orig_step_func.name, self.flow, input_obj)
81
90
  wrappers_stack.append(w)
82
91
  if w.skip_step:
83
- # We have nothing to run
84
- do_next = w.skip_step
92
+ # We are not going to run anything so we will have to fake calling
93
+ # next.
94
+ fake_next_call_args = w.skip_step
85
95
  break
86
96
  if wrapped_func:
87
97
  break # We have nothing left to do since we now execute the
88
98
  # wrapped function
89
99
  # Else, we continue down the list of wrappers
90
100
  try:
91
- if not do_next:
101
+ # fake_next_call is used here to also indicate that the step was skipped
102
+ # so we do not execute anything.
103
+ if not fake_next_call_args:
92
104
  if input_obj is None:
93
105
  if wrapped_func:
94
- do_next = wrapped_func(self.flow)
95
- if not do_next:
96
- do_next = True
106
+ fake_next_call_args = wrapped_func(self.flow)
97
107
  else:
98
108
  step_function()
99
109
  else:
100
110
  if wrapped_func:
101
- do_next = wrapped_func(self.flow, input_obj)
102
- if not do_next:
103
- do_next = True
111
+ fake_next_call_args = wrapped_func(self.flow, input_obj)
104
112
  else:
105
113
  step_function(input_obj)
106
114
  except Exception as ex:
107
115
  raised_exception = ex
116
+ had_raised_exception = True
117
+
118
+ # We back out of the stack of generators
119
+ for w in reversed(wrappers_stack):
120
+ r = w.post_step(orig_step_func.name, self.flow, raised_exception)
121
+ if r is None or isinstance(r, Exception):
122
+ raised_exception = None
123
+ elif isinstance(r, tuple):
124
+ raised_exception, fake_next_call_args = r
125
+ else:
126
+ raise RuntimeError(
127
+ "Invalid return value from a UserStepDecorator. Expected an"
128
+ "exception or an exception and arguments for self.next, got: %s" % r
129
+ )
130
+ if raised_exception:
131
+ # We have an exception that we need to propagate
132
+ raise raised_exception
108
133
 
109
- if do_next or raised_exception:
110
- # If we are skipping the step, or executed a wrapped function,
134
+ if fake_next_call_args or had_raised_exception:
135
+ # We want to override the next call or we caught an exception (in which
136
+ # case the regular step code didn't call self.next). In this case,
111
137
  # we need to set the transition variables
112
138
  # properly. We call the next function as needed
113
139
  # We also do this in case we want to gobble the exception.
114
140
  graph_node = self.flow._graph[orig_step_func.name]
115
141
  out_funcs = [getattr(self.flow, f) for f in graph_node.out_funcs]
116
142
  if out_funcs:
117
- if isinstance(do_next, bool) or raised_exception:
143
+ if isinstance(fake_next_call_args, dict) and fake_next_call_args:
144
+ # Not an empty dictionary -- we use this as arguments for the next
145
+ # call
146
+ self.flow.next(*out_funcs, **fake_next_call_args)
147
+ elif (
148
+ fake_next_call_args == True
149
+ or fake_next_call_args == {}
150
+ or had_raised_exception
151
+ ):
118
152
  # We need to extract things from the self.next. This is not possible
119
153
  # in the case where there was a num_parallel.
120
154
  if graph_node.parallel_foreach:
@@ -126,23 +160,11 @@ class MetaflowTask(object):
126
160
  self.flow.next(*out_funcs, foreach=graph_node.foreach_param)
127
161
  else:
128
162
  self.flow.next(*out_funcs)
129
- elif isinstance(do_next, dict):
130
- # Here it is a dictionary so we just call the next method with
131
- # those arguments
132
- self.flow.next(*out_funcs, **do_next)
133
163
  else:
134
164
  raise RuntimeError(
135
165
  "Invalid value passed to self.next; expected "
136
- " bool of a dictionary; got: %s" % do_next
166
+ " bool of a dictionary; got: %s" % fake_next_call_args
137
167
  )
138
- # We back out of the stack of generators
139
- for w in reversed(wrappers_stack):
140
- raised_exception = w.post_step(
141
- orig_step_func.name, self.flow, raised_exception
142
- )
143
- if raised_exception:
144
- # We have an exception that we need to propagate
145
- raise raised_exception
146
168
 
147
169
  def _init_parameters(self, parameter_ds, passdown=True):
148
170
  cls = self.flow.__class__
@@ -671,14 +693,20 @@ class MetaflowTask(object):
671
693
  if join_type:
672
694
  # Join step:
673
695
 
674
- # Ensure that we have the right number of inputs. The
675
- # foreach case is checked above.
676
- if join_type != "foreach" and len(inputs) != len(node.in_funcs):
677
- raise MetaflowDataMissing(
678
- "Join *%s* expected %d "
679
- "inputs but only %d inputs "
680
- "were found" % (step_name, len(node.in_funcs), len(inputs))
681
- )
696
+ # Ensure that we have the right number of inputs.
697
+ if join_type != "foreach":
698
+ # Find the corresponding split node from the graph.
699
+ split_node = self.flow._graph[node.split_parents[-1]]
700
+ # The number of expected inputs is the number of branches
701
+ # from that split -- we can't use in_funcs because there may
702
+ # be more due to split-switch branches that all converge here.
703
+ expected_inputs = len(split_node.out_funcs)
704
+
705
+ if len(inputs) != expected_inputs:
706
+ raise MetaflowDataMissing(
707
+ "Join *%s* expected %d inputs but only %d inputs "
708
+ "were found" % (step_name, expected_inputs, len(inputs))
709
+ )
682
710
 
683
711
  # Multiple input contexts are passed in as an argument
684
712
  # to the step function.
@@ -463,7 +463,9 @@ class UserStepDecorator(UserStepDecoratorBase):
463
463
  step_name: str,
464
464
  flow: "metaflow.flowspec.FlowSpec",
465
465
  exception: Optional[Exception] = None,
466
- ):
466
+ ) -> Optional[
467
+ Union[Optional[Exception], Tuple[Optional[Exception], Optional[Dict[str, Any]]]]
468
+ ]:
467
469
  """
468
470
  Implement this method to perform any action after the execution of a step.
469
471
 
@@ -483,9 +485,23 @@ class UserStepDecorator(UserStepDecoratorBase):
483
485
  The flow object to which the step belongs.
484
486
  exception: Optional[Exception]
485
487
  The exception raised during the step execution, if any.
488
+
489
+ Returns
490
+ -------
491
+ Optional[Union[Optional[Exception], Tuple[Optional[Exception], Optional[Dict[str, Any]]]]]
492
+ An exception (if None, the step is considered successful)
493
+ OR
494
+ A tuple containing:
495
+ - An exception to be raised (if None, the step is considered successful).
496
+ - A dictionary with values to pass to `self.next()`. If an empty dictionary
497
+ is returned, the default arguments to `self.next()` for this step will be
498
+ used. Return None if you do not want to call `self.next()` at all
499
+ (this is typically the case as the step will call it itself).
500
+ Note that returning None will gobble the exception.
486
501
  """
487
502
  if exception:
488
- raise exception
503
+ return exception, None
504
+ return None, None
489
505
 
490
506
  @property
491
507
  def skip_step(self) -> Union[bool, Dict[str, Any]]:
@@ -624,24 +640,27 @@ def user_step_decorator(*args, **kwargs):
624
640
  self._generator = self._generator(step_name, flow, inputs)
625
641
  v = self._generator.send(None)
626
642
  if isinstance(v, dict):
627
- # We are skipping the step
643
+ # We are modifying the behavior of self.next
628
644
  if v:
629
645
  self.skip_step = v
630
646
  else:
647
+ # Emtpy dict is just skip the step
631
648
  self.skip_step = True
632
649
  return None
633
650
  return v
634
651
 
635
652
  def post_step(self, step_name, flow, exception=None):
653
+ to_return = None, None
636
654
  try:
637
655
  if exception:
638
656
  self._generator.throw(exception)
639
657
  else:
640
658
  self._generator.send(None)
641
- except StopIteration:
642
- pass
659
+ except StopIteration as e:
660
+ to_return = e.value
643
661
  else:
644
662
  raise MetaflowException(" %s should only yield once" % self)
663
+ return to_return
645
664
 
646
665
  return WrapClass
647
666
  else:
metaflow/version.py CHANGED
@@ -1 +1 @@
1
- metaflow_version = "2.17.1"
1
+ metaflow_version = "2.17.3"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: metaflow
3
- Version: 2.17.1
3
+ Version: 2.17.3
4
4
  Summary: Metaflow: More AI and ML, Less Engineering
5
5
  Author: Metaflow Developers
6
6
  Author-email: help@metaflow.org
@@ -26,7 +26,7 @@ License-File: LICENSE
26
26
  Requires-Dist: requests
27
27
  Requires-Dist: boto3
28
28
  Provides-Extra: stubs
29
- Requires-Dist: metaflow-stubs==2.17.1; extra == "stubs"
29
+ Requires-Dist: metaflow-stubs==2.17.3; extra == "stubs"
30
30
  Dynamic: author
31
31
  Dynamic: author-email
32
32
  Dynamic: classifier
@@ -10,11 +10,11 @@ metaflow/decorators.py,sha256=4g11F5xtXmKRMNfeFd9yKOWpiHAoyxfbfDqIWak1_Q0,30831
10
10
  metaflow/event_logger.py,sha256=joTVRqZPL87nvah4ZOwtqWX8NeraM_CXKXXGVpKGD8o,780
11
11
  metaflow/events.py,sha256=ahjzkSbSnRCK9RZ-9vTfUviz_6gMvSO9DGkJ86X80-k,5300
12
12
  metaflow/exception.py,sha256=_m9ZBJM0cooHRslDqfxCPQmkChqaTh6fGxp7HvISnYI,5161
13
- metaflow/flowspec.py,sha256=hCONv0wlC-MgxNUDWzDtS_4ayr-0sqPNUdnpXJ75b1Y,37944
14
- metaflow/graph.py,sha256=alPCQPexm-0hjquQgLYNhoe6PbXL_LXMg1L__G1DxYw,13183
13
+ metaflow/flowspec.py,sha256=9wsO2_QoO_VHKusKdpslfbwQREOwf0fAzF-DSEA0iZ8,41968
14
+ metaflow/graph.py,sha256=3Ova0lGbUZzxV89vqw3bX-dCSaVXfGUz3Tm9a8cmtSI,19198
15
15
  metaflow/includefile.py,sha256=RtISGl1V48qjkJBakUZ9yPpHV102h7pOIFiKP8PLHpc,20927
16
16
  metaflow/integrations.py,sha256=LlsaoePRg03DjENnmLxZDYto3NwWc9z_PtU6nJxLldg,1480
17
- metaflow/lint.py,sha256=x4p6tnRzYqNNniCGXyrUW0WuYfTUgnaOMRivxvnxask,11661
17
+ metaflow/lint.py,sha256=2VLHNgxmHDtUcudvyfPCFIlbDy1pW7GFjNPBWtKZVjA,14102
18
18
  metaflow/meta_files.py,sha256=vlgJHI8GJUKzXoxdrVoH8yyCF5bhFgwYemUgnyd1wgM,342
19
19
  metaflow/metaflow_config.py,sha256=lsdfr_1eS4cP6g1OgLWePKzUIypUGVjNxffRhKlFWfA,24102
20
20
  metaflow/metaflow_config_funcs.py,sha256=5GlvoafV6SxykwfL8D12WXSfwjBN_NsyuKE_Q3gjGVE,6738
@@ -29,14 +29,14 @@ metaflow/parameters.py,sha256=b3rS6P-TeEj2JgPEKaiy0ys1B_JtOGJ6XM0KkY2layc,18649
29
29
  metaflow/procpoll.py,sha256=U2tE4iK_Mwj2WDyVTx_Uglh6xZ-jixQOo4wrM9OOhxg,2859
30
30
  metaflow/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
31
  metaflow/pylint_wrapper.py,sha256=tJjmdsgtbHTCqg_oA6fV6SbWq_3V5XUgE9xH0zJ1CGU,3004
32
- metaflow/runtime.py,sha256=KwHKZ6kNZuC8HgL_r0-gTi9Y-GPAhTz0tNXydQFjZO4,77617
32
+ metaflow/runtime.py,sha256=QjmWeaphyP4U8CI0fN9rVFOXvkC0yNr7-bnSG0fNhWQ,79508
33
33
  metaflow/tagging_util.py,sha256=ctyf0Q1gBi0RyZX6J0e9DQGNkNHblV_CITfy66axXB4,2346
34
- metaflow/task.py,sha256=1DslU1CHoEeFIilABQvk4Zbpl-yCdZMEkECnv2LQAZg,34356
34
+ metaflow/task.py,sha256=O8swwqdSPZ_IyAC0GzjLyRVIyHH2C5iv19AtC8shFXs,35932
35
35
  metaflow/tuple_util.py,sha256=_G5YIEhuugwJ_f6rrZoelMFak3DqAR2tt_5CapS1XTY,830
36
36
  metaflow/unbounded_foreach.py,sha256=p184WMbrMJ3xKYHwewj27ZhRUsSj_kw1jlye5gA9xJk,387
37
37
  metaflow/util.py,sha256=g2SOU_CRzJLgDM_UGF9QDMANMAIHAsDRXE6S76_YzsY,14594
38
38
  metaflow/vendor.py,sha256=A82CGHfStZGDP5pQ5XzRjFkbN1ZC-vFmghXIrzMDDNg,5868
39
- metaflow/version.py,sha256=cOW5Gzl3yHX8RxsVq7TnPv58zlZoFrqwP_PGsg1JfRQ,28
39
+ metaflow/version.py,sha256=XUi5503h1FTLCQTm2Er2t3lqs9HEd10aLotp-zKBeg8,28
40
40
  metaflow/_vendor/__init__.py,sha256=y_CiwUD3l4eAKvTVDZeqgVujMy31cAM1qjAB-HfI-9s,353
41
41
  metaflow/_vendor/typing_extensions.py,sha256=q9zxWa6p6CzF1zZvSkygSlklduHf_b3K7MCxGz7MJRc,134519
42
42
  metaflow/_vendor/zipp.py,sha256=ajztOH-9I7KA_4wqDYygtHa6xUBVZgFpmZ8FE74HHHI,8425
@@ -153,7 +153,7 @@ metaflow/_vendor/yaml/tokens.py,sha256=lTQIzSVw8Mg9wv459-TjiOQe6wVziqaRlqX2_89rp
153
153
  metaflow/cli_components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
154
154
  metaflow/cli_components/dump_cmd.py,sha256=SZEX51BWNd1o3H2uHDkYA8KRvou5X8g5rTwpdu5vnNQ,2704
155
155
  metaflow/cli_components/init_cmd.py,sha256=AIkQHNlMRsmf8fxXwXQSEWTuv_9nxNY82-IdWsgGjEs,1554
156
- metaflow/cli_components/run_cmds.py,sha256=xULZQ2UrxLNsWjQIZd38EbOGNBw8UJT7w_T19UbS_fg,11555
156
+ metaflow/cli_components/run_cmds.py,sha256=_xk2asy3SkqsJfZVhbgYSJ2rkkJe7cvLik6b0HT-704,12264
157
157
  metaflow/cli_components/step_cmd.py,sha256=zGJgTv7wxrv34nWDi__CHaC2eS6kItR95EdVGJX803w,4766
158
158
  metaflow/cli_components/utils.py,sha256=gpoDociadjnJD7MuiJup_MDR02ZJjjleejr0jPBu29c,6057
159
159
  metaflow/client/__init__.py,sha256=1GtQB4Y_CBkzaxg32L1syNQSlfj762wmLrfrDxGi1b8,226
@@ -199,14 +199,14 @@ metaflow/packaging_sys/tar_backend.py,sha256=nFWuXiwYjWQkFdV2KaZ6gazNVvtY84Eqsh9
199
199
  metaflow/packaging_sys/utils.py,sha256=x8SVglJvY5mIAilS7MqZi2PpMr6IEyi6RCg3l8hN3G0,2972
200
200
  metaflow/packaging_sys/v1.py,sha256=kbNK0-pDAv3QJPZ789TE0UirGXcHbXkVQiyNT815H7A,20631
201
201
  metaflow/plugins/__init__.py,sha256=yFxjJOlnfap7tQMNgSgaso2tl_zr1BcWL7KoUKk4c9Y,8617
202
- metaflow/plugins/catch_decorator.py,sha256=UOM2taN_OL2RPpuJhwEOA9ZALm0-hHD0XS2Hn2GUev0,4061
202
+ metaflow/plugins/catch_decorator.py,sha256=vorlDA6MLB2yHSsEuBoNzAZbrJ6Vknj1qJO9vey2_AI,4523
203
203
  metaflow/plugins/debug_logger.py,sha256=mcF5HYzJ0NQmqCMjyVUk3iAP-heroHRIiVWQC6Ha2-I,879
204
204
  metaflow/plugins/debug_monitor.py,sha256=Md5X_sDOSssN9pt2D8YcaIjTK5JaQD55UAYTcF6xYF0,1099
205
205
  metaflow/plugins/environment_decorator.py,sha256=6m9j2B77d-Ja_l_9CTJ__0O6aB2a8Qt_lAZu6UjAcUA,587
206
206
  metaflow/plugins/events_decorator.py,sha256=T_YSK-DlgZhd3ge9PlpTRNaMi15GK0tKZMZl1NdV9DQ,24403
207
207
  metaflow/plugins/logs_cli.py,sha256=77W5UNagU2mOKSMMvrQxQmBLRzvmjK-c8dWxd-Ygbqs,11410
208
208
  metaflow/plugins/package_cli.py,sha256=4OIBmuSSmQ6utWbeMln9HzQXnC9UYm3SilsHzf_sqbo,2002
209
- metaflow/plugins/parallel_decorator.py,sha256=cUv_CrMwdItDqQScp5bg18JteSS6p0Ms70mCzD5YcNU,9180
209
+ metaflow/plugins/parallel_decorator.py,sha256=wtR_3eRIP3eV7fBIm15oouRjmHBFZ9OklxdaNvttLEQ,9702
210
210
  metaflow/plugins/project_decorator.py,sha256=uhwsguEj7OM_E2OnY1ap3MoGocQHeywuJSa-qPuWn-U,7592
211
211
  metaflow/plugins/resources_decorator.py,sha256=AtoOwg4mHYHYthg-CAfbfam-QiT0ViuDLDoukoDvF6Q,1347
212
212
  metaflow/plugins/retry_decorator.py,sha256=tz_2Tq6GLg3vjDBZp0KKVTk3ADlCvqaWTSf7blmFdUw,1548
@@ -230,12 +230,13 @@ metaflow/plugins/airflow/sensors/s3_sensor.py,sha256=iDReG-7FKnumrtQg-HY6cCUAAqN
230
230
  metaflow/plugins/argo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
231
231
  metaflow/plugins/argo/argo_client.py,sha256=jLz0FjCTBvFLZt-8lZcMQhDcInhgEcGdPrU2Gvh67zA,17080
232
232
  metaflow/plugins/argo/argo_events.py,sha256=_C1KWztVqgi3zuH57pInaE9OzABc2NnncC-zdwOMZ-w,5909
233
- metaflow/plugins/argo/argo_workflows.py,sha256=lnyS5xXBDTwdFdnjA0F8C2VfTuINscoG-ZWCeJ7uer0,189138
233
+ metaflow/plugins/argo/argo_workflows.py,sha256=iSwLp-LA868pHE8C-ltW-J_W_qpP59UjFtqjXEj3lyI,200184
234
234
  metaflow/plugins/argo/argo_workflows_cli.py,sha256=L5KwcT6Vd4HqAXFCPGmHUONgM2eOCTbvxdoIs6CQchw,51877
235
- metaflow/plugins/argo/argo_workflows_decorator.py,sha256=ogCSBmwsC2C3eusydrgjuAJd4qK18f1sI4jJwA4Fd-o,7800
235
+ metaflow/plugins/argo/argo_workflows_decorator.py,sha256=CLSjPqFTGucZ2_dSQGAYkoWWUZBQ9TCBXul4rxhDj3w,8282
236
236
  metaflow/plugins/argo/argo_workflows_deployer.py,sha256=6kHxEnYXJwzNCM9swI8-0AckxtPWqwhZLerYkX8fxUM,4444
237
237
  metaflow/plugins/argo/argo_workflows_deployer_objects.py,sha256=ydBE-lP42eNKvep36nQdUBPS3rQQErvoA7rCgyp5M6I,14949
238
238
  metaflow/plugins/argo/capture_error.py,sha256=Ys9dscGrTpW-ZCirLBU0gD9qBM0BjxyxGlUMKcwewQc,1852
239
+ metaflow/plugins/argo/conditional_input_paths.py,sha256=kpzwyjXjO7PjeAJMapYX_ajUulFQJvCj-2DhH7OHzy0,645
239
240
  metaflow/plugins/argo/exit_hooks.py,sha256=nh8IEkzAtQnbKVnh3N9CVnVKZB39Bjm3e0LFrACsLz8,6109
240
241
  metaflow/plugins/argo/generate_input_paths.py,sha256=loYsI6RFX9LlFsHb7Fe-mzlTTtRdySoOu7sYDy-uXK0,881
241
242
  metaflow/plugins/argo/jobset_input_paths.py,sha256=-h0E_e0w6FMiBUod9Rf_XOSCtZv_C0exacw4q1SfIfg,501
@@ -255,7 +256,7 @@ metaflow/plugins/aws/step_functions/event_bridge_client.py,sha256=U9-tqKdih4KR-Z
255
256
  metaflow/plugins/aws/step_functions/production_token.py,sha256=rREx9djJzKYDiGhPCZ919pSpfrBCYuhSL5WlwnAojNM,1890
256
257
  metaflow/plugins/aws/step_functions/schedule_decorator.py,sha256=Ab1rW8O_no4HNZm4__iBmFDCDW0Z8-TgK4lnxHHA6HI,1940
257
258
  metaflow/plugins/aws/step_functions/set_batch_environment.py,sha256=ibiGWFHDjKcLfprH3OsX-g2M9lUsh6J-bp7v2cdLhD4,1294
258
- metaflow/plugins/aws/step_functions/step_functions.py,sha256=Svz232OA5UewY5W9gfDk-xGqiWyCNPkuUwlPxe9g5j8,53577
259
+ metaflow/plugins/aws/step_functions/step_functions.py,sha256=3mkd9FCiWe1QlduLq73hlfdA6RonxstSYKw80jZiVqU,53819
259
260
  metaflow/plugins/aws/step_functions/step_functions_cli.py,sha256=tLIfDwgdcfBjkjmQMNgVjXY85HoDZNA6lNcOtZZZA1A,26495
260
261
  metaflow/plugins/aws/step_functions/step_functions_client.py,sha256=DKpNwAIWElvWjFANs5Ku3rgzjxFoqAD6k-EF8Xhkg3Q,4754
261
262
  metaflow/plugins/aws/step_functions/step_functions_decorator.py,sha256=jzDHYmgU_XvLffZDazR_1viow_1qQFblx9UKyjtoM_0,3788
@@ -282,12 +283,13 @@ metaflow/plugins/cards/exception.py,sha256=2UqlNb-Kxpg6cuLu2sBEIPTIElwlVBsSpeCgD
282
283
  metaflow/plugins/cards/metadata.py,sha256=tACaw7_XNAICZ4A25celIbgxUF0CxHh7BBpFzKrMLTo,487
283
284
  metaflow/plugins/cards/card_modules/__init__.py,sha256=WI2IAsFiKGyqPrHtO9S9-MbyVtUTgWJNL4xjJaBErRo,3437
284
285
  metaflow/plugins/cards/card_modules/base.html,sha256=Y208ZKIZqEWWUcoBFTLTdWKAG0C8xH5lmyCRSjaN2FY,21004
285
- metaflow/plugins/cards/card_modules/basic.py,sha256=vFWijqHnil-d337qRztfekgySSkZJjCNLUbhU-u1Csw,25405
286
+ metaflow/plugins/cards/card_modules/basic.py,sha256=b6aBg7800CjjkQb0J_TOd3JujVR10X2QoXYdwiXFbkE,25831
286
287
  metaflow/plugins/cards/card_modules/bundle.css,sha256=ms2wOKftlPM_i6bC_4BkrmqCOj8mYw9OFvRCJF9FSV4,11981
287
288
  metaflow/plugins/cards/card_modules/card.py,sha256=6sbqP5mwf7QWvQvX2N_bC78H9ixuI5sQ8612Q5islys,4627
288
289
  metaflow/plugins/cards/card_modules/components.py,sha256=Y-Yo7UgSOyTB3zs-wDfUqUKl0PI_BzeY1QGcy2fqE2M,26752
289
290
  metaflow/plugins/cards/card_modules/convert_to_native_type.py,sha256=Vcjqn5rfC0kVMdhqDwsYEjknXTbkG_ppraQrQGaQY_E,16245
290
- metaflow/plugins/cards/card_modules/main.js,sha256=72mKcMEjrne7TlLxc-LkxTJVoM4z2pLWGtU1NzHtlWM,1043628
291
+ metaflow/plugins/cards/card_modules/main.css,sha256=avu7BTB9qj0M8LvqNLUhikUFQhmAJhQQ7REcUgh9zMw,11725
292
+ metaflow/plugins/cards/card_modules/main.js,sha256=UHwjWFWevGPjOFIzWAqY63j2UdBq_z-LociaG4QVxfU,1043692
291
293
  metaflow/plugins/cards/card_modules/renderer_tools.py,sha256=uiTdKHWFInWgtfWArOUSQLnTwqVd4hAw49jfOfg8rGA,1642
292
294
  metaflow/plugins/cards/card_modules/test_cards.py,sha256=t2PZ3QnjCN_KUlDKxAt2FfK1BX2dp8rqK6TjtkCNyew,5876
293
295
  metaflow/plugins/cards/card_modules/chevron/__init__.py,sha256=SicpH_1eT76HUTA8aMuiGLRNKTqgYD1Qfutt2NdTL0E,156
@@ -425,13 +427,13 @@ metaflow/user_decorators/common.py,sha256=0u9NRLQ95TfJCjWVEOGT4MJ9WoQgAMBM9kJ2gJ
425
427
  metaflow/user_decorators/mutable_flow.py,sha256=EywKTN3cnXPQF_s62wQaC4a4aH14j8oeqzD3yZaiDxw,19467
426
428
  metaflow/user_decorators/mutable_step.py,sha256=-BY0UDXf_RCAEnC5JlLzEXGdiw1KD9oSrSxS_SWaB9Y,16791
427
429
  metaflow/user_decorators/user_flow_decorator.py,sha256=2yDwZq9QGv9W-7kEuKwa8o4ZkTvuHJ5ESz7VVrGViAI,9890
428
- metaflow/user_decorators/user_step_decorator.py,sha256=JYNGXONWCpzwn-_bF5WiAkof4Ii9tRS4xdK8ojSxG6M,26007
429
- metaflow-2.17.1.data/data/share/metaflow/devtools/Makefile,sha256=TT4TCq8ALSfqYyGqDPocN5oPcZe2FqoCZxmGO1LmyCc,13760
430
- metaflow-2.17.1.data/data/share/metaflow/devtools/Tiltfile,sha256=Ty5p6AD3MwJAcAnOGv4yMz8fExAsnNQ11r8whK6uzzw,21381
431
- metaflow-2.17.1.data/data/share/metaflow/devtools/pick_services.sh,sha256=DCnrMXwtApfx3B4S-YiZESMyAFHbXa3VuNL0MxPLyiE,2196
432
- metaflow-2.17.1.dist-info/licenses/LICENSE,sha256=nl_Lt5v9VvJ-5lWJDT4ddKAG-VZ-2IaLmbzpgYDz2hU,11343
433
- metaflow-2.17.1.dist-info/METADATA,sha256=mvfncSAe9iX2JRZxjAHd8YTHZOk8rbCAJHpU23wEtI0,6740
434
- metaflow-2.17.1.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
435
- metaflow-2.17.1.dist-info/entry_points.txt,sha256=RvEq8VFlgGe_FfqGOZi0D7ze1hLD0pAtXeNyGfzc_Yc,103
436
- metaflow-2.17.1.dist-info/top_level.txt,sha256=v1pDHoWaSaKeuc5fKTRSfsXCKSdW1zvNVmvA-i0if3o,9
437
- metaflow-2.17.1.dist-info/RECORD,,
430
+ metaflow/user_decorators/user_step_decorator.py,sha256=bZvg16RUWgfGrAx5tgKT_1aTK7urp0usK59jnV-yR8s,27054
431
+ metaflow-2.17.3.data/data/share/metaflow/devtools/Makefile,sha256=TT4TCq8ALSfqYyGqDPocN5oPcZe2FqoCZxmGO1LmyCc,13760
432
+ metaflow-2.17.3.data/data/share/metaflow/devtools/Tiltfile,sha256=Ty5p6AD3MwJAcAnOGv4yMz8fExAsnNQ11r8whK6uzzw,21381
433
+ metaflow-2.17.3.data/data/share/metaflow/devtools/pick_services.sh,sha256=DCnrMXwtApfx3B4S-YiZESMyAFHbXa3VuNL0MxPLyiE,2196
434
+ metaflow-2.17.3.dist-info/licenses/LICENSE,sha256=nl_Lt5v9VvJ-5lWJDT4ddKAG-VZ-2IaLmbzpgYDz2hU,11343
435
+ metaflow-2.17.3.dist-info/METADATA,sha256=ovW_YDMG1cJMx7y4XvjrEDnbw25yEg25Ac44GvgPwMM,6740
436
+ metaflow-2.17.3.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
437
+ metaflow-2.17.3.dist-info/entry_points.txt,sha256=RvEq8VFlgGe_FfqGOZi0D7ze1hLD0pAtXeNyGfzc_Yc,103
438
+ metaflow-2.17.3.dist-info/top_level.txt,sha256=v1pDHoWaSaKeuc5fKTRSfsXCKSdW1zvNVmvA-i0if3o,9
439
+ metaflow-2.17.3.dist-info/RECORD,,