metaflow 2.12.36__tar.gz → 2.12.38__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.
Files changed (374) hide show
  1. {metaflow-2.12.36/metaflow.egg-info → metaflow-2.12.38}/PKG-INFO +3 -2
  2. {metaflow-2.12.36 → metaflow-2.12.38}/README.md +1 -0
  3. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/__init__.py +3 -0
  4. metaflow-2.12.38/metaflow/cli.py +576 -0
  5. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/cli_args.py +17 -0
  6. metaflow-2.12.38/metaflow/cli_components/dump_cmd.py +96 -0
  7. metaflow-2.12.38/metaflow/cli_components/init_cmd.py +51 -0
  8. metaflow-2.12.38/metaflow/cli_components/run_cmds.py +358 -0
  9. metaflow-2.12.38/metaflow/cli_components/step_cmd.py +189 -0
  10. metaflow-2.12.38/metaflow/cli_components/utils.py +140 -0
  11. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/cmd/develop/stub_generator.py +9 -2
  12. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/decorators.py +63 -2
  13. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/extension_support/plugins.py +41 -27
  14. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/flowspec.py +156 -16
  15. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/includefile.py +50 -22
  16. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/metaflow_config.py +1 -1
  17. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/package.py +17 -3
  18. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/parameters.py +80 -23
  19. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/__init__.py +4 -0
  20. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/airflow/airflow_cli.py +1 -0
  21. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/argo/argo_workflows.py +41 -1
  22. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/argo/argo_workflows_cli.py +1 -0
  23. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/aws/batch/batch_decorator.py +2 -2
  24. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/aws/step_functions/step_functions.py +32 -0
  25. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/aws/step_functions/step_functions_cli.py +1 -0
  26. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/kubernetes/kubernetes_decorator.py +2 -2
  27. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/pypi/conda_decorator.py +22 -0
  28. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/pypi/pypi_decorator.py +1 -0
  29. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/timeout_decorator.py +2 -2
  30. metaflow-2.12.38/metaflow/runner/__init__.py +0 -0
  31. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/runner/click_api.py +73 -19
  32. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/runtime.py +111 -73
  33. metaflow-2.12.38/metaflow/user_configs/__init__.py +0 -0
  34. metaflow-2.12.38/metaflow/user_configs/config_decorators.py +563 -0
  35. metaflow-2.12.38/metaflow/user_configs/config_options.py +495 -0
  36. metaflow-2.12.38/metaflow/user_configs/config_parameters.py +386 -0
  37. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/util.py +17 -0
  38. metaflow-2.12.38/metaflow/version.py +1 -0
  39. {metaflow-2.12.36 → metaflow-2.12.38/metaflow.egg-info}/PKG-INFO +3 -2
  40. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow.egg-info/SOURCES.txt +11 -1
  41. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow.egg-info/requires.txt +1 -1
  42. metaflow-2.12.36/metaflow/cli.py +0 -1189
  43. metaflow-2.12.36/metaflow/version.py +0 -1
  44. {metaflow-2.12.36 → metaflow-2.12.38}/LICENSE +0 -0
  45. {metaflow-2.12.36 → metaflow-2.12.38}/MANIFEST.in +0 -0
  46. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/R.py +0 -0
  47. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/__init__.py +0 -0
  48. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/click/__init__.py +0 -0
  49. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/click/_bashcomplete.py +0 -0
  50. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/click/_compat.py +0 -0
  51. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/click/_termui_impl.py +0 -0
  52. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/click/_textwrap.py +0 -0
  53. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/click/_unicodefun.py +0 -0
  54. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/click/_winconsole.py +0 -0
  55. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/click/core.py +0 -0
  56. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/click/decorators.py +0 -0
  57. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/click/exceptions.py +0 -0
  58. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/click/formatting.py +0 -0
  59. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/click/globals.py +0 -0
  60. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/click/parser.py +0 -0
  61. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/click/termui.py +0 -0
  62. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/click/testing.py +0 -0
  63. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/click/types.py +0 -0
  64. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/click/utils.py +0 -0
  65. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/importlib_metadata/__init__.py +0 -0
  66. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/importlib_metadata/_adapters.py +0 -0
  67. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/importlib_metadata/_collections.py +0 -0
  68. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/importlib_metadata/_compat.py +0 -0
  69. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/importlib_metadata/_functools.py +0 -0
  70. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/importlib_metadata/_itertools.py +0 -0
  71. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/importlib_metadata/_meta.py +0 -0
  72. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/importlib_metadata/_text.py +0 -0
  73. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/importlib_metadata/py.typed +0 -0
  74. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/packaging/__init__.py +0 -0
  75. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/packaging/_elffile.py +0 -0
  76. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/packaging/_manylinux.py +0 -0
  77. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/packaging/_musllinux.py +0 -0
  78. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/packaging/_parser.py +0 -0
  79. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/packaging/_structures.py +0 -0
  80. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/packaging/_tokenizer.py +0 -0
  81. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/packaging/markers.py +0 -0
  82. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/packaging/py.typed +0 -0
  83. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/packaging/requirements.py +0 -0
  84. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/packaging/specifiers.py +0 -0
  85. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/packaging/tags.py +0 -0
  86. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/packaging/utils.py +0 -0
  87. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/packaging/version.py +0 -0
  88. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/typeguard/__init__.py +0 -0
  89. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/typeguard/_checkers.py +0 -0
  90. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/typeguard/_config.py +0 -0
  91. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/typeguard/_decorators.py +0 -0
  92. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/typeguard/_exceptions.py +0 -0
  93. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/typeguard/_functions.py +0 -0
  94. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/typeguard/_importhook.py +0 -0
  95. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/typeguard/_memo.py +0 -0
  96. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/typeguard/_pytest_plugin.py +0 -0
  97. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/typeguard/_suppression.py +0 -0
  98. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/typeguard/_transformer.py +0 -0
  99. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/typeguard/_union_transformer.py +0 -0
  100. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/typeguard/_utils.py +0 -0
  101. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/typeguard/py.typed +0 -0
  102. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/typing_extensions.py +0 -0
  103. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/v3_5/__init__.py +0 -0
  104. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/v3_5/importlib_metadata/__init__.py +0 -0
  105. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/v3_5/importlib_metadata/_compat.py +0 -0
  106. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/v3_5/zipp.py +0 -0
  107. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/v3_6/__init__.py +0 -0
  108. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/v3_6/importlib_metadata/__init__.py +0 -0
  109. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/v3_6/importlib_metadata/_adapters.py +0 -0
  110. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/v3_6/importlib_metadata/_collections.py +0 -0
  111. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/v3_6/importlib_metadata/_compat.py +0 -0
  112. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/v3_6/importlib_metadata/_functools.py +0 -0
  113. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/v3_6/importlib_metadata/_itertools.py +0 -0
  114. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/v3_6/importlib_metadata/_meta.py +0 -0
  115. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/v3_6/importlib_metadata/_text.py +0 -0
  116. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/v3_6/importlib_metadata/py.typed +0 -0
  117. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/v3_6/typing_extensions.py +0 -0
  118. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/v3_6/zipp.py +0 -0
  119. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/_vendor/zipp.py +0 -0
  120. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/cards.py +0 -0
  121. {metaflow-2.12.36/metaflow/plugins/airflow → metaflow-2.12.38/metaflow/cli_components}/__init__.py +0 -0
  122. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/client/__init__.py +0 -0
  123. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/client/core.py +0 -0
  124. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/client/filecache.py +0 -0
  125. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/clone_util.py +0 -0
  126. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/cmd/__init__.py +0 -0
  127. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/cmd/configure_cmd.py +0 -0
  128. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/cmd/develop/__init__.py +0 -0
  129. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/cmd/develop/stubs.py +0 -0
  130. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/cmd/main_cli.py +0 -0
  131. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/cmd/tutorials_cmd.py +0 -0
  132. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/cmd/util.py +0 -0
  133. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/cmd_with_io.py +0 -0
  134. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/datastore/__init__.py +0 -0
  135. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/datastore/content_addressed_store.py +0 -0
  136. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/datastore/datastore_set.py +0 -0
  137. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/datastore/datastore_storage.py +0 -0
  138. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/datastore/exceptions.py +0 -0
  139. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/datastore/flow_datastore.py +0 -0
  140. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/datastore/inputs.py +0 -0
  141. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/datastore/task_datastore.py +0 -0
  142. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/debug.py +0 -0
  143. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/event_logger.py +0 -0
  144. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/events.py +0 -0
  145. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/exception.py +0 -0
  146. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/extension_support/__init__.py +0 -0
  147. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/extension_support/_empty_file.py +0 -0
  148. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/extension_support/cmd.py +0 -0
  149. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/extension_support/integrations.py +0 -0
  150. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/graph.py +0 -0
  151. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/info_file.py +0 -0
  152. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/integrations.py +0 -0
  153. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/lint.py +0 -0
  154. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/metadata_provider/__init__.py +0 -0
  155. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/metadata_provider/heartbeat.py +0 -0
  156. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/metadata_provider/metadata.py +0 -0
  157. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/metadata_provider/util.py +0 -0
  158. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/metaflow_config_funcs.py +0 -0
  159. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/metaflow_current.py +0 -0
  160. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/metaflow_environment.py +0 -0
  161. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/metaflow_profile.py +0 -0
  162. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/metaflow_version.py +0 -0
  163. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/mflog/__init__.py +0 -0
  164. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/mflog/mflog.py +0 -0
  165. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/mflog/save_logs.py +0 -0
  166. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/mflog/save_logs_periodically.py +0 -0
  167. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/mflog/tee.py +0 -0
  168. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/monitor.py +0 -0
  169. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/multicore_utils.py +0 -0
  170. {metaflow-2.12.36/metaflow/plugins/airflow/plumbing → metaflow-2.12.38/metaflow/plugins/airflow}/__init__.py +0 -0
  171. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/airflow/airflow.py +0 -0
  172. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/airflow/airflow_decorator.py +0 -0
  173. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/airflow/airflow_utils.py +0 -0
  174. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/airflow/dag.py +0 -0
  175. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/airflow/exception.py +0 -0
  176. {metaflow-2.12.36/metaflow/plugins/argo → metaflow-2.12.38/metaflow/plugins/airflow/plumbing}/__init__.py +0 -0
  177. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/airflow/plumbing/set_parameters.py +0 -0
  178. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/airflow/sensors/__init__.py +0 -0
  179. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/airflow/sensors/base_sensor.py +0 -0
  180. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/airflow/sensors/external_task_sensor.py +0 -0
  181. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/airflow/sensors/s3_sensor.py +0 -0
  182. {metaflow-2.12.36/metaflow/plugins/aws → metaflow-2.12.38/metaflow/plugins/argo}/__init__.py +0 -0
  183. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/argo/argo_client.py +0 -0
  184. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/argo/argo_events.py +0 -0
  185. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/argo/argo_workflows_decorator.py +0 -0
  186. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/argo/argo_workflows_deployer.py +0 -0
  187. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/argo/argo_workflows_deployer_objects.py +0 -0
  188. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/argo/capture_error.py +0 -0
  189. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/argo/generate_input_paths.py +0 -0
  190. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/argo/jobset_input_paths.py +0 -0
  191. {metaflow-2.12.36/metaflow/plugins/aws/batch → metaflow-2.12.38/metaflow/plugins/aws}/__init__.py +0 -0
  192. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/aws/aws_client.py +0 -0
  193. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/aws/aws_utils.py +0 -0
  194. {metaflow-2.12.36/metaflow/plugins/aws/secrets_manager → metaflow-2.12.38/metaflow/plugins/aws/batch}/__init__.py +0 -0
  195. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/aws/batch/batch.py +0 -0
  196. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/aws/batch/batch_cli.py +0 -0
  197. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/aws/batch/batch_client.py +0 -0
  198. {metaflow-2.12.36/metaflow/plugins/aws/step_functions → metaflow-2.12.38/metaflow/plugins/aws/secrets_manager}/__init__.py +0 -0
  199. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/aws/secrets_manager/aws_secrets_manager_secrets_provider.py +0 -0
  200. {metaflow-2.12.36/metaflow/plugins/cards → metaflow-2.12.38/metaflow/plugins/aws/step_functions}/__init__.py +0 -0
  201. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/aws/step_functions/dynamo_db_client.py +0 -0
  202. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/aws/step_functions/event_bridge_client.py +0 -0
  203. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/aws/step_functions/production_token.py +0 -0
  204. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/aws/step_functions/schedule_decorator.py +0 -0
  205. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/aws/step_functions/set_batch_environment.py +0 -0
  206. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/aws/step_functions/step_functions_client.py +0 -0
  207. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/aws/step_functions/step_functions_decorator.py +0 -0
  208. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/aws/step_functions/step_functions_deployer.py +0 -0
  209. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/aws/step_functions/step_functions_deployer_objects.py +0 -0
  210. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/azure/__init__.py +0 -0
  211. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/azure/azure_credential.py +0 -0
  212. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/azure/azure_exceptions.py +0 -0
  213. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/azure/azure_secret_manager_secrets_provider.py +0 -0
  214. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/azure/azure_tail.py +0 -0
  215. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/azure/azure_utils.py +0 -0
  216. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/azure/blob_service_client_factory.py +0 -0
  217. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/azure/includefile_support.py +0 -0
  218. {metaflow-2.12.36/metaflow/plugins/datastores → metaflow-2.12.38/metaflow/plugins/cards}/__init__.py +0 -0
  219. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_cli.py +0 -0
  220. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_client.py +0 -0
  221. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_creator.py +0 -0
  222. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_datastore.py +0 -0
  223. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_decorator.py +0 -0
  224. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_modules/__init__.py +0 -0
  225. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_modules/base.html +0 -0
  226. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_modules/basic.py +0 -0
  227. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_modules/bundle.css +0 -0
  228. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_modules/card.py +0 -0
  229. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_modules/chevron/__init__.py +0 -0
  230. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_modules/chevron/main.py +0 -0
  231. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_modules/chevron/metadata.py +0 -0
  232. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_modules/chevron/renderer.py +0 -0
  233. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_modules/chevron/tokenizer.py +0 -0
  234. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_modules/components.py +0 -0
  235. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_modules/convert_to_native_type.py +0 -0
  236. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_modules/main.js +0 -0
  237. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_modules/renderer_tools.py +0 -0
  238. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_modules/test_cards.py +0 -0
  239. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_resolver.py +0 -0
  240. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_server.py +0 -0
  241. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/card_viewer/viewer.html +0 -0
  242. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/component_serializer.py +0 -0
  243. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/cards/exception.py +0 -0
  244. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/catch_decorator.py +0 -0
  245. {metaflow-2.12.36/metaflow/plugins/env_escape/configurations/emulate_test_lib → metaflow-2.12.38/metaflow/plugins/datastores}/__init__.py +0 -0
  246. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/datastores/azure_storage.py +0 -0
  247. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/datastores/gs_storage.py +0 -0
  248. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/datastores/local_storage.py +0 -0
  249. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/datastores/s3_storage.py +0 -0
  250. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/datatools/__init__.py +0 -0
  251. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/datatools/local.py +0 -0
  252. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/datatools/s3/__init__.py +0 -0
  253. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/datatools/s3/s3.py +0 -0
  254. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/datatools/s3/s3op.py +3 -3
  255. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/datatools/s3/s3tail.py +0 -0
  256. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/datatools/s3/s3util.py +0 -0
  257. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/debug_logger.py +0 -0
  258. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/debug_monitor.py +0 -0
  259. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/env_escape/__init__.py +0 -0
  260. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/env_escape/client.py +0 -0
  261. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/env_escape/client_modules.py +0 -0
  262. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/env_escape/communication/__init__.py +0 -0
  263. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/env_escape/communication/bytestream.py +0 -0
  264. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/env_escape/communication/channel.py +0 -0
  265. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/env_escape/communication/socket_bytestream.py +0 -0
  266. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/env_escape/communication/utils.py +0 -0
  267. {metaflow-2.12.36/metaflow/plugins/frameworks → metaflow-2.12.38/metaflow/plugins/env_escape/configurations/emulate_test_lib}/__init__.py +0 -0
  268. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/env_escape/configurations/emulate_test_lib/overrides.py +0 -0
  269. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/env_escape/configurations/emulate_test_lib/server_mappings.py +0 -0
  270. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/env_escape/configurations/test_lib_impl/__init__.py +0 -0
  271. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/env_escape/configurations/test_lib_impl/test_lib.py +0 -0
  272. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/env_escape/consts.py +0 -0
  273. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/env_escape/data_transferer.py +0 -0
  274. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/env_escape/exception_transferer.py +0 -0
  275. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/env_escape/override_decorators.py +0 -0
  276. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/env_escape/server.py +0 -0
  277. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/env_escape/stub.py +0 -0
  278. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/env_escape/utils.py +0 -0
  279. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/environment_decorator.py +0 -0
  280. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/events_decorator.py +0 -0
  281. {metaflow-2.12.36/metaflow/plugins/kubernetes → metaflow-2.12.38/metaflow/plugins/frameworks}/__init__.py +0 -0
  282. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/frameworks/pytorch.py +0 -0
  283. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/gcp/__init__.py +0 -0
  284. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/gcp/gcp_secret_manager_secrets_provider.py +0 -0
  285. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/gcp/gs_exceptions.py +0 -0
  286. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/gcp/gs_storage_client_factory.py +0 -0
  287. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/gcp/gs_tail.py +0 -0
  288. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/gcp/gs_utils.py +0 -0
  289. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/gcp/includefile_support.py +0 -0
  290. {metaflow-2.12.36/metaflow/runner → metaflow-2.12.38/metaflow/plugins/kubernetes}/__init__.py +0 -0
  291. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/kubernetes/kube_utils.py +0 -0
  292. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/kubernetes/kubernetes.py +0 -0
  293. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/kubernetes/kubernetes_cli.py +1 -1
  294. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/kubernetes/kubernetes_client.py +0 -0
  295. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/kubernetes/kubernetes_job.py +0 -0
  296. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/kubernetes/kubernetes_jobsets.py +0 -0
  297. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/logs_cli.py +0 -0
  298. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/metadata_providers/__init__.py +0 -0
  299. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/metadata_providers/local.py +0 -0
  300. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/metadata_providers/service.py +0 -0
  301. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/package_cli.py +0 -0
  302. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/parallel_decorator.py +0 -0
  303. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/project_decorator.py +0 -0
  304. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/pypi/__init__.py +0 -0
  305. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/pypi/bootstrap.py +0 -0
  306. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/pypi/conda_environment.py +0 -0
  307. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/pypi/micromamba.py +0 -0
  308. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/pypi/pip.py +0 -0
  309. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/pypi/pypi_environment.py +0 -0
  310. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/pypi/utils.py +0 -0
  311. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/resources_decorator.py +0 -0
  312. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/retry_decorator.py +0 -0
  313. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/secrets/__init__.py +0 -0
  314. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/secrets/inline_secrets_provider.py +0 -0
  315. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/secrets/secrets_decorator.py +0 -0
  316. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/storage_executor.py +0 -0
  317. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/tag_cli.py +0 -0
  318. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/plugins/test_unbounded_foreach_decorator.py +0 -0
  319. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/procpoll.py +0 -0
  320. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/py.typed +0 -0
  321. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/pylint_wrapper.py +0 -0
  322. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/runner/deployer.py +0 -0
  323. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/runner/deployer_impl.py +0 -0
  324. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/runner/metaflow_runner.py +0 -0
  325. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/runner/nbdeploy.py +0 -0
  326. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/runner/nbrun.py +0 -0
  327. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/runner/subprocess_manager.py +0 -0
  328. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/runner/utils.py +0 -0
  329. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/sidecar/__init__.py +0 -0
  330. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/sidecar/sidecar.py +0 -0
  331. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/sidecar/sidecar_messages.py +0 -0
  332. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/sidecar/sidecar_subprocess.py +0 -0
  333. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/sidecar/sidecar_worker.py +1 -1
  334. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/system/__init__.py +0 -0
  335. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/system/system_logger.py +0 -0
  336. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/system/system_monitor.py +0 -0
  337. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/system/system_utils.py +0 -0
  338. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tagging_util.py +0 -0
  339. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/task.py +0 -0
  340. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tracing/__init__.py +0 -0
  341. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tracing/propagator.py +0 -0
  342. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tracing/span_exporter.py +0 -0
  343. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tracing/tracing_modules.py +0 -0
  344. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tuple_util.py +0 -0
  345. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/00-helloworld/README.md +0 -0
  346. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/00-helloworld/helloworld.py +0 -0
  347. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/01-playlist/README.md +0 -0
  348. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/01-playlist/movies.csv +0 -0
  349. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/01-playlist/playlist.ipynb +0 -0
  350. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/01-playlist/playlist.py +0 -0
  351. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/02-statistics/README.md +0 -0
  352. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/02-statistics/movies.csv +0 -0
  353. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/02-statistics/stats.ipynb +0 -0
  354. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/02-statistics/stats.py +0 -0
  355. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/03-playlist-redux/README.md +0 -0
  356. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/03-playlist-redux/playlist.py +0 -0
  357. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/04-playlist-plus/README.md +0 -0
  358. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/04-playlist-plus/playlist.py +0 -0
  359. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/05-hello-cloud/README.md +0 -0
  360. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/05-hello-cloud/hello-cloud.ipynb +0 -0
  361. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/05-hello-cloud/hello-cloud.py +0 -0
  362. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/06-statistics-redux/README.md +0 -0
  363. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/06-statistics-redux/stats.ipynb +0 -0
  364. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/07-worldview/README.md +0 -0
  365. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/07-worldview/worldview.ipynb +0 -0
  366. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/08-autopilot/README.md +0 -0
  367. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/tutorials/08-autopilot/autopilot.ipynb +0 -0
  368. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/unbounded_foreach.py +0 -0
  369. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow/vendor.py +0 -0
  370. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow.egg-info/dependency_links.txt +0 -0
  371. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow.egg-info/entry_points.txt +0 -0
  372. {metaflow-2.12.36 → metaflow-2.12.38}/metaflow.egg-info/top_level.txt +0 -0
  373. {metaflow-2.12.36 → metaflow-2.12.38}/setup.cfg +0 -0
  374. {metaflow-2.12.36 → metaflow-2.12.38}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: metaflow
