From 034f06537d55c28c420d57dc04d1d4b738284a1d Mon Sep 17 00:00:00 2001 From: marii Date: Fri, 15 Jan 2021 20:20:12 -0800 Subject: [PATCH] add hackability to use_kwargs_dict --- fastcore/_nbdev.py | 1 + fastcore/meta.py | 23 +++++++++++++++++--- nbs/07_meta.ipynb | 54 ++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 73 insertions(+), 5 deletions(-) diff --git a/fastcore/_nbdev.py b/fastcore/_nbdev.py index f3d3d263..51caa77d 100644 --- a/fastcore/_nbdev.py +++ b/fastcore/_nbdev.py @@ -236,6 +236,7 @@ "BypassNewMeta": "07_meta.ipynb", "empty2none": "07_meta.ipynb", "anno_dict": "07_meta.ipynb", + "get_kwargs_dict": "07_meta.ipynb", "use_kwargs_dict": "07_meta.ipynb", "use_kwargs": "07_meta.ipynb", "delegates": "07_meta.ipynb", diff --git a/fastcore/meta.py b/fastcore/meta.py index 0612c232..9a164515 100644 --- a/fastcore/meta.py +++ b/fastcore/meta.py @@ -1,7 +1,7 @@ # AUTOGENERATED! DO NOT EDIT! File to edit: nbs/07_meta.ipynb (unless otherwise specified). __all__ = ['test_sig', 'FixSigMeta', 'PrePostInitMeta', 'AutoInit', 'NewChkMeta', 'BypassNewMeta', 'empty2none', - 'anno_dict', 'use_kwargs_dict', 'use_kwargs', 'delegates', 'method', 'funcs_kwargs'] + 'anno_dict', 'get_kwargs_dict', 'use_kwargs_dict', 'use_kwargs', 'delegates', 'method', 'funcs_kwargs'] # Cell from .imports import * @@ -76,7 +76,24 @@ def anno_dict(f): def _mk_param(n,d=None): return inspect.Parameter(n, inspect.Parameter.KEYWORD_ONLY, default=d) # Cell -def use_kwargs_dict(keep=False, **kwargs): +def get_kwargs_dict(f): + "Gets kwargs of a function as a dictionary" + return {v.name:v.default for v in inspect.signature(f).parameters.values() + if v.default != inspect.Parameter.empty} + +# Cell +def _wrap(wrapped_f,keep=False): + "Wrap decorators so they will not run multiple times. keep will determine if flag should be set for further decorators to not run" + def _f(f,wrap=None): + from_f=getattr(f,'__func__',f) + if hasattr(from_f,'__delwrap__') or wrap is None: return f + f = wrap(from_f) + if not keep: f.__delwrap__=from_f + return f + return partial(_f,wrap=wrapped_f) + +# Cell +def use_kwargs_dict(keep=False,wrap=False, **kwargs): "Decorator: replace `**kwargs` in signature with `names` params" def _f(f): sig = inspect.signature(f) @@ -87,7 +104,7 @@ def _f(f): if keep: sigd['kwargs'] = k f.__signature__ = sig.replace(parameters=sigd.values()) return f - return _f + return _wrap(_f,keep=keep) if wrap else _f # Cell def use_kwargs(names, keep=False): diff --git a/nbs/07_meta.ipynb b/nbs/07_meta.ipynb index 96b94300..09ca75b1 100644 --- a/nbs/07_meta.ipynb +++ b/nbs/07_meta.ipynb @@ -749,7 +749,38 @@ "outputs": [], "source": [ "#export\n", - "def use_kwargs_dict(keep=False, **kwargs):\n", + "def get_kwargs_dict(f):\n", + " \"Gets kwargs of a function as a dictionary\"\n", + " return {v.name:v.default for v in inspect.signature(f).parameters.values() \n", + " if v.default != inspect.Parameter.empty}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#export\n", + "def _wrap(wrapped_f,keep=False):\n", + " \"Wrap decorators so they will not run multiple times. keep will determine if flag should be set for further decorators to not run\"\n", + " def _f(f,wrap=None):\n", + " from_f=getattr(f,'__func__',f)\n", + " if hasattr(from_f,'__delwrap__') or wrap is None: return f\n", + " f = wrap(from_f)\n", + " if not keep: f.__delwrap__=from_f\n", + " return f\n", + " return partial(_f,wrap=wrapped_f)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#export\n", + "def use_kwargs_dict(keep=False,wrap=False, **kwargs):\n", " \"Decorator: replace `**kwargs` in signature with `names` params\"\n", " def _f(f):\n", " sig = inspect.signature(f)\n", @@ -760,7 +791,7 @@ " if keep: sigd['kwargs'] = k\n", " f.__signature__ = sig.replace(parameters=sigd.values())\n", " return f\n", - " return _f" + " return _wrap(_f,keep=keep) if wrap else _f" ] }, { @@ -782,6 +813,25 @@ "test_sig(foo, '(a, b=1, *, y=1, z=None)')" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "@use_kwargs_dict(y=1,z=None)\n", + "@use_kwargs_dict(x=2,wrap=True,keep=True)\n", + "def foo(a, b=1, **kwargs): pass\n", + "\n", + "test_sig(foo, '(a, b=1, *, x=2, y=1, z=None)')\n", + "\n", + "@use_kwargs_dict(**{ 'val_'+k:v for k,v in get_kwargs_dict(foo).items()})\n", + "@use_kwargs_dict(**get_kwargs_dict(foo),wrap=True,keep=True)\n", + "def goo(g=4, **kwargs): pass\n", + "\n", + "test_sig(goo, '(g=4, *, b=1, x=2, y=1, z=None, val_b=1, val_x=2, val_y=1, val_z=None)')" + ] + }, { "cell_type": "markdown", "metadata": {},