fastcore 2.2.17__tar.gz → 2.2.18__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.
- {fastcore-2.2.17/fastcore.egg-info → fastcore-2.2.18}/PKG-INFO +1 -1
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/__init__.py +1 -1
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/_modidx.py +3 -1
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/aio.py +16 -2
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/script.py +17 -3
- {fastcore-2.2.17 → fastcore-2.2.18/fastcore.egg-info}/PKG-INFO +1 -1
- {fastcore-2.2.17 → fastcore-2.2.18}/CONTRIBUTING.md +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/LICENSE +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/MANIFEST.in +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/README.md +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/all.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/ansi.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/apisurface.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/basics.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/dispatch.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/docments.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/docscrape.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/editskill.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/foundation.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/funccall.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/imghdr.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/imports.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/meta.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/nb_imports.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/nbio.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/net.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/parallel.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/py2pyi.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/shutil.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/style.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/test.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/tools.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/transform.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/utils.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/xdg.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/xml.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore/xtras.py +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore.egg-info/SOURCES.txt +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore.egg-info/dependency_links.txt +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore.egg-info/entry_points.txt +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore.egg-info/requires.txt +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/fastcore.egg-info/top_level.txt +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/pyproject.toml +0 -0
- {fastcore-2.2.17 → fastcore-2.2.18}/setup.cfg +0 -0
|
@@ -31,7 +31,8 @@ d = { 'settings': { 'branch': 'main',
|
|
|
31
31
|
'fastcore.aio.reawaitable': ('aio.html#reawaitable', 'fastcore/aio.py'),
|
|
32
32
|
'fastcore.aio.run_sync': ('aio.html#run_sync', 'fastcore/aio.py'),
|
|
33
33
|
'fastcore.aio.then': ('aio.html#then', 'fastcore/aio.py'),
|
|
34
|
-
'fastcore.aio.to_aiter': ('aio.html#to_aiter', 'fastcore/aio.py')
|
|
34
|
+
'fastcore.aio.to_aiter': ('aio.html#to_aiter', 'fastcore/aio.py'),
|
|
35
|
+
'fastcore.aio.wait_until': ('aio.html#wait_until', 'fastcore/aio.py')},
|
|
35
36
|
'fastcore.all': {},
|
|
36
37
|
'fastcore.ansi': {},
|
|
37
38
|
'fastcore.apisurface': { 'fastcore.apisurface.OpGroup': ('apisurface.html#opgroup', 'fastcore/apisurface.py'),
|
|
@@ -745,6 +746,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
745
746
|
'fastcore.script._is_script_run': ('script.html#_is_script_run', 'fastcore/script.py'),
|
|
746
747
|
'fastcore.script._is_union': ('script.html#_is_union', 'fastcore/script.py'),
|
|
747
748
|
'fastcore.script._pkg_version': ('script.html#_pkg_version', 'fastcore/script.py'),
|
|
749
|
+
'fastcore.script._pos_split': ('script.html#_pos_split', 'fastcore/script.py'),
|
|
748
750
|
'fastcore.script._run_cli': ('script.html#_run_cli', 'fastcore/script.py'),
|
|
749
751
|
'fastcore.script._union_parser': ('script.html#_union_parser', 'fastcore/script.py'),
|
|
750
752
|
'fastcore.script._union_type': ('script.html#_union_type', 'fastcore/script.py'),
|
|
@@ -16,8 +16,8 @@ Docs: https://fastcore.fast.ai/aio.html.md"""
|
|
|
16
16
|
|
|
17
17
|
# %% auto #0
|
|
18
18
|
__all__ = ['run_sync', 'iter_sync', 'ctx_sync', 'athreaded', 'maybe_await', 'then', 'acache', 'CachedAwaitable', 'reawaitable',
|
|
19
|
-
'is_async_callable', 'to_aiter', 'maybe_aiter', 'mapa', 'noopa', '
|
|
20
|
-
'disable_async_magics']
|
|
19
|
+
'is_async_callable', 'to_aiter', 'maybe_aiter', 'mapa', 'noopa', 'wait_until', 'Debounce',
|
|
20
|
+
'enable_async_magics', 'disable_async_magics']
|
|
21
21
|
|
|
22
22
|
# %% ../nbs/03c_aio.ipynb #7e2193be
|
|
23
23
|
import asyncio,contextvars,threading
|
|
@@ -160,6 +160,20 @@ async def noopa(x=None, *args, **kwargs):
|
|
|
160
160
|
"Do nothing (async)"
|
|
161
161
|
return x
|
|
162
162
|
|
|
163
|
+
# %% ../nbs/03c_aio.ipynb #959bd288
|
|
164
|
+
async def wait_until(
|
|
165
|
+
probe, # Sync or async callable; falsy result means keep waiting
|
|
166
|
+
what:str=None, # Named in the `TimeoutError`; `probe`'s name if None
|
|
167
|
+
timeout:float=10, # Seconds to wait before raising
|
|
168
|
+
sleep:float=0.2, # Seconds between probes
|
|
169
|
+
):
|
|
170
|
+
"Call `probe` until truthy, returning its first truthy result"
|
|
171
|
+
deadline = asyncio.get_running_loop().time() + timeout
|
|
172
|
+
while asyncio.get_running_loop().time() < deadline:
|
|
173
|
+
if (r := await maybe_await(probe())): return r
|
|
174
|
+
await asyncio.sleep(sleep)
|
|
175
|
+
raise TimeoutError(f'Timed out waiting for {what or getattr(probe, "__name__", probe)}')
|
|
176
|
+
|
|
163
177
|
# %% ../nbs/03c_aio.ipynb #5eaf5cd7
|
|
164
178
|
class Debounce:
|
|
165
179
|
"Coalesce a burst of calls into one run of `f`, `wait` secs after calls stop (or `max_wait` secs after they start)"
|
|
@@ -55,7 +55,7 @@ A capital letter in a parameter name declares a short flag: the capitalized lett
|
|
|
55
55
|
|
|
56
56
|
## Positional params
|
|
57
57
|
|
|
58
|
-
Parameters without a default are positional, and the rest are flags. Pass `pos` to `call_parse` (or to `anno_parser`) to keep named parameters positional even when they have a default, in which case they are optional on the command line and take the default when omitted. Command line order follows the signature, not the order of the names in `pos`. Naming a bool parameter in `pos` raises, since a flag takes no value.
|
|
58
|
+
Parameters without a default are positional, and the rest are flags. A `*args` parameter is a variadic positional, taking zero or more values, and since Python makes any params after it keyword-only, they are flags. A `**kwargs` parameter is skipped: a CLI run passes nothing for it. Pass `pos` to `call_parse` (or to `anno_parser`) to keep named parameters positional even when they have a default, in which case they are optional on the command line and take the default when omitted. Command line order follows the signature, not the order of the names in `pos`. Naming a bool parameter in `pos` raises, since a flag takes no value.
|
|
59
59
|
|
|
60
60
|
## Param types
|
|
61
61
|
|
|
@@ -213,9 +213,13 @@ def anno_parser(func, prog:str=None, pos:list=None):
|
|
|
213
213
|
"Look at params (with type/docments/`Annotated` annotations) in func and return an `ArgumentParser`"
|
|
214
214
|
p = argparse.ArgumentParser(description=func.__doc__, prog=prog, formatter_class=_HelpFormatter, epilog=_pkg_version(func))
|
|
215
215
|
for k,v in docments(func, full=True, returns=False, eval_str=True).items():
|
|
216
|
+
if v.kind is inspect.Parameter.VAR_KEYWORD: continue
|
|
216
217
|
anno,meta = ann_parts(v.anno)
|
|
217
218
|
extra = next((o for o in meta if isinstance(o,dict)), {})
|
|
218
|
-
if
|
|
219
|
+
if v.kind is inspect.Parameter.VAR_POSITIONAL:
|
|
220
|
+
if anno in (bool,store_true,store_false): raise ValueError(f"variadic param {k!r} can't be a bool: a flag takes no value")
|
|
221
|
+
extra = merge({'opt':False, 'nargs':'*'}, extra)
|
|
222
|
+
elif pos and k in pos:
|
|
219
223
|
if anno in (bool,store_true,store_false): raise ValueError(f"positional param {k!r} can't be a bool: a flag takes no value")
|
|
220
224
|
extra = merge({'opt':False}, {'nargs':'?'} if v.default is not inspect.Parameter.empty else {}, extra)
|
|
221
225
|
mv = anno2str(anno)
|
|
@@ -260,6 +264,15 @@ def _is_script_run(frame):
|
|
|
260
264
|
if g.get('__name__')!='__main__' or not g.get('__file__'): return False
|
|
261
265
|
return Path(g['__file__']).resolve()==Path(frame.f_code.co_filename).resolve()
|
|
262
266
|
|
|
267
|
+
# %% ../nbs/06_script.ipynb #d9a3f93c
|
|
268
|
+
def _pos_split(func, args):
|
|
269
|
+
"Pop values for params up to a `*args` param from `args` in signature order, to pass positionally"
|
|
270
|
+
ks = []
|
|
271
|
+
for k,v in inspect.signature(func).parameters.items():
|
|
272
|
+
if v.kind is inspect.Parameter.VAR_POSITIONAL: return [args.pop(o) for o in ks]+list(args.pop(k)), args
|
|
273
|
+
ks.append(k)
|
|
274
|
+
return [],args
|
|
275
|
+
|
|
263
276
|
# %% ../nbs/06_script.ipynb #dee5e259
|
|
264
277
|
_cli_func = ContextVar('_cli_func', default=None)
|
|
265
278
|
|
|
@@ -273,7 +286,8 @@ def _run_cli(func, nested, pos=None):
|
|
|
273
286
|
args = args.__dict__
|
|
274
287
|
xtra = otherwise(args.pop('xtra', ''), eq(1), p.prog)
|
|
275
288
|
tfunc = trace(func) if args.pop('pdb', False) else func
|
|
276
|
-
|
|
289
|
+
pargs,args = _pos_split(func, merge(args, args_from_prog(func, xtra)))
|
|
290
|
+
res = tfunc(*pargs, **args)
|
|
277
291
|
return asyncio.run(res) if inspect.isawaitable(res) else res
|
|
278
292
|
|
|
279
293
|
def call_parse(func=None, nested=False, pos:list=None):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|