hydraflow 0.12.0__py3-none-any.whl → 0.12.2__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.
- hydraflow/core/main.py +2 -1
- hydraflow/executor/parser.py +153 -53
- {hydraflow-0.12.0.dist-info → hydraflow-0.12.2.dist-info}/METADATA +1 -1
- {hydraflow-0.12.0.dist-info → hydraflow-0.12.2.dist-info}/RECORD +7 -7
- {hydraflow-0.12.0.dist-info → hydraflow-0.12.2.dist-info}/WHEEL +0 -0
- {hydraflow-0.12.0.dist-info → hydraflow-0.12.2.dist-info}/entry_points.txt +0 -0
- {hydraflow-0.12.0.dist-info → hydraflow-0.12.2.dist-info}/licenses/LICENSE +0 -0
hydraflow/core/main.py
CHANGED
@@ -16,6 +16,7 @@ used to wrap experiment entry points. This decorator handles:
|
|
16
16
|
|
17
17
|
Example:
|
18
18
|
```python
|
19
|
+
import hydraflow
|
19
20
|
from dataclasses import dataclass
|
20
21
|
from mlflow.entities import Run
|
21
22
|
|
@@ -24,7 +25,7 @@ Example:
|
|
24
25
|
learning_rate: float
|
25
26
|
batch_size: int
|
26
27
|
|
27
|
-
@main(Config)
|
28
|
+
@hydraflow.main(Config)
|
28
29
|
def train(run: Run, config: Config):
|
29
30
|
# Your training code here
|
30
31
|
pass
|
hydraflow/executor/parser.py
CHANGED
@@ -48,7 +48,7 @@ def to_number(x: str) -> int | float:
|
|
48
48
|
return int(x)
|
49
49
|
|
50
50
|
|
51
|
-
def
|
51
|
+
def count_decimal_digits(x: str) -> int:
|
52
52
|
"""Count decimal places in a string.
|
53
53
|
|
54
54
|
Examine a string representing a number and returns the count
|
@@ -62,13 +62,13 @@ def count_decimal_places(x: str) -> int:
|
|
62
62
|
int: The number of decimal places.
|
63
63
|
|
64
64
|
Examples:
|
65
|
-
>>>
|
65
|
+
>>> count_decimal_digits("1")
|
66
66
|
0
|
67
|
-
>>>
|
67
|
+
>>> count_decimal_digits("-1.2")
|
68
68
|
1
|
69
|
-
>>>
|
69
|
+
>>> count_decimal_digits("1.234")
|
70
70
|
3
|
71
|
-
>>>
|
71
|
+
>>> count_decimal_digits("-1.234e-10")
|
72
72
|
3
|
73
73
|
|
74
74
|
"""
|
@@ -82,8 +82,52 @@ def count_decimal_places(x: str) -> int:
|
|
82
82
|
return len(decimal_part)
|
83
83
|
|
84
84
|
|
85
|
+
def count_integer_digits(num_str: str) -> int:
|
86
|
+
"""Count the number of digits in the integer part of a number.
|
87
|
+
|
88
|
+
Consider only the integer part of a number, even if it is in
|
89
|
+
scientific notation.
|
90
|
+
|
91
|
+
Args:
|
92
|
+
num_str (str): The string representing a number.
|
93
|
+
|
94
|
+
Returns:
|
95
|
+
int: The number of digits in the integer part of a number.
|
96
|
+
(excluding the sign)
|
97
|
+
|
98
|
+
Examples:
|
99
|
+
>>> count_integer_digits("123")
|
100
|
+
3
|
101
|
+
>>> count_integer_digits("-123.45")
|
102
|
+
3
|
103
|
+
>>> count_integer_digits("+0.00123")
|
104
|
+
1
|
105
|
+
>>> count_integer_digits("-1.200")
|
106
|
+
1
|
107
|
+
>>> count_integer_digits("+1.20e3")
|
108
|
+
1
|
109
|
+
>>> count_integer_digits("-0.120e-3")
|
110
|
+
1
|
111
|
+
>>> count_integer_digits(".123")
|
112
|
+
0
|
113
|
+
|
114
|
+
"""
|
115
|
+
if num_str.startswith(("+", "-")):
|
116
|
+
num_str = num_str[1:]
|
117
|
+
|
118
|
+
if "e" in num_str.lower():
|
119
|
+
num_str = num_str.lower().split("e")[0]
|
120
|
+
|
121
|
+
if "." in num_str:
|
122
|
+
int_part = num_str.split(".")[0]
|
123
|
+
if not int_part:
|
124
|
+
return 0
|
125
|
+
return len(int_part)
|
126
|
+
return len(num_str)
|
127
|
+
|
128
|
+
|
85
129
|
def is_number(x: str) -> bool:
|
86
|
-
"""Check if a string
|
130
|
+
"""Check if a string represents a valid number.
|
87
131
|
|
88
132
|
Args:
|
89
133
|
x (str): The string to check.
|
@@ -140,18 +184,46 @@ def _get_range(arg: str) -> tuple[float, float, float]:
|
|
140
184
|
|
141
185
|
|
142
186
|
def _arange(start: float, step: float, stop: float) -> list[float]:
|
187
|
+
"""Generate a range of floating point numbers.
|
188
|
+
|
189
|
+
This function generates a range of floating point numbers
|
190
|
+
with protection against rounding errors.
|
191
|
+
|
192
|
+
Args:
|
193
|
+
start (float): The starting value.
|
194
|
+
step (float): The step size.
|
195
|
+
stop (float): The end value (inclusive).
|
196
|
+
|
197
|
+
Returns:
|
198
|
+
list[float]: A list of floating point numbers from start to stop
|
199
|
+
(inclusive) with the given step.
|
200
|
+
|
201
|
+
"""
|
202
|
+
if step == 0:
|
203
|
+
raise ValueError("Step cannot be zero")
|
204
|
+
|
205
|
+
epsilon = min(abs(start), abs(stop)) * 1e-5
|
206
|
+
|
143
207
|
result = []
|
144
208
|
current = start
|
145
209
|
|
146
|
-
|
147
|
-
|
148
|
-
|
210
|
+
if step > 0:
|
211
|
+
while current <= stop + epsilon:
|
212
|
+
result.append(current)
|
213
|
+
current += step
|
214
|
+
else:
|
215
|
+
while current >= stop - epsilon:
|
216
|
+
result.append(current)
|
217
|
+
current += step
|
149
218
|
|
150
219
|
return result
|
151
220
|
|
152
221
|
|
153
222
|
def split_suffix(arg: str) -> tuple[str, str]:
|
154
|
-
"""Split a string into prefix and suffix.
|
223
|
+
"""Split a string into the prefix and suffix.
|
224
|
+
|
225
|
+
The suffix is the part of the string that starts with a colon (:).
|
226
|
+
The prefix is the part of the string that precedes the suffix.
|
155
227
|
|
156
228
|
Args:
|
157
229
|
arg (str): The string to split.
|
@@ -194,6 +266,16 @@ def add_exponent(value: str, exponent: str) -> str:
|
|
194
266
|
Returns:
|
195
267
|
str: The value with the exponent added.
|
196
268
|
|
269
|
+
Examples:
|
270
|
+
>>> add_exponent("1", "e3")
|
271
|
+
'1e3'
|
272
|
+
>>> add_exponent("1", "")
|
273
|
+
'1'
|
274
|
+
>>> add_exponent("0", "e-3")
|
275
|
+
'0'
|
276
|
+
>>> add_exponent("0.0", "e-3")
|
277
|
+
'0.0'
|
278
|
+
|
197
279
|
"""
|
198
280
|
if value in ["0", "0.", "0.0"] or not exponent:
|
199
281
|
return value
|
@@ -201,43 +283,6 @@ def add_exponent(value: str, exponent: str) -> str:
|
|
201
283
|
return f"{value}{exponent}"
|
202
284
|
|
203
285
|
|
204
|
-
def collect_values(arg: str) -> list[str]:
|
205
|
-
"""Collect a list of values from a range argument.
|
206
|
-
|
207
|
-
Collect all individual values within a numeric range
|
208
|
-
represented by a string (e.g., `1:4`) and return them
|
209
|
-
as a list of strings.
|
210
|
-
Support both integer and floating-point ranges.
|
211
|
-
|
212
|
-
Args:
|
213
|
-
arg (str): The argument to collect.
|
214
|
-
|
215
|
-
Returns:
|
216
|
-
list[str]: A list of the collected values.
|
217
|
-
|
218
|
-
"""
|
219
|
-
if "(" in arg:
|
220
|
-
return collect_parentheses(arg)
|
221
|
-
|
222
|
-
if ":" not in arg:
|
223
|
-
return [arg]
|
224
|
-
|
225
|
-
arg, exponent = split_suffix(arg)
|
226
|
-
|
227
|
-
if ":" not in arg:
|
228
|
-
return [f"{arg}{exponent}"]
|
229
|
-
|
230
|
-
rng = _get_range(arg)
|
231
|
-
|
232
|
-
if all(isinstance(x, int) for x in rng):
|
233
|
-
values = [str(x) for x in _arange(*rng)]
|
234
|
-
else:
|
235
|
-
n = max(*(count_decimal_places(x) for x in arg.split(":")))
|
236
|
-
values = [str(round(x, n)) for x in _arange(*rng)]
|
237
|
-
|
238
|
-
return [add_exponent(x, exponent) for x in values]
|
239
|
-
|
240
|
-
|
241
286
|
def split_parentheses(arg: str) -> Iterator[str]:
|
242
287
|
"""Split a string with parentheses into a list of strings.
|
243
288
|
|
@@ -290,8 +335,60 @@ def collect_parentheses(arg: str) -> list[str]:
|
|
290
335
|
return ["".join(x[::-1]) for x in product(*it[::-1])]
|
291
336
|
|
292
337
|
|
338
|
+
def collect_values(arg: str) -> list[str]:
|
339
|
+
"""Collect a list of values from a range argument.
|
340
|
+
|
341
|
+
Collect all individual values within a numeric range
|
342
|
+
represented by a string (e.g., `1:4`) and return them
|
343
|
+
as a list of strings.
|
344
|
+
Support both integer and floating-point ranges.
|
345
|
+
|
346
|
+
Args:
|
347
|
+
arg (str): The argument to collect.
|
348
|
+
|
349
|
+
Returns:
|
350
|
+
list[str]: A list of the collected values.
|
351
|
+
|
352
|
+
Examples:
|
353
|
+
>>> collect_values("1:4")
|
354
|
+
['1', '2', '3', '4']
|
355
|
+
>>> collect_values("1.2:0.1:1.4:k")
|
356
|
+
['1.2e3', '1.3e3', '1.4e3']
|
357
|
+
>>> collect_values("0.1")
|
358
|
+
['0.1']
|
359
|
+
>>> collect_values("4:M")
|
360
|
+
['4e6']
|
361
|
+
>>> collect_values("(1:3,5:7)M")
|
362
|
+
['1e6', '2e6', '3e6', '5e6', '6e6', '7e6']
|
363
|
+
>>> collect_values("(1,5)e-(1:3)")
|
364
|
+
['1e-1', '5e-1', '1e-2', '5e-2', '1e-3', '5e-3']
|
365
|
+
|
366
|
+
"""
|
367
|
+
if "(" in arg:
|
368
|
+
return collect_parentheses(arg)
|
369
|
+
|
370
|
+
if ":" not in arg:
|
371
|
+
return [arg]
|
372
|
+
|
373
|
+
arg, exponent = split_suffix(arg)
|
374
|
+
|
375
|
+
if ":" not in arg:
|
376
|
+
return [f"{arg}{exponent}"]
|
377
|
+
|
378
|
+
rng = _get_range(arg)
|
379
|
+
|
380
|
+
if all(isinstance(x, int) for x in rng):
|
381
|
+
values = [str(x) for x in _arange(*rng)]
|
382
|
+
else:
|
383
|
+
n = max(*(count_integer_digits(x) for x in arg.split(":")))
|
384
|
+
m = max(*(count_decimal_digits(x) for x in arg.split(":")))
|
385
|
+
values = [f"{x:.{n + m}g}" for x in _arange(*rng)]
|
386
|
+
|
387
|
+
return [add_exponent(x, exponent) for x in values]
|
388
|
+
|
389
|
+
|
293
390
|
def split(arg: str) -> list[str]:
|
294
|
-
|
391
|
+
"""Split a string by top-level commas.
|
295
392
|
|
296
393
|
Splits a string by commas while respecting nested structures.
|
297
394
|
Commas inside brackets and quotes are ignored, only splitting
|
@@ -355,8 +452,9 @@ def split(arg: str) -> list[str]:
|
|
355
452
|
def expand_values(arg: str, suffix: str = "") -> Iterator[str]:
|
356
453
|
"""Expand a string argument into a list of values.
|
357
454
|
|
358
|
-
Take a string containing comma-separated values or ranges
|
359
|
-
of all individual values.
|
455
|
+
Take a string containing comma-separated values or ranges
|
456
|
+
and return a list of all individual values.
|
457
|
+
Handle numeric ranges and special characters.
|
360
458
|
|
361
459
|
Args:
|
362
460
|
arg (str): The argument to expand.
|
@@ -379,7 +477,8 @@ def split_arg(arg: str) -> tuple[str, str, str]:
|
|
379
477
|
arg (str): The argument to split.
|
380
478
|
|
381
479
|
Returns:
|
382
|
-
tuple[str, str, str]: A tuple containing the key,
|
480
|
+
tuple[str, str, str]: A tuple containing the key,
|
481
|
+
suffix, and value.
|
383
482
|
|
384
483
|
"""
|
385
484
|
if "=" not in arg:
|
@@ -398,8 +497,9 @@ def split_arg(arg: str) -> tuple[str, str, str]:
|
|
398
497
|
def collect_arg(arg: str) -> str:
|
399
498
|
"""Collect a string of expanded key-value pairs.
|
400
499
|
|
401
|
-
Take a key-value pair argument and concatenates all expanded
|
402
|
-
returning a single string suitable for
|
500
|
+
Take a key-value pair argument and concatenates all expanded
|
501
|
+
values with commas, returning a single string suitable for
|
502
|
+
command-line usage.
|
403
503
|
|
404
504
|
Args:
|
405
505
|
arg (str): The argument to collect.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: hydraflow
|
3
|
-
Version: 0.12.
|
3
|
+
Version: 0.12.2
|
4
4
|
Summary: Hydraflow integrates Hydra and MLflow to manage and track machine learning experiments.
|
5
5
|
Project-URL: Documentation, https://daizutabi.github.io/hydraflow/
|
6
6
|
Project-URL: Source, https://github.com/daizutabi/hydraflow
|
@@ -5,7 +5,7 @@ hydraflow/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
hydraflow/core/config.py,sha256=SJzjgsO_kzB78_whJ3lmy7GlZvTvwZONH1BJBn8zCuI,3817
|
6
6
|
hydraflow/core/context.py,sha256=QPyPg1xrTlmhviKNn-0nDY9bXcVky1zInqRqPN-VNhc,4741
|
7
7
|
hydraflow/core/io.py,sha256=C207DsGAU4CLvlHySyyIl0_aKZ83ysJ-W_wNM2n4RPI,6754
|
8
|
-
hydraflow/core/main.py,sha256=
|
8
|
+
hydraflow/core/main.py,sha256=66-X2-IJVEcJ4XrEC2BIKNzdd_M1RfVIAHME8k70Jo0,5131
|
9
9
|
hydraflow/core/mlflow.py,sha256=M3MhiChnMzKnKRmjBl4h_SRGkAZKL7GAmFr3DdzwRuQ,5666
|
10
10
|
hydraflow/core/param.py,sha256=LHU9j9_7oA99igasoOyKofKClVr9FmGA3UABJ-KmyS0,4538
|
11
11
|
hydraflow/entities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -16,9 +16,9 @@ hydraflow/executor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
|
|
16
16
|
hydraflow/executor/conf.py,sha256=2dv6_PlsynRmia-fGZlmBEVt8GopT0f32N13qY7tYnM,402
|
17
17
|
hydraflow/executor/io.py,sha256=yZMcBVmAbPZZ82cAXhgiJfj9p8WvHmzOCMBg_vtEVek,1509
|
18
18
|
hydraflow/executor/job.py,sha256=IL7ek0Vwa3Bl_gANq0wCbldNCUclo8YBckeEeO6W6xg,4852
|
19
|
-
hydraflow/executor/parser.py,sha256=
|
20
|
-
hydraflow-0.12.
|
21
|
-
hydraflow-0.12.
|
22
|
-
hydraflow-0.12.
|
23
|
-
hydraflow-0.12.
|
24
|
-
hydraflow-0.12.
|
19
|
+
hydraflow/executor/parser.py,sha256=_Rfund3FDgrXitTt_znsTpgEtMDqZ_ICynaB_Zje14Q,14561
|
20
|
+
hydraflow-0.12.2.dist-info/METADATA,sha256=8i5Ejzdakw6X9t6ddhuNGW0DaeQT9N3-xVCWrmX1QfQ,4549
|
21
|
+
hydraflow-0.12.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
22
|
+
hydraflow-0.12.2.dist-info/entry_points.txt,sha256=XI0khPbpCIUo9UPqkNEpgh-kqK3Jy8T7L2VCWOdkbSM,48
|
23
|
+
hydraflow-0.12.2.dist-info/licenses/LICENSE,sha256=IGdDrBPqz1O0v_UwCW-NJlbX9Hy9b3uJ11t28y2srmY,1062
|
24
|
+
hydraflow-0.12.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|