flock-core 0.4.0b33__py3-none-any.whl → 0.4.0b34__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.
Potentially problematic release.
This version of flock-core might be problematic. Click here for more details.
- flock/core/util/spliter.py +139 -54
- {flock_core-0.4.0b33.dist-info → flock_core-0.4.0b34.dist-info}/METADATA +1 -1
- {flock_core-0.4.0b33.dist-info → flock_core-0.4.0b34.dist-info}/RECORD +6 -6
- {flock_core-0.4.0b33.dist-info → flock_core-0.4.0b34.dist-info}/WHEEL +0 -0
- {flock_core-0.4.0b33.dist-info → flock_core-0.4.0b34.dist-info}/entry_points.txt +0 -0
- {flock_core-0.4.0b33.dist-info → flock_core-0.4.0b34.dist-info}/licenses/LICENSE +0 -0
flock/core/util/spliter.py
CHANGED
|
@@ -2,46 +2,37 @@ import re
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
def split_top_level(spec: str) -> list[str]:
|
|
5
|
-
"""
|
|
6
|
-
are **not** inside brackets, braces, parentheses, string literals,
|
|
7
|
-
or the free-form description).
|
|
8
|
-
|
|
9
|
-
Strategy
|
|
10
|
-
--------
|
|
11
|
-
1. Single pass, char-by-char.
|
|
12
|
-
2. Track • nesting depth for (), [], {}
|
|
13
|
-
• whether we are inside a quoted string
|
|
14
|
-
3. Consider a comma a separator *only* if depth == 0, we are not
|
|
15
|
-
inside quotes **and** the text that follows matches
|
|
16
|
-
`optional-ws + identifier + optional-ws + ':'`
|
|
17
|
-
which can only be the start of the next field.
|
|
18
|
-
"""
|
|
5
|
+
"""Return raw field strings, split on *top-level* commas."""
|
|
19
6
|
fields: list[str] = []
|
|
20
7
|
start = 0
|
|
21
8
|
depth = 0
|
|
22
9
|
quote_char: str | None = None
|
|
23
10
|
i = 0
|
|
24
|
-
ident_re = re.compile(r"[A-Za-z_]\w*") # cheap
|
|
11
|
+
ident_re = re.compile(r"[A-Za-z_]\w*") # cheap identifier
|
|
25
12
|
|
|
26
13
|
while i < len(spec):
|
|
27
14
|
ch = spec[i]
|
|
28
15
|
|
|
29
|
-
#
|
|
16
|
+
# ---------- string handling ----------
|
|
30
17
|
if quote_char:
|
|
18
|
+
if ch == "\\":
|
|
19
|
+
i += 2 # skip escaped char
|
|
20
|
+
continue
|
|
31
21
|
if ch == quote_char:
|
|
32
22
|
quote_char = None
|
|
33
23
|
i += 1
|
|
34
24
|
continue
|
|
35
25
|
|
|
36
26
|
if ch in {"'", '"'}:
|
|
37
|
-
# treat as string delimiter only in places regular Python would
|
|
38
27
|
prev = spec[i - 1] if i else " "
|
|
39
|
-
if
|
|
28
|
+
if (
|
|
29
|
+
depth or prev.isspace() or prev in "=([{,:"
|
|
30
|
+
): # looks like a quote
|
|
40
31
|
quote_char = ch
|
|
41
32
|
i += 1
|
|
42
33
|
continue
|
|
43
34
|
|
|
44
|
-
#
|
|
35
|
+
# ---------- bracket / brace / paren ----------
|
|
45
36
|
if ch in "([{":
|
|
46
37
|
depth += 1
|
|
47
38
|
i += 1
|
|
@@ -51,23 +42,28 @@ def split_top_level(spec: str) -> list[str]:
|
|
|
51
42
|
i += 1
|
|
52
43
|
continue
|
|
53
44
|
|
|
54
|
-
#
|
|
45
|
+
# ---------- field separators ----------
|
|
55
46
|
if ch == "," and depth == 0:
|
|
56
47
|
j = i + 1
|
|
57
48
|
while j < len(spec) and spec[j].isspace():
|
|
58
49
|
j += 1
|
|
59
|
-
if j
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
50
|
+
if j >= len(spec): # comma at end – split
|
|
51
|
+
fields.append(spec[start:i].strip())
|
|
52
|
+
start = i + 1
|
|
53
|
+
i += 1
|
|
54
|
+
continue
|
|
55
|
+
|
|
56
|
+
id_match = ident_re.match(spec, j)
|
|
57
|
+
if id_match:
|
|
58
|
+
k = id_match.end()
|
|
59
|
+
while k < len(spec) and spec[k].isspace():
|
|
60
|
+
k += 1
|
|
61
|
+
if k >= len(spec) or spec[k] in {":", "|", ","}:
|
|
62
|
+
# confirmed: comma separates two fields
|
|
63
|
+
fields.append(spec[start:i].strip())
|
|
64
|
+
start = i + 1
|
|
65
|
+
i += 1
|
|
66
|
+
continue
|
|
71
67
|
|
|
72
68
|
i += 1
|
|
73
69
|
|
|
@@ -76,21 +72,29 @@ def split_top_level(spec: str) -> list[str]:
|
|
|
76
72
|
|
|
77
73
|
|
|
78
74
|
def parse_schema(spec: str) -> list[tuple[str, str, str]]:
|
|
79
|
-
"""Turn
|
|
75
|
+
"""Turn *spec* into a list of (name, python_type, description)."""
|
|
80
76
|
result: list[tuple[str, str, str]] = []
|
|
81
77
|
|
|
82
78
|
for field in split_top_level(spec):
|
|
83
|
-
|
|
84
|
-
|
|
79
|
+
name = ""
|
|
80
|
+
type_str = "str" # default type
|
|
81
|
+
description = ""
|
|
85
82
|
|
|
86
|
-
name_part,
|
|
87
|
-
name = name_part.strip()
|
|
88
|
-
|
|
89
|
-
type_part, _, desc_part = rest.partition("|")
|
|
90
|
-
type_str = type_part.strip()
|
|
83
|
+
name_part, _, desc_part = field.partition("|")
|
|
91
84
|
description = desc_part.strip()
|
|
85
|
+
main_part = name_part.strip()
|
|
86
|
+
|
|
87
|
+
if ":" in main_part:
|
|
88
|
+
name, type_candidate = main_part.split(":", 1)
|
|
89
|
+
name = name.strip()
|
|
90
|
+
type_candidate = type_candidate.strip()
|
|
91
|
+
if type_candidate:
|
|
92
|
+
type_str = type_candidate
|
|
93
|
+
else:
|
|
94
|
+
name = main_part # keeps default type
|
|
92
95
|
|
|
93
|
-
|
|
96
|
+
if name: # skip broken pieces
|
|
97
|
+
result.append((name, type_str, description))
|
|
94
98
|
|
|
95
99
|
return result
|
|
96
100
|
|
|
@@ -107,20 +111,101 @@ if __name__ == "__main__":
|
|
|
107
111
|
SAMPLE_2 = (
|
|
108
112
|
"field_with_internal_quotes: Literal['type_A', "
|
|
109
113
|
'"type_B_with_\'_apostrophe"] | A literal with mixed quotes,'
|
|
110
|
-
" another_field:
|
|
114
|
+
" another_field :str| A field with a description"
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
SAMPLE_3 = (
|
|
118
|
+
"field_with_internal_quotes: Literal['type_A', "
|
|
119
|
+
'"type_B_with_\'_apostrophe"] | A literal with mixed quotes,'
|
|
120
|
+
" another_field | A field with a description"
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
SAMPLE_4 = "input, query, output"
|
|
124
|
+
|
|
125
|
+
SAMPLE_5 = (
|
|
126
|
+
"name: str | The character's full name,"
|
|
127
|
+
"race: str | The character's fantasy race,"
|
|
128
|
+
"class: Literal['mage','thief'] | The character's profession, which can be either mage or thief,"
|
|
129
|
+
"background: str | A brief backstory for the character"
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
SAMPLE_6 = (
|
|
133
|
+
"summary: str | A short blurb, e.g. key:value pairs that appear in logs"
|
|
111
134
|
)
|
|
135
|
+
# ➜ [('summary', 'str',
|
|
136
|
+
# 'A short blurb, e.g. key:value pairs that appear in logs')]
|
|
112
137
|
|
|
113
|
-
|
|
114
|
-
print(f"Sample 2: {SAMPLE_2}")
|
|
138
|
+
SAMPLE_7 = "path: str | The literal string 'C:\\\\Program Files\\\\My,App'"
|
|
115
139
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
print(split_sample_1)
|
|
119
|
-
for field in split_sample_1:
|
|
120
|
-
print(parse_schema(field))
|
|
140
|
+
# ➜ [('path', 'str',
|
|
141
|
+
# "The literal string 'C:\\Program Files\\My,App'")]
|
|
121
142
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
143
|
+
SAMPLE_8 = (
|
|
144
|
+
"transform: Callable[[int, str], bool] | Function that returns True on success,"
|
|
145
|
+
"retries: int | How many times to retry"
|
|
146
|
+
)
|
|
147
|
+
# ➜ ('transform', 'Callable[[int, str], bool]', 'Function that returns True on success')
|
|
148
|
+
# ('retries', 'int', 'How many times to retry')
|
|
149
|
+
|
|
150
|
+
SAMPLE_9 = (
|
|
151
|
+
r"regex: str | Pattern such as r'^[A-Z\|a-z]+$',"
|
|
152
|
+
"flags: int | re flags to use"
|
|
153
|
+
)
|
|
154
|
+
# ➜ ('regex', 'str', "Pattern such as r'^[A-Z\\|a-z]+$'")
|
|
155
|
+
# ('flags', 'int', 're flags to use')
|
|
156
|
+
|
|
157
|
+
SAMPLE_10 = "id:int, name:str," # note the final comma!
|
|
158
|
+
# ➜ ('id', 'int', '')
|
|
159
|
+
# ('name', 'str', '')
|
|
160
|
+
|
|
161
|
+
SAMPLE_11 = "id:int | Primary key\nname:str | Display name\nactive:bool"
|
|
162
|
+
# ➜ should not work!
|
|
163
|
+
|
|
164
|
+
SAMPLE_12 = (
|
|
165
|
+
'comment:str | The text "done | failed" goes here,'
|
|
166
|
+
'status:Literal["done","failed"]'
|
|
167
|
+
)
|
|
168
|
+
# ➜ ('comment', 'str', 'The text "done | failed" goes here')
|
|
169
|
+
# ('status', 'Literal["done","failed"]', '')
|
|
170
|
+
|
|
171
|
+
SAMPLE_13 = "choice: Literal['He said \\'yes\\'', 'no'] | User response"
|
|
172
|
+
# ➜ ('choice', "Literal['He said \\'yes\\'', 'no']", 'User response')
|
|
173
|
+
|
|
174
|
+
SAMPLE_14 = ""
|
|
175
|
+
# ➜ []
|
|
176
|
+
|
|
177
|
+
SAMPLE_15 = "username"
|
|
178
|
+
# ➜ [('username', 'str', '')]
|
|
179
|
+
|
|
180
|
+
SAMPLE_16 = (
|
|
181
|
+
"payload: dict[str, list[dict[str, tuple[int,str]]]] "
|
|
182
|
+
"| Arbitrarily complex structure"
|
|
183
|
+
)
|
|
184
|
+
# ➜ ('payload', 'dict[str, list[dict[str, tuple[int,str]]]]',
|
|
185
|
+
# 'Arbitrarily complex structure')
|
|
186
|
+
|
|
187
|
+
SAMPLE_17 = "münze: str | Deutsche Münzbezeichnung, engl. 'coin'"
|
|
188
|
+
# ➜ [('münze', 'str', "Deutsche Münzbezeichnung, engl. 'coin'")]
|
|
189
|
+
|
|
190
|
+
for title, spec in [
|
|
191
|
+
("Sample-1", SAMPLE_1),
|
|
192
|
+
("Sample-2", SAMPLE_2),
|
|
193
|
+
("Sample-3", SAMPLE_3),
|
|
194
|
+
("Sample-4", SAMPLE_4),
|
|
195
|
+
("Sample-5", SAMPLE_5),
|
|
196
|
+
("Sample-6", SAMPLE_6),
|
|
197
|
+
("Sample-7", SAMPLE_7),
|
|
198
|
+
("Sample-8", SAMPLE_8),
|
|
199
|
+
("Sample-9", SAMPLE_9),
|
|
200
|
+
("Sample-10", SAMPLE_10),
|
|
201
|
+
("Sample-11", SAMPLE_11),
|
|
202
|
+
("Sample-12", SAMPLE_12),
|
|
203
|
+
("Sample-13", SAMPLE_13),
|
|
204
|
+
("Sample-14", SAMPLE_14),
|
|
205
|
+
("Sample-15", SAMPLE_15),
|
|
206
|
+
("Sample-16", SAMPLE_16),
|
|
207
|
+
("Sample-17", SAMPLE_17),
|
|
208
|
+
]:
|
|
209
|
+
print(f"\n{title}")
|
|
210
|
+
for row in parse_schema(spec):
|
|
211
|
+
print(row)
|
|
@@ -76,7 +76,7 @@ flock/core/util/file_path_utils.py,sha256=Odf7uU32C-x1KNighbNERSiMtkzW4h8laABIoF
|
|
|
76
76
|
flock/core/util/hydrator.py,sha256=QJvCA8F4nkSP5akp3yg0cT6oaajOr1n7sldW5dCs6Lo,10733
|
|
77
77
|
flock/core/util/input_resolver.py,sha256=KPoPSpklyCoiR2t5r6J6GJHegmPLFZ0YE126VcKBewM,4703
|
|
78
78
|
flock/core/util/loader.py,sha256=j3q2qem5bFMP2SmMuYjb-ISxsNGNZd1baQmpvAnRUUk,2244
|
|
79
|
-
flock/core/util/spliter.py,sha256=
|
|
79
|
+
flock/core/util/spliter.py,sha256=D-P4u3vdKQFyC4DltpCoX4PExXuOKnE-G5kBG_6H678,6770
|
|
80
80
|
flock/evaluators/declarative/declarative_evaluator.py,sha256=q3qKHuKrj17mhaoOZuKh2HyVfiDBEEUk1Y1ZrejvggA,6328
|
|
81
81
|
flock/evaluators/memory/memory_evaluator.py,sha256=ySwz7kcc8suXMJ7gKNSWThW8iOMlE8lUcUzEAHvv8rw,3559
|
|
82
82
|
flock/evaluators/test/test_case_evaluator.py,sha256=3Emcoty0LOLLBIuPGxSpKphuZC9Fu1DTr1vbGg-hd0Q,1233
|
|
@@ -445,8 +445,8 @@ flock/workflow/agent_execution_activity.py,sha256=Gy6FtuVAjf0NiUXmC3syS2eJpNQF4R
|
|
|
445
445
|
flock/workflow/flock_workflow.py,sha256=iSUF_soFvWar0ffpkzE4irkDZRx0p4HnwmEBi_Ne2sY,9666
|
|
446
446
|
flock/workflow/temporal_config.py,sha256=3_8O7SDEjMsSMXsWJBfnb6XTp0TFaz39uyzSlMTSF_I,3988
|
|
447
447
|
flock/workflow/temporal_setup.py,sha256=YIHnSBntzOchHfMSh8hoLeNXrz3B1UbR14YrR6soM7A,1606
|
|
448
|
-
flock_core-0.4.
|
|
449
|
-
flock_core-0.4.
|
|
450
|
-
flock_core-0.4.
|
|
451
|
-
flock_core-0.4.
|
|
452
|
-
flock_core-0.4.
|
|
448
|
+
flock_core-0.4.0b34.dist-info/METADATA,sha256=xImOi53HupDqDi8RpnOjZfkS_rbLJQ6j_CrwoIR7RPA,17125
|
|
449
|
+
flock_core-0.4.0b34.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
450
|
+
flock_core-0.4.0b34.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
|
|
451
|
+
flock_core-0.4.0b34.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
|
|
452
|
+
flock_core-0.4.0b34.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|