metaflow 2.15.5__py2.py3-none-any.whl → 2.15.7__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.
- metaflow/_vendor/typeguard/_checkers.py +259 -95
- metaflow/_vendor/typeguard/_config.py +4 -4
- metaflow/_vendor/typeguard/_decorators.py +8 -12
- metaflow/_vendor/typeguard/_functions.py +33 -32
- metaflow/_vendor/typeguard/_pytest_plugin.py +40 -13
- metaflow/_vendor/typeguard/_suppression.py +3 -5
- metaflow/_vendor/typeguard/_transformer.py +84 -48
- metaflow/_vendor/typeguard/_union_transformer.py +1 -0
- metaflow/_vendor/typeguard/_utils.py +13 -9
- metaflow/_vendor/typing_extensions.py +1088 -500
- metaflow/_vendor/v3_7/__init__.py +1 -0
- metaflow/_vendor/v3_7/importlib_metadata/__init__.py +1063 -0
- metaflow/_vendor/v3_7/importlib_metadata/_adapters.py +68 -0
- metaflow/_vendor/v3_7/importlib_metadata/_collections.py +30 -0
- metaflow/_vendor/v3_7/importlib_metadata/_compat.py +71 -0
- metaflow/_vendor/v3_7/importlib_metadata/_functools.py +104 -0
- metaflow/_vendor/v3_7/importlib_metadata/_itertools.py +73 -0
- metaflow/_vendor/v3_7/importlib_metadata/_meta.py +48 -0
- metaflow/_vendor/v3_7/importlib_metadata/_text.py +99 -0
- metaflow/_vendor/v3_7/importlib_metadata/py.typed +0 -0
- metaflow/_vendor/v3_7/typeguard/__init__.py +48 -0
- metaflow/_vendor/v3_7/typeguard/_checkers.py +906 -0
- metaflow/_vendor/v3_7/typeguard/_config.py +108 -0
- metaflow/_vendor/v3_7/typeguard/_decorators.py +237 -0
- metaflow/_vendor/v3_7/typeguard/_exceptions.py +42 -0
- metaflow/_vendor/v3_7/typeguard/_functions.py +310 -0
- metaflow/_vendor/v3_7/typeguard/_importhook.py +213 -0
- metaflow/_vendor/v3_7/typeguard/_memo.py +48 -0
- metaflow/_vendor/v3_7/typeguard/_pytest_plugin.py +100 -0
- metaflow/_vendor/v3_7/typeguard/_suppression.py +88 -0
- metaflow/_vendor/v3_7/typeguard/_transformer.py +1207 -0
- metaflow/_vendor/v3_7/typeguard/_union_transformer.py +54 -0
- metaflow/_vendor/v3_7/typeguard/_utils.py +169 -0
- metaflow/_vendor/v3_7/typeguard/py.typed +0 -0
- metaflow/_vendor/v3_7/typing_extensions.py +3072 -0
- metaflow/_vendor/v3_7/zipp.py +329 -0
- metaflow/cmd/develop/stubs.py +1 -1
- metaflow/extension_support/__init__.py +1 -1
- metaflow/plugins/argo/argo_workflows.py +34 -11
- metaflow/plugins/argo/argo_workflows_deployer_objects.py +7 -6
- metaflow/plugins/pypi/utils.py +4 -0
- metaflow/runner/click_api.py +7 -2
- metaflow/vendor.py +1 -0
- metaflow/version.py +1 -1
- {metaflow-2.15.5.data → metaflow-2.15.7.data}/data/share/metaflow/devtools/Makefile +2 -2
- {metaflow-2.15.5.dist-info → metaflow-2.15.7.dist-info}/METADATA +4 -3
- {metaflow-2.15.5.dist-info → metaflow-2.15.7.dist-info}/RECORD +53 -27
- {metaflow-2.15.5.dist-info → metaflow-2.15.7.dist-info}/WHEEL +1 -1
- {metaflow-2.15.5.data → metaflow-2.15.7.data}/data/share/metaflow/devtools/Tiltfile +0 -0
- {metaflow-2.15.5.data → metaflow-2.15.7.data}/data/share/metaflow/devtools/pick_services.sh +0 -0
- {metaflow-2.15.5.dist-info → metaflow-2.15.7.dist-info}/entry_points.txt +0 -0
- {metaflow-2.15.5.dist-info → metaflow-2.15.7.dist-info/licenses}/LICENSE +0 -0
- {metaflow-2.15.5.dist-info → metaflow-2.15.7.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,329 @@
|
|
1
|
+
import io
|
2
|
+
import posixpath
|
3
|
+
import zipfile
|
4
|
+
import itertools
|
5
|
+
import contextlib
|
6
|
+
import sys
|
7
|
+
import pathlib
|
8
|
+
|
9
|
+
if sys.version_info < (3, 7):
|
10
|
+
from collections import OrderedDict
|
11
|
+
else:
|
12
|
+
OrderedDict = dict
|
13
|
+
|
14
|
+
|
15
|
+
__all__ = ['Path']
|
16
|
+
|
17
|
+
|
18
|
+
def _parents(path):
|
19
|
+
"""
|
20
|
+
Given a path with elements separated by
|
21
|
+
posixpath.sep, generate all parents of that path.
|
22
|
+
|
23
|
+
>>> list(_parents('b/d'))
|
24
|
+
['b']
|
25
|
+
>>> list(_parents('/b/d/'))
|
26
|
+
['/b']
|
27
|
+
>>> list(_parents('b/d/f/'))
|
28
|
+
['b/d', 'b']
|
29
|
+
>>> list(_parents('b'))
|
30
|
+
[]
|
31
|
+
>>> list(_parents(''))
|
32
|
+
[]
|
33
|
+
"""
|
34
|
+
return itertools.islice(_ancestry(path), 1, None)
|
35
|
+
|
36
|
+
|
37
|
+
def _ancestry(path):
|
38
|
+
"""
|
39
|
+
Given a path with elements separated by
|
40
|
+
posixpath.sep, generate all elements of that path
|
41
|
+
|
42
|
+
>>> list(_ancestry('b/d'))
|
43
|
+
['b/d', 'b']
|
44
|
+
>>> list(_ancestry('/b/d/'))
|
45
|
+
['/b/d', '/b']
|
46
|
+
>>> list(_ancestry('b/d/f/'))
|
47
|
+
['b/d/f', 'b/d', 'b']
|
48
|
+
>>> list(_ancestry('b'))
|
49
|
+
['b']
|
50
|
+
>>> list(_ancestry(''))
|
51
|
+
[]
|
52
|
+
"""
|
53
|
+
path = path.rstrip(posixpath.sep)
|
54
|
+
while path and path != posixpath.sep:
|
55
|
+
yield path
|
56
|
+
path, tail = posixpath.split(path)
|
57
|
+
|
58
|
+
|
59
|
+
_dedupe = OrderedDict.fromkeys
|
60
|
+
"""Deduplicate an iterable in original order"""
|
61
|
+
|
62
|
+
|
63
|
+
def _difference(minuend, subtrahend):
|
64
|
+
"""
|
65
|
+
Return items in minuend not in subtrahend, retaining order
|
66
|
+
with O(1) lookup.
|
67
|
+
"""
|
68
|
+
return itertools.filterfalse(set(subtrahend).__contains__, minuend)
|
69
|
+
|
70
|
+
|
71
|
+
class CompleteDirs(zipfile.ZipFile):
|
72
|
+
"""
|
73
|
+
A ZipFile subclass that ensures that implied directories
|
74
|
+
are always included in the namelist.
|
75
|
+
"""
|
76
|
+
|
77
|
+
@staticmethod
|
78
|
+
def _implied_dirs(names):
|
79
|
+
parents = itertools.chain.from_iterable(map(_parents, names))
|
80
|
+
as_dirs = (p + posixpath.sep for p in parents)
|
81
|
+
return _dedupe(_difference(as_dirs, names))
|
82
|
+
|
83
|
+
def namelist(self):
|
84
|
+
names = super(CompleteDirs, self).namelist()
|
85
|
+
return names + list(self._implied_dirs(names))
|
86
|
+
|
87
|
+
def _name_set(self):
|
88
|
+
return set(self.namelist())
|
89
|
+
|
90
|
+
def resolve_dir(self, name):
|
91
|
+
"""
|
92
|
+
If the name represents a directory, return that name
|
93
|
+
as a directory (with the trailing slash).
|
94
|
+
"""
|
95
|
+
names = self._name_set()
|
96
|
+
dirname = name + '/'
|
97
|
+
dir_match = name not in names and dirname in names
|
98
|
+
return dirname if dir_match else name
|
99
|
+
|
100
|
+
@classmethod
|
101
|
+
def make(cls, source):
|
102
|
+
"""
|
103
|
+
Given a source (filename or zipfile), return an
|
104
|
+
appropriate CompleteDirs subclass.
|
105
|
+
"""
|
106
|
+
if isinstance(source, CompleteDirs):
|
107
|
+
return source
|
108
|
+
|
109
|
+
if not isinstance(source, zipfile.ZipFile):
|
110
|
+
return cls(_pathlib_compat(source))
|
111
|
+
|
112
|
+
# Only allow for FastLookup when supplied zipfile is read-only
|
113
|
+
if 'r' not in source.mode:
|
114
|
+
cls = CompleteDirs
|
115
|
+
|
116
|
+
source.__class__ = cls
|
117
|
+
return source
|
118
|
+
|
119
|
+
|
120
|
+
class FastLookup(CompleteDirs):
|
121
|
+
"""
|
122
|
+
ZipFile subclass to ensure implicit
|
123
|
+
dirs exist and are resolved rapidly.
|
124
|
+
"""
|
125
|
+
|
126
|
+
def namelist(self):
|
127
|
+
with contextlib.suppress(AttributeError):
|
128
|
+
return self.__names
|
129
|
+
self.__names = super(FastLookup, self).namelist()
|
130
|
+
return self.__names
|
131
|
+
|
132
|
+
def _name_set(self):
|
133
|
+
with contextlib.suppress(AttributeError):
|
134
|
+
return self.__lookup
|
135
|
+
self.__lookup = super(FastLookup, self)._name_set()
|
136
|
+
return self.__lookup
|
137
|
+
|
138
|
+
|
139
|
+
def _pathlib_compat(path):
|
140
|
+
"""
|
141
|
+
For path-like objects, convert to a filename for compatibility
|
142
|
+
on Python 3.6.1 and earlier.
|
143
|
+
"""
|
144
|
+
try:
|
145
|
+
return path.__fspath__()
|
146
|
+
except AttributeError:
|
147
|
+
return str(path)
|
148
|
+
|
149
|
+
|
150
|
+
class Path:
|
151
|
+
"""
|
152
|
+
A pathlib-compatible interface for zip files.
|
153
|
+
|
154
|
+
Consider a zip file with this structure::
|
155
|
+
|
156
|
+
.
|
157
|
+
├── a.txt
|
158
|
+
└── b
|
159
|
+
├── c.txt
|
160
|
+
└── d
|
161
|
+
└── e.txt
|
162
|
+
|
163
|
+
>>> data = io.BytesIO()
|
164
|
+
>>> zf = zipfile.ZipFile(data, 'w')
|
165
|
+
>>> zf.writestr('a.txt', 'content of a')
|
166
|
+
>>> zf.writestr('b/c.txt', 'content of c')
|
167
|
+
>>> zf.writestr('b/d/e.txt', 'content of e')
|
168
|
+
>>> zf.filename = 'mem/abcde.zip'
|
169
|
+
|
170
|
+
Path accepts the zipfile object itself or a filename
|
171
|
+
|
172
|
+
>>> root = Path(zf)
|
173
|
+
|
174
|
+
From there, several path operations are available.
|
175
|
+
|
176
|
+
Directory iteration (including the zip file itself):
|
177
|
+
|
178
|
+
>>> a, b = root.iterdir()
|
179
|
+
>>> a
|
180
|
+
Path('mem/abcde.zip', 'a.txt')
|
181
|
+
>>> b
|
182
|
+
Path('mem/abcde.zip', 'b/')
|
183
|
+
|
184
|
+
name property:
|
185
|
+
|
186
|
+
>>> b.name
|
187
|
+
'b'
|
188
|
+
|
189
|
+
join with divide operator:
|
190
|
+
|
191
|
+
>>> c = b / 'c.txt'
|
192
|
+
>>> c
|
193
|
+
Path('mem/abcde.zip', 'b/c.txt')
|
194
|
+
>>> c.name
|
195
|
+
'c.txt'
|
196
|
+
|
197
|
+
Read text:
|
198
|
+
|
199
|
+
>>> c.read_text()
|
200
|
+
'content of c'
|
201
|
+
|
202
|
+
existence:
|
203
|
+
|
204
|
+
>>> c.exists()
|
205
|
+
True
|
206
|
+
>>> (b / 'missing.txt').exists()
|
207
|
+
False
|
208
|
+
|
209
|
+
Coercion to string:
|
210
|
+
|
211
|
+
>>> import os
|
212
|
+
>>> str(c).replace(os.sep, posixpath.sep)
|
213
|
+
'mem/abcde.zip/b/c.txt'
|
214
|
+
|
215
|
+
At the root, ``name``, ``filename``, and ``parent``
|
216
|
+
resolve to the zipfile. Note these attributes are not
|
217
|
+
valid and will raise a ``ValueError`` if the zipfile
|
218
|
+
has no filename.
|
219
|
+
|
220
|
+
>>> root.name
|
221
|
+
'abcde.zip'
|
222
|
+
>>> str(root.filename).replace(os.sep, posixpath.sep)
|
223
|
+
'mem/abcde.zip'
|
224
|
+
>>> str(root.parent)
|
225
|
+
'mem'
|
226
|
+
"""
|
227
|
+
|
228
|
+
__repr = "{self.__class__.__name__}({self.root.filename!r}, {self.at!r})"
|
229
|
+
|
230
|
+
def __init__(self, root, at=""):
|
231
|
+
"""
|
232
|
+
Construct a Path from a ZipFile or filename.
|
233
|
+
|
234
|
+
Note: When the source is an existing ZipFile object,
|
235
|
+
its type (__class__) will be mutated to a
|
236
|
+
specialized type. If the caller wishes to retain the
|
237
|
+
original type, the caller should either create a
|
238
|
+
separate ZipFile object or pass a filename.
|
239
|
+
"""
|
240
|
+
self.root = FastLookup.make(root)
|
241
|
+
self.at = at
|
242
|
+
|
243
|
+
def open(self, mode='r', *args, pwd=None, **kwargs):
|
244
|
+
"""
|
245
|
+
Open this entry as text or binary following the semantics
|
246
|
+
of ``pathlib.Path.open()`` by passing arguments through
|
247
|
+
to io.TextIOWrapper().
|
248
|
+
"""
|
249
|
+
if self.is_dir():
|
250
|
+
raise IsADirectoryError(self)
|
251
|
+
zip_mode = mode[0]
|
252
|
+
if not self.exists() and zip_mode == 'r':
|
253
|
+
raise FileNotFoundError(self)
|
254
|
+
stream = self.root.open(self.at, zip_mode, pwd=pwd)
|
255
|
+
if 'b' in mode:
|
256
|
+
if args or kwargs:
|
257
|
+
raise ValueError("encoding args invalid for binary operation")
|
258
|
+
return stream
|
259
|
+
return io.TextIOWrapper(stream, *args, **kwargs)
|
260
|
+
|
261
|
+
@property
|
262
|
+
def name(self):
|
263
|
+
return pathlib.Path(self.at).name or self.filename.name
|
264
|
+
|
265
|
+
@property
|
266
|
+
def suffix(self):
|
267
|
+
return pathlib.Path(self.at).suffix or self.filename.suffix
|
268
|
+
|
269
|
+
@property
|
270
|
+
def suffixes(self):
|
271
|
+
return pathlib.Path(self.at).suffixes or self.filename.suffixes
|
272
|
+
|
273
|
+
@property
|
274
|
+
def stem(self):
|
275
|
+
return pathlib.Path(self.at).stem or self.filename.stem
|
276
|
+
|
277
|
+
@property
|
278
|
+
def filename(self):
|
279
|
+
return pathlib.Path(self.root.filename).joinpath(self.at)
|
280
|
+
|
281
|
+
def read_text(self, *args, **kwargs):
|
282
|
+
with self.open('r', *args, **kwargs) as strm:
|
283
|
+
return strm.read()
|
284
|
+
|
285
|
+
def read_bytes(self):
|
286
|
+
with self.open('rb') as strm:
|
287
|
+
return strm.read()
|
288
|
+
|
289
|
+
def _is_child(self, path):
|
290
|
+
return posixpath.dirname(path.at.rstrip("/")) == self.at.rstrip("/")
|
291
|
+
|
292
|
+
def _next(self, at):
|
293
|
+
return self.__class__(self.root, at)
|
294
|
+
|
295
|
+
def is_dir(self):
|
296
|
+
return not self.at or self.at.endswith("/")
|
297
|
+
|
298
|
+
def is_file(self):
|
299
|
+
return self.exists() and not self.is_dir()
|
300
|
+
|
301
|
+
def exists(self):
|
302
|
+
return self.at in self.root._name_set()
|
303
|
+
|
304
|
+
def iterdir(self):
|
305
|
+
if not self.is_dir():
|
306
|
+
raise ValueError("Can't listdir a file")
|
307
|
+
subs = map(self._next, self.root.namelist())
|
308
|
+
return filter(self._is_child, subs)
|
309
|
+
|
310
|
+
def __str__(self):
|
311
|
+
return posixpath.join(self.root.filename, self.at)
|
312
|
+
|
313
|
+
def __repr__(self):
|
314
|
+
return self.__repr.format(self=self)
|
315
|
+
|
316
|
+
def joinpath(self, *other):
|
317
|
+
next = posixpath.join(self.at, *map(_pathlib_compat, other))
|
318
|
+
return self._next(self.root.resolve_dir(next))
|
319
|
+
|
320
|
+
__truediv__ = joinpath
|
321
|
+
|
322
|
+
@property
|
323
|
+
def parent(self):
|
324
|
+
if not self.at:
|
325
|
+
return self.filename.parent
|
326
|
+
parent_at = posixpath.dirname(self.at.rstrip('/'))
|
327
|
+
if parent_at:
|
328
|
+
parent_at += '/'
|
329
|
+
return self._next(parent_at)
|
metaflow/cmd/develop/stubs.py
CHANGED
@@ -24,7 +24,7 @@ def _check_stubs_supported():
|
|
24
24
|
if _py_ver >= (3, 8):
|
25
25
|
from importlib import metadata
|
26
26
|
elif _py_ver >= (3, 7):
|
27
|
-
from metaflow._vendor import importlib_metadata as metadata
|
27
|
+
from metaflow._vendor.v3_7 import importlib_metadata as metadata
|
28
28
|
elif _py_ver >= (3, 6):
|
29
29
|
from metaflow._vendor.v3_6 import importlib_metadata as metadata
|
30
30
|
else:
|
@@ -321,7 +321,7 @@ if _py_ver >= (3, 4):
|
|
321
321
|
if _py_ver >= (3, 8):
|
322
322
|
from importlib import metadata
|
323
323
|
elif _py_ver >= (3, 7):
|
324
|
-
from metaflow._vendor import importlib_metadata as metadata
|
324
|
+
from metaflow._vendor.v3_7 import importlib_metadata as metadata
|
325
325
|
elif _py_ver >= (3, 6):
|
326
326
|
from metaflow._vendor.v3_6 import importlib_metadata as metadata
|
327
327
|
else:
|
@@ -524,6 +524,7 @@ class ArgoWorkflows(object):
|
|
524
524
|
default_value = json.dumps(default_value)
|
525
525
|
|
526
526
|
parameters[param.name] = dict(
|
527
|
+
python_var_name=var,
|
527
528
|
name=param.name,
|
528
529
|
value=default_value,
|
529
530
|
type=param_type,
|
@@ -838,7 +839,11 @@ class ArgoWorkflows(object):
|
|
838
839
|
Arguments().parameters(
|
839
840
|
[
|
840
841
|
Parameter(parameter["name"])
|
841
|
-
.value(
|
842
|
+
.value(
|
843
|
+
"'%s'" % parameter["value"]
|
844
|
+
if parameter["type"] == "JSON"
|
845
|
+
else parameter["value"]
|
846
|
+
)
|
842
847
|
.description(parameter.get("description"))
|
843
848
|
# TODO: Better handle IncludeFile in Argo Workflows UI.
|
844
849
|
for parameter in self.parameters.values()
|
@@ -1594,11 +1599,7 @@ class ArgoWorkflows(object):
|
|
1594
1599
|
# {{foo.bar['param_name']}}.
|
1595
1600
|
# https://argoproj.github.io/argo-events/tutorials/02-parameterization/
|
1596
1601
|
# http://masterminds.github.io/sprig/strings.html
|
1597
|
-
|
1598
|
-
"--%s='{{workflow.parameters.%s}}'"
|
1599
|
-
if parameter["type"] == "JSON"
|
1600
|
-
else "--%s={{workflow.parameters.%s}}"
|
1601
|
-
)
|
1602
|
+
"--%s={{workflow.parameters.%s}}"
|
1602
1603
|
% (parameter["name"], parameter["name"])
|
1603
1604
|
for parameter in self.parameters.values()
|
1604
1605
|
]
|
@@ -3156,15 +3157,37 @@ class ArgoWorkflows(object):
|
|
3156
3157
|
# NOTE: We need the conditional logic in order to successfully fall back to the default value
|
3157
3158
|
# when the event payload does not contain a key for a parameter.
|
3158
3159
|
# NOTE: Keys might contain dashes, so use the safer 'get' for fetching the value
|
3159
|
-
data_template='{{ if (hasKey $.Input.body.payload "%s") }}{{- (get $.Input.body.payload "%s"
|
3160
|
-
% (
|
3160
|
+
data_template='{{ if (hasKey $.Input.body.payload "%s") }}{{- (get $.Input.body.payload "%s" %s) -}}{{- else -}}{{ (fail "use-default-instead") }}{{- end -}}'
|
3161
|
+
% (
|
3162
|
+
v,
|
3163
|
+
v,
|
3164
|
+
(
|
3165
|
+
"| toRawJson | squote"
|
3166
|
+
if self.parameters[
|
3167
|
+
parameter_name
|
3168
|
+
]["type"]
|
3169
|
+
== "JSON"
|
3170
|
+
else "| toRawJson"
|
3171
|
+
),
|
3172
|
+
),
|
3161
3173
|
# Unfortunately the sensor needs to
|
3162
3174
|
# record the default values for
|
3163
3175
|
# the parameters - there doesn't seem
|
3164
3176
|
# to be any way for us to skip
|
3165
|
-
value=
|
3166
|
-
|
3167
|
-
|
3177
|
+
value=(
|
3178
|
+
json.dumps(
|
3179
|
+
self.parameters[parameter_name][
|
3180
|
+
"value"
|
3181
|
+
]
|
3182
|
+
)
|
3183
|
+
if self.parameters[parameter_name][
|
3184
|
+
"type"
|
3185
|
+
]
|
3186
|
+
== "JSON"
|
3187
|
+
else self.parameters[
|
3188
|
+
parameter_name
|
3189
|
+
]["value"]
|
3190
|
+
),
|
3168
3191
|
)
|
3169
3192
|
.dest(
|
3170
3193
|
# this undocumented (mis?)feature in
|
@@ -19,6 +19,7 @@ def generate_fake_flow_file_contents(
|
|
19
19
|
):
|
20
20
|
params_code = ""
|
21
21
|
for _, param_details in param_info.items():
|
22
|
+
param_python_var_name = param_details["python_var_name"]
|
22
23
|
param_name = param_details["name"]
|
23
24
|
param_type = param_details["type"]
|
24
25
|
param_help = param_details["description"]
|
@@ -26,21 +27,21 @@ def generate_fake_flow_file_contents(
|
|
26
27
|
|
27
28
|
if param_type == "JSON":
|
28
29
|
params_code += (
|
29
|
-
f" {
|
30
|
-
f"type=JSONType, help='{param_help}', required={param_required})\n"
|
30
|
+
f" {param_python_var_name} = Parameter('{param_name}', "
|
31
|
+
f"type=JSONType, help='''{param_help}''', required={param_required})\n"
|
31
32
|
)
|
32
33
|
elif param_type == "FilePath":
|
33
34
|
is_text = param_details.get("is_text", True)
|
34
35
|
encoding = param_details.get("encoding", "utf-8")
|
35
36
|
params_code += (
|
36
|
-
f" {
|
37
|
-
f"is_text={is_text}, encoding='{encoding}', help='{param_help}', "
|
37
|
+
f" {param_python_var_name} = IncludeFile('{param_name}', "
|
38
|
+
f"is_text={is_text}, encoding='{encoding}', help='''{param_help}''', "
|
38
39
|
f"required={param_required})\n"
|
39
40
|
)
|
40
41
|
else:
|
41
42
|
params_code += (
|
42
|
-
f" {
|
43
|
-
f"type={param_type}, help='{param_help}', required={param_required})\n"
|
43
|
+
f" {param_python_var_name} = Parameter('{param_name}', "
|
44
|
+
f"type={param_type}, help='''{param_help}''', required={param_required})\n"
|
44
45
|
)
|
45
46
|
|
46
47
|
project_decorator = f"@project(name='{project_name}')\n" if project_name else ""
|
metaflow/plugins/pypi/utils.py
CHANGED
@@ -69,6 +69,8 @@ def pip_tags(python_version, mamba_platform):
|
|
69
69
|
"_2_25",
|
70
70
|
"_2_26",
|
71
71
|
"_2_27",
|
72
|
+
"_2_28",
|
73
|
+
"_2_29",
|
72
74
|
)
|
73
75
|
]
|
74
76
|
platforms.append("linux_x86_64")
|
@@ -87,6 +89,8 @@ def pip_tags(python_version, mamba_platform):
|
|
87
89
|
"_2_25",
|
88
90
|
"_2_26",
|
89
91
|
"_2_27",
|
92
|
+
"_2_28",
|
93
|
+
"_2_29",
|
90
94
|
)
|
91
95
|
]
|
92
96
|
platforms.append("linux_aarch64")
|
metaflow/runner/click_api.py
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
import os
|
2
2
|
import sys
|
3
3
|
|
4
|
-
|
4
|
+
_py_ver = sys.version_info[:2]
|
5
|
+
|
6
|
+
if _py_ver >= (3, 8):
|
7
|
+
from metaflow._vendor.typeguard import TypeCheckError, check_type
|
8
|
+
elif _py_ver >= (3, 7):
|
9
|
+
from metaflow._vendor.v3_7.typeguard import TypeCheckError, check_type
|
10
|
+
else:
|
5
11
|
raise RuntimeError(
|
6
12
|
"""
|
7
13
|
The Metaflow Programmatic API is not supported for versions of Python less than 3.7
|
@@ -35,7 +41,6 @@ from metaflow._vendor.click.types import (
|
|
35
41
|
Tuple,
|
36
42
|
UUIDParameterType,
|
37
43
|
)
|
38
|
-
from metaflow._vendor.typeguard import TypeCheckError, check_type
|
39
44
|
from metaflow.decorators import add_decorator_options
|
40
45
|
from metaflow.exception import MetaflowException
|
41
46
|
from metaflow.includefile import FilePathClass
|
metaflow/vendor.py
CHANGED
metaflow/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
metaflow_version = "2.15.
|
1
|
+
metaflow_version = "2.15.7"
|
@@ -75,7 +75,7 @@ check-docker:
|
|
75
75
|
@if [ "$(shell uname)" = "Darwin" ]; then \
|
76
76
|
open -a Docker || (echo "❌ Please start Docker Desktop" && exit 1); \
|
77
77
|
else \
|
78
|
-
|
78
|
+
docker info >/dev/null 2>&1 || (echo "❌ Docker daemon is not running." && exit 1); \
|
79
79
|
fi
|
80
80
|
@echo "✅ Docker is running"
|
81
81
|
|
@@ -339,4 +339,4 @@ ui: setup-tilt
|
|
339
339
|
|
340
340
|
.PHONY: install-helm setup-minikube setup-tilt teardown-minikube tunnel up down check-docker install-curl install-gum install-brew up down dashboard shell ui all-up help
|
341
341
|
|
342
|
-
.DEFAULT_GOAL := help
|
342
|
+
.DEFAULT_GOAL := help
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: metaflow
|
3
|
-
Version: 2.15.
|
3
|
+
Version: 2.15.7
|
4
4
|
Summary: Metaflow: More AI and ML, Less Engineering
|
5
5
|
Author: Metaflow Developers
|
6
6
|
Author-email: help@metaflow.org
|
@@ -26,13 +26,14 @@ License-File: LICENSE
|
|
26
26
|
Requires-Dist: requests
|
27
27
|
Requires-Dist: boto3
|
28
28
|
Provides-Extra: stubs
|
29
|
-
Requires-Dist: metaflow-stubs==2.15.
|
29
|
+
Requires-Dist: metaflow-stubs==2.15.7; extra == "stubs"
|
30
30
|
Dynamic: author
|
31
31
|
Dynamic: author-email
|
32
32
|
Dynamic: classifier
|
33
33
|
Dynamic: description
|
34
34
|
Dynamic: description-content-type
|
35
35
|
Dynamic: license
|
36
|
+
Dynamic: license-file
|
36
37
|
Dynamic: project-url
|
37
38
|
Dynamic: provides-extra
|
38
39
|
Dynamic: requires-dist
|