3
- Version: 2.12.36
3
+ Version: 2.12.38
4
4
  Summary: Metaflow: More Data Science, 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.12.36; extra == "stubs"
29
+ Requires-Dist: metaflow-stubs==2.12.38; extra == "stubs"
30
30
 
31
31
  ![Metaflow_Logo_Horizontal_FullColor_Ribbon_Dark_RGB](https://user-images.githubusercontent.com/763451/89453116-96a57e00-d713-11ea-9fa6-82b29d4d6eff.png)
32
32
 
@@ -97,3 +97,4 @@ There are several ways to get in touch with us:
97
97
 
98
98
  ## Contributing
99
99
  We welcome contributions to Metaflow. Please see our [contribution guide](https://docs.metaflow.org/introduction/contributing-to-metaflow) for more details.
100
+
@@ -67,3 +67,4 @@ There are several ways to get in touch with us:
67
67
 
68
68
  ## Contributing
69
69
  We welcome contributions to Metaflow. Please see our [contribution guide](https://docs.metaflow.org/introduction/contributing-to-metaflow) for more details.
70
+
@@ -103,6 +103,9 @@ from .flowspec import FlowSpec
103
103
 
104
104
  from .parameters import Parameter, JSONTypeClass, JSONType
105
105
 
106
+ from .user_configs.config_parameters import Config, config_expr
107
+ from .user_configs.config_decorators import CustomFlowDecorator, CustomStepDecorator
108
+
106
109
  # data layer
107
110
  # For historical reasons, we make metaflow.plugins.datatools accessible as
108
111
  # metaflow.datatools. S3 is also a tool that has historically been available at the
@@ -0,0 +1,576 @@
1
+ import functools
2
+ import inspect
3
+ import sys
4
+ import traceback
5
+ from datetime import datetime
6
+
7
+ import metaflow.tracing as tracing
8
+ from metaflow._vendor import click
9
+
10
+ from . import decorators, lint, metaflow_version, parameters, plugins
11
+ from .cli_args import cli_args
12
+ from .cli_components.utils import LazyGroup, LazyPluginCommandCollection
13
+ from .datastore import FlowDataStore
14
+ from .exception import CommandException, MetaflowException
15
+ from .flowspec import _FlowState
16
+ from .graph import FlowGraph
17
+ from .metaflow_config import (
18
+ DECOSPECS,
19
+ DEFAULT_DATASTORE,
20
+ DEFAULT_ENVIRONMENT,
21
+ DEFAULT_EVENT_LOGGER,
22
+ DEFAULT_METADATA,
23
+ DEFAULT_MONITOR,
24
+ DEFAULT_PACKAGE_SUFFIXES,
25
+ )
26
+ from .metaflow_current import current
27
+ from metaflow.system import _system_monitor, _system_logger
28
+ from .metaflow_environment import MetaflowEnvironment
29
+ from .plugins import (
30
+ DATASTORES,
31
+ ENVIRONMENTS,
32
+ LOGGING_SIDECARS,
33
+ METADATA_PROVIDERS,
34
+ MONITOR_SIDECARS,
35
+ )
36
+ from .pylint_wrapper import PyLint
37
+ from .R import metaflow_r_version, use_r
38
+ from .util import resolve_identity
39
+ from .user_configs.config_options import LocalFileInput, config_options
40
+ from .user_configs.config_parameters import ConfigValue
41
+
42
+ ERASE_TO_EOL = "\033[K"
43
+ HIGHLIGHT = "red"
44
+ INDENT = " " * 4
45
+
46
+ LOGGER_TIMESTAMP = "magenta"
47
+ LOGGER_COLOR = "green"
48
+ LOGGER_BAD_COLOR = "red"
49
+
50
+
51
+ def echo_dev_null(*args, **kwargs):
52
+ pass
53
+
54
+
55
+ def echo_always(line, **kwargs):
56
+ kwargs["err"] = kwargs.get("err", True)
57
+ if kwargs.pop("indent", None):
58
+ line = "\n".join(INDENT + x for x in line.splitlines())
59
+ if "nl" not in kwargs or kwargs["nl"]:
60
+ line += ERASE_TO_EOL
61
+ top = kwargs.pop("padding_top", None)
62
+ bottom = kwargs.pop("padding_bottom", None)
63
+ highlight = kwargs.pop("highlight", HIGHLIGHT)
64
+ if top:
65
+ click.secho(ERASE_TO_EOL, **kwargs)
66
+
67
+ hl_bold = kwargs.pop("highlight_bold", True)
68
+ nl = kwargs.pop("nl", True)
69
+ fg = kwargs.pop("fg", None)
70
+ bold = kwargs.pop("bold", False)
71
+ kwargs["nl"] = False
72
+ hl = True
73
+ nobold = kwargs.pop("no_bold", False)
74
+ if nobold:
75
+ click.secho(line, **kwargs)
76
+ else:
77
+ for span in line.split("*"):
78
+ if hl:
79
+ hl = False
80
+ kwargs["fg"] = fg
81
+ kwargs["bold"] = bold
82
+ click.secho(span, **kwargs)
83
+ else:
84
+ hl = True
85
+ kwargs["fg"] = highlight
86
+ kwargs["bold"] = hl_bold
87
+ click.secho(span, **kwargs)
88
+ if nl:
89
+ kwargs["nl"] = True
90
+ click.secho("", **kwargs)
91
+ if bottom:
92
+ click.secho(ERASE_TO_EOL, **kwargs)
93
+
94
+
95
+ def logger(body="", system_msg=False, head="", bad=False, timestamp=True, nl=True):
96
+ if timestamp:
97
+ if timestamp is True:
98
+ dt = datetime.now()
99
+ else:
100
+ dt = timestamp
101
+ tstamp = dt.strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
102
+ click.secho(tstamp + " ", fg=LOGGER_TIMESTAMP, nl=False)
103
+ if head:
104
+ click.secho(head, fg=LOGGER_COLOR, nl=False)
105
+ click.secho(body, bold=system_msg, fg=LOGGER_BAD_COLOR if bad else None, nl=nl)
106
+
107
+
108
+ def config_merge_cb(ctx, param, value):
109
+ # Callback to:
110
+ # - read the Click auto_envvar variable from both the
111
+ # environment AND the configuration
112
+ # - merge that value with the value passed in the command line (value)
113
+ # - return the value as a tuple
114
+ # Note that this function gets called even if there is no option passed on the
115
+ # command line.
116
+ # NOTE: Assumes that ctx.auto_envvar_prefix is set to METAFLOW (same as in
117
+ # from_conf)
118
+
119
+ # Special case where DECOSPECS and value are the same. This happens
120
+ # when there is no --with option at the TL and DECOSPECS is read from
121
+ # the env var. In this case, click also passes it as value
122
+ splits = DECOSPECS.split()
123
+ if len(splits) == len(value) and all([a == b for (a, b) in zip(splits, value)]):
124
+ return value
125
+ return tuple(list(value) + DECOSPECS.split())
126
+
127
+
128
+ @click.group(
129
+ cls=LazyGroup,
130
+ lazy_subcommands={
131
+ "init": "metaflow.cli_components.init_cmd.init",
132
+ "dump": "metaflow.cli_components.dump_cmd.dump",
133
+ "step": "metaflow.cli_components.step_cmd.step",
134
+ "run": "metaflow.cli_components.run_cmds.run",
135
+ "resume": "metaflow.cli_components.run_cmds.resume",
136
+ },
137
+ )
138
+ def cli(ctx):
139
+ pass
140
+
141
+
142
+ @cli.command(help="Check that the flow is valid (default).")
143
+ @click.option(
144
+ "--warnings/--no-warnings",
145
+ default=False,
146
+ show_default=True,
147
+ help="Show all Pylint warnings, not just errors.",
148
+ )
149
+ @click.pass_obj
150
+ def check(obj, warnings=False):
151
+ if obj.is_quiet:
152
+ echo = echo_dev_null
153
+ else:
154
+ echo = echo_always
155
+ _check(
156
+ echo, obj.graph, obj.flow, obj.environment, pylint=obj.pylint, warnings=warnings
157
+ )
158
+ fname = inspect.getfile(obj.flow.__class__)
159
+ echo(
160
+ "\n*'{cmd} show'* shows a description of this flow.\n"
161
+ "*'{cmd} run'* runs the flow locally.\n"
162
+ "*'{cmd} help'* shows all available commands and options.\n".format(cmd=fname),
163
+ highlight="magenta",
164
+ highlight_bold=False,
165
+ )
166
+
167
+
168
+ @cli.command(help="Show structure of the flow.")
169
+ @click.pass_obj
170
+ def show(obj):
171
+ echo_always("\n%s" % obj.graph.doc)
172
+ for _, node in sorted((n.func_lineno, n) for n in obj.graph):
173
+ echo_always("\nStep *%s*" % node.name, err=False)
174
+ echo_always(node.doc if node.doc else "?", indent=True, err=False)
175
+ if node.type != "end":
176
+ echo_always(
177
+ "*=>* %s" % ", ".join("*%s*" % n for n in node.out_funcs),
178
+ indent=True,
179
+ highlight="magenta",
180
+ highlight_bold=False,
181
+ err=False,
182
+ )
183
+ echo_always("")
184
+
185
+
186
+ @cli.command(help="Show all available commands.")
187
+ @click.pass_context
188
+ def help(ctx):
189
+ print(ctx.parent.get_help())
190
+
191
+
192
+ @cli.command(help="Output internal state of the flow graph.")
193
+ @click.option("--json", is_flag=True, help="Output the flow graph in JSON format.")
194
+ @click.pass_obj
195
+ def output_raw(obj, json):
196
+ if json:
197
+ import json as _json
198
+
199
+ _msg = "Internal representation of the flow in JSON format:"
200
+ _graph_dict, _graph_struct = obj.graph.output_steps()
201
+ _graph = _json.dumps(
202
+ dict(graph=_graph_dict, graph_structure=_graph_struct), indent=4
203
+ )
204
+ else:
205
+ _graph = str(obj.graph)
206
+ _msg = "Internal representation of the flow:"
207
+ echo(_msg, fg="magenta", bold=False)
208
+ echo_always(_graph, err=False)
209
+
210
+
211
+ @cli.command(help="Visualize the flow with Graphviz.")
212
+ @click.pass_obj
213
+ def output_dot(obj):
214
+ echo("Visualizing the flow as a GraphViz graph", fg="magenta", bold=False)
215
+ echo(
216
+ "Try piping the output to 'dot -Tpng -o graph.png' to produce "
217
+ "an actual image.",
218
+ indent=True,
219
+ )
220
+ echo_always(obj.graph.output_dot(), err=False)
221
+
222
+
223
+ @cli.command(help="Print the Metaflow version")
224
+ @click.pass_obj
225
+ def version(obj):
226
+ echo_always(obj.version)
227
+
228
+
229
+ # NOTE: add_decorator_options should be TL because it checks to make sure
230
+ # that no option conflict with the ones below
231
+ @decorators.add_decorator_options
232
+ @config_options
233
+ @click.command(
234
+ cls=LazyPluginCommandCollection,
235
+ sources=[cli],
236
+ lazy_sources=plugins.get_plugin_cli_path(),
237
+ invoke_without_command=True,
238
+ )
239
+ @tracing.cli_entrypoint("cli/start")
240
+ # Quiet is eager to make sure it is available when processing --config options since
241
+ # we need it to construct a context to pass to any DeployTimeField for the default
242
+ # value.
243
+ @click.option(
244
+ "--quiet/--not-quiet",
245
+ show_default=True,
246
+ default=False,
247
+ help="Suppress unnecessary messages",
248
+ is_eager=True,
249
+ )
250
+ @click.option(
251
+ "--metadata",
252
+ default=DEFAULT_METADATA,
253
+ show_default=True,
254
+ type=click.Choice([m.TYPE for m in METADATA_PROVIDERS]),
255
+ help="Metadata service type",
256
+ )
257
+ @click.option(
258
+ "--environment",
259
+ default=DEFAULT_ENVIRONMENT,
260
+ show_default=True,
261
+ type=click.Choice(["local"] + [m.TYPE for m in ENVIRONMENTS]),
262
+ help="Execution environment type",
263
+ )
264
+ # See comment for --quiet
265
+ @click.option(
266
+ "--datastore",
267
+ default=DEFAULT_DATASTORE,
268
+ show_default=True,
269
+ type=click.Choice([d.TYPE for d in DATASTORES]),
270
+ help="Data backend type",
271
+ is_eager=True,
272
+ )
273
+ @click.option("--datastore-root", help="Root path for datastore")
274
+ @click.option(
275
+ "--package-suffixes",
276
+ help="A comma-separated list of file suffixes to include in the code package.",
277
+ default=DEFAULT_PACKAGE_SUFFIXES,
278
+ show_default=True,
279
+ )
280
+ @click.option(
281
+ "--with",
282
+ "decospecs",
283
+ multiple=True,
284
+ help="Add a decorator to all steps. You can specify this option "
285
+ "multiple times to attach multiple decorators in steps.",
286
+ callback=config_merge_cb,
287
+ )
288
+ @click.option(
289
+ "--pylint/--no-pylint",
290
+ default=True,
291
+ show_default=True,
292
+ help="Run Pylint on the flow if pylint is installed.",
293
+ )
294
+ @click.option(
295
+ "--event-logger",
296
+ default=DEFAULT_EVENT_LOGGER,
297
+ show_default=True,
298
+ type=click.Choice(LOGGING_SIDECARS),
299
+ help="type of event logger used",
300
+ )
301
+ @click.option(
302
+ "--monitor",
303
+ default=DEFAULT_MONITOR,
304
+ show_default=True,
305
+ type=click.Choice(MONITOR_SIDECARS),
306
+ help="Monitoring backend type",
307
+ )
308
+ @click.option(
309
+ "--local-config-file",
310
+ type=LocalFileInput(exists=True, readable=True, dir_okay=False, resolve_path=True),
311
+ required=False,
312
+ default=None,
313
+ help="A filename containing the dumped configuration values. Internal use only.",
314
+ hidden=True,
315
+ is_eager=True,
316
+ )
317
+ @click.pass_context
318
+ def start(
319
+ ctx,
320
+ quiet=False,
321
+ metadata=None,
322
+ environment=None,
323
+ datastore=None,
324
+ datastore_root=None,
325
+ decospecs=None,
326
+ package_suffixes=None,
327
+ pylint=None,
328
+ event_logger=None,
329
+ monitor=None,
330
+ local_config_file=None,
331
+ config_file_options=None,
332
+ config_value_options=None,
333
+ **deco_options
334
+ ):
335
+ if quiet:
336
+ echo = echo_dev_null
337
+ else:
338
+ echo = echo_always
339
+
340
+ ctx.obj.version = metaflow_version.get_version()
341
+ version = ctx.obj.version
342
+ if use_r():
343
+ version = metaflow_r_version()
344
+
345
+ echo("Metaflow %s" % version, fg="magenta", bold=True, nl=False)
346
+ echo(" executing *%s*" % ctx.obj.flow.name, fg="magenta", nl=False)
347
+ echo(" for *%s*" % resolve_identity(), fg="magenta")
348
+
349
+ # At this point, we are able to resolve the user-configuration options so we can
350
+ # process all those decorators that the user added that will modify the flow based
351
+ # on those configurations. It is important to do this as early as possible since it
352
+ # actually modifies the flow itself
353
+
354
+ # When we process the options, the first one processed will return None and the
355
+ # second one processed will return the actual options. The order of processing
356
+ # depends on what (and in what order) the user specifies on the command line.
357
+ config_options = config_file_options or config_value_options
358
+ ctx.obj.flow = ctx.obj.flow._process_config_decorators(config_options)
359
+
360
+ cli_args._set_top_kwargs(ctx.params)
361
+ ctx.obj.echo = echo
362
+ ctx.obj.echo_always = echo_always
363
+ ctx.obj.is_quiet = quiet
364
+ ctx.obj.graph = ctx.obj.flow._graph
365
+ ctx.obj.logger = logger
366
+ ctx.obj.pylint = pylint
367
+ ctx.obj.check = functools.partial(_check, echo)
368
+ ctx.obj.top_cli = cli
369
+ ctx.obj.package_suffixes = package_suffixes.split(",")
370
+
371
+ ctx.obj.environment = [
372
+ e for e in ENVIRONMENTS + [MetaflowEnvironment] if e.TYPE == environment
373
+ ][0](ctx.obj.flow)
374
+ ctx.obj.environment.validate_environment(ctx.obj.logger, datastore)
375
+
376
+ ctx.obj.event_logger = LOGGING_SIDECARS[event_logger](
377
+ flow=ctx.obj.flow, env=ctx.obj.environment
378
+ )
379
+ ctx.obj.event_logger.start()
380
+ _system_logger.init_system_logger(ctx.obj.flow.name, ctx.obj.event_logger)
381
+
382
+ ctx.obj.monitor = MONITOR_SIDECARS[monitor](
383
+ flow=ctx.obj.flow, env=ctx.obj.environment
384
+ )
385
+ ctx.obj.monitor.start()
386
+ _system_monitor.init_system_monitor(ctx.obj.flow.name, ctx.obj.monitor)
387
+
388
+ ctx.obj.metadata = [m for m in METADATA_PROVIDERS if m.TYPE == metadata][0](
389
+ ctx.obj.environment, ctx.obj.flow, ctx.obj.event_logger, ctx.obj.monitor
390
+ )
391
+
392
+ ctx.obj.datastore_impl = [d for d in DATASTORES if d.TYPE == datastore][0]
393
+
394
+ if datastore_root is None:
395
+ datastore_root = ctx.obj.datastore_impl.get_datastore_root_from_config(
396
+ ctx.obj.echo
397
+ )
398
+ if datastore_root is None:
399
+ raise CommandException(
400
+ "Could not find the location of the datastore -- did you correctly set the "
401
+ "METAFLOW_DATASTORE_SYSROOT_%s environment variable?" % datastore.upper()
402
+ )
403
+
404
+ ctx.obj.datastore_impl.datastore_root = datastore_root
405
+
406
+ FlowDataStore.default_storage_impl = ctx.obj.datastore_impl
407
+ ctx.obj.flow_datastore = FlowDataStore(
408
+ ctx.obj.flow.name,
409
+ ctx.obj.environment,
410
+ ctx.obj.metadata,
411
+ ctx.obj.event_logger,
412
+ ctx.obj.monitor,
413
+ )
414
+
415
+ ctx.obj.config_options = config_options
416
+
417
+ decorators._init(ctx.obj.flow)
418
+
419
+ # It is important to initialize flow decorators early as some of the
420
+ # things they provide may be used by some of the objects initialized after.
421
+ decorators._init_flow_decorators(
422
+ ctx.obj.flow,
423
+ ctx.obj.graph,
424
+ ctx.obj.environment,
425
+ ctx.obj.flow_datastore,
426
+ ctx.obj.metadata,
427
+ ctx.obj.logger,
428
+ echo,
429
+ deco_options,
430
+ )
431
+
432
+ # In the case of run/resume, we will want to apply the TL decospecs
433
+ # *after* the run decospecs so that they don't take precedence. In other
434
+ # words, for the same decorator, we want `myflow.py run --with foo` to
435
+ # take precedence over any other `foo` decospec
436
+ ctx.obj.tl_decospecs = list(decospecs or [])
437
+
438
+ # initialize current and parameter context for deploy-time parameters
439
+ current._set_env(flow=ctx.obj.flow, is_running=False)
440
+ parameters.set_parameter_context(
441
+ ctx.obj.flow.name,
442
+ ctx.obj.echo,
443
+ ctx.obj.flow_datastore,
444
+ {
445
+ k: ConfigValue(v)
446
+ for k, v in ctx.obj.flow.__class__._flow_state.get(
447
+ _FlowState.CONFIGS, {}
448
+ ).items()
449
+ },
450
+ )
451
+
452
+ if (
453
+ hasattr(ctx, "saved_args")
454
+ and ctx.saved_args
455
+ and ctx.saved_args[0] not in ("run", "resume")
456
+ ):
457
+ # run/resume are special cases because they can add more decorators with --with,
458
+ # so they have to take care of themselves.
459
+ all_decospecs = ctx.obj.tl_decospecs + list(
460
+ ctx.obj.environment.decospecs() or []
461
+ )
462
+ if all_decospecs:
463
+ decorators._attach_decorators(ctx.obj.flow, all_decospecs)
464
+ decorators._init(ctx.obj.flow)
465
+ # Regenerate graph if we attached more decorators
466
+ ctx.obj.graph = FlowGraph(ctx.obj.flow.__class__)
467
+
468
+ decorators._init_step_decorators(
469
+ ctx.obj.flow,
470
+ ctx.obj.graph,
471
+ ctx.obj.environment,
472
+ ctx.obj.flow_datastore,
473
+ ctx.obj.logger,
474
+ )
475
+
476
+ # TODO (savin): Enable lazy instantiation of package
477
+ ctx.obj.package = None
478
+
479
+ if ctx.invoked_subcommand is None:
480
+ ctx.invoke(check)
481
+
482
+
483
+ def _check(echo, graph, flow, environment, pylint=True, warnings=False, **kwargs):
484
+ echo("Validating your flow...", fg="magenta", bold=False)
485
+ linter = lint.linter
486
+ # TODO set linter settings
487
+ linter.run_checks(graph, **kwargs)
488
+ echo("The graph looks good!", fg="green", bold=True, indent=True)
489
+ if pylint:
490
+ echo("Running pylint...", fg="magenta", bold=False)
491
+ fname = inspect.getfile(flow.__class__)
492
+ pylint = PyLint(fname)
493
+ if pylint.has_pylint():
494
+ pylint_is_happy, pylint_exception_msg = pylint.run(
495
+ warnings=warnings,
496
+ pylint_config=environment.pylint_config(),
497
+ logger=echo_always,
498
+ )
499
+
500
+ if pylint_is_happy:
501
+ echo("Pylint is happy!", fg="green", bold=True, indent=True)
502
+ else:
503
+ echo(
504
+ "Pylint couldn't analyze your code.\n\tPylint exception: %s"
505
+ % pylint_exception_msg,
506
+ fg="red",
507
+ bold=True,
508
+ indent=True,
509
+ )
510
+ echo("Skipping Pylint checks.", fg="red", bold=True, indent=True)
511
+ else:
512
+ echo(
513
+ "Pylint not found, so extra checks are disabled.",
514
+ fg="green",
515
+ indent=True,
516
+ bold=False,
517
+ )
518
+
519
+
520
+ def print_metaflow_exception(ex):
521
+ echo_always(ex.headline, indent=True, nl=False, bold=True)
522
+ if ex.line_no is None:
523
+ echo_always(":")
524
+ else:
525
+ echo_always(" on line %d:" % ex.line_no, bold=True)
526
+ echo_always(ex.message, indent=True, bold=False, padding_bottom=True)
527
+
528
+
529
+ def print_unknown_exception(ex):
530
+ echo_always("Internal error", indent=True, bold=True)
531
+ echo_always(traceback.format_exc(), highlight=None, highlight_bold=False)
532
+
533
+
534
+ class CliState(object):
535
+ def __init__(self, flow):
536
+ self.flow = flow
537
+
538
+
539
+ def main(flow, args=None, handle_exceptions=True, entrypoint=None):
540
+ # Ignore warning(s) and prevent spamming the end-user.
541
+ # TODO: This serves as a short term workaround for RuntimeWarning(s) thrown
542
+ # in py3.8 related to log buffering (bufsize=1).
543
+ import warnings
544
+
545
+ warnings.filterwarnings("ignore")
546
+ if entrypoint is None:
547
+ entrypoint = [sys.executable, sys.argv[0]]
548
+
549
+ state = CliState(flow)
550
+ state.entrypoint = entrypoint
551
+
552
+ try:
553
+ if args is None:
554
+ start(auto_envvar_prefix="METAFLOW", obj=state)
555
+ else:
556
+ try:
557
+ start(args=args, obj=state, auto_envvar_prefix="METAFLOW")
558
+ except SystemExit as e:
559
+ return e.code
560
+ except MetaflowException as x:
561
+ if handle_exceptions:
562
+ print_metaflow_exception(x)
563
+ sys.exit(1)
564
+ else:
565
+ raise
566
+ except Exception as x:
567
+ if handle_exceptions:
568
+ print_unknown_exception(x)
569
+ sys.exit(1)
570
+ else:
571
+ raise
572
+ finally:
573
+ if hasattr(state, "monitor") and state.monitor is not None:
574
+ state.monitor.terminate()
575
+ if hasattr(state, "event_logger") and state.event_logger is not None:
576
+ state.event_logger.terminate()
@@ -12,7 +12,14 @@
12
12
  # well as the converting of options in runtime.py. We should make it so that we
13
13
  # can properly shlex things and un-shlex when using. Ideally this should all be
14
14
  # done in one place.
15
+ #
16
+ # NOTE: There is an important between these two as well:
17
+ # - this one will include local_config_file whereas the other one WILL NOT.
18
+ # This is because this is used when constructing the parallel UBF command which
19
+ # executes locally and therefore needs the local_config_file but the other (remote)
20
+ # commands do not.
15
21
 
22
+ from .user_configs.config_options import ConfigInput
16
23
  from .util import to_unicode
17
24
 
18
25
 
@@ -65,6 +72,16 @@ class CLIArgs(object):
65
72
  # keyword in Python, so we call it 'decospecs' in click args
66
73
  if k == "decospecs":
67
74
  k = "with"
75
+ if k in ("config_file_options", "config_value_options"):
76
+ # Special handling here since we gather them all in one option but actually
77
+ # need to send them one at a time using --config-value <name> kv.<name>.
78
+ # Note it can be either config_file_options or config_value_options depending
79
+ # on click processing order.
80
+ for config_name in v.keys():
81
+ yield "--config-value"
82
+ yield to_unicode(config_name)
83
+ yield to_unicode(ConfigInput.make_key_name(config_name))
84
+ continue
68
85
  k = k.replace("_", "-")
69
86
  v = v if isinstance(v, (list, tuple, set)) else [v]
70
87
  for value in v: