08_use_kwargs_dict

Imports

from fastdebug.utils import *
from fastdebug.core import *
from fastcore.meta import *

Reading official docs

from fastcore.meta import _mk_param # not included in __all__

empty2none

fdbe = Fastdb(empty2none)
fdbe.docsrc(0, "p is the Parameter.default value")
fdbe.docsrc(1, "to use empty2none, I need to make sure p is not a parameter, but parameter.default")
fdbe.docsrc(2, "how to check whether a parameter default value is empty")
========================================================     Investigating empty2none     ========================================================
===============================================================     on line 0     ================================================================
=============================================================     with example      ==============================================================

print selected srcline with expands below--------
def empty2none(p):======================================================================================================================================(0)
                                                                                                                             p is the Parameter.default value
    "Replace `Parameter.empty` with `None`"                                                                                                             (1)
    return None if p==inspect.Parameter.empty else p                                                                                                    (2)
========================================================     Investigating empty2none     ========================================================
===============================================================     on line 1     ================================================================
=============================================================     with example 
     =============================================================

print selected srcline with expands below--------
def empty2none(p):                                                                                                                                      (0)
    "Replace `Parameter.empty` with `None`"=============================================================================================================(1)
                                                                           to use empty2none, I need to make sure p is not a parameter, but parameter.default
    return None if p==inspect.Parameter.empty else p                                                                                                    (2)
                                                                                                                                                        (3)

Review srcode with all comments added so far======================================================================================================
def empty2none(p):========================================================================(0) # p is the Parameter.default value; 
    "Replace `Parameter.empty` with `None`"===============================================(1) # to use empty2none, I need to make sure p is not a parameter, but parameter.default; 
    return None if p==inspect.Parameter.empty else p======================================(2)       
                                                                                                                                                        (3)
                                                                                                                                     part No.1 out of 1 parts

========================================================     Investigating empty2none     ========================================================
===============================================================     on line 2     ================================================================
============================================================     with example 

     =============================================================

print selected srcline with expands below--------
def empty2none(p):                                                                                                                                      (0)
    "Replace `Parameter.empty` with `None`"                                                                                                             (1)
    return None if p==inspect.Parameter.empty else p====================================================================================================(2)
                                                                                                      how to check whether a parameter default value is empty
                                                                                                                                                        (3)

Review srcode with all comments added so far======================================================================================================
def empty2none(p):========================================================================(0) # p is the Parameter.default value; 
    "Replace `Parameter.empty` with `None`"===============================================(1) # to use empty2none, I need to make sure p is not a parameter, but parameter.default; 
    return None if p==inspect.Parameter.empty else p======================================(2) # how to check whether a parameter default value is empty; 
                                                                                                                                                        (3)
                                                                                                                                     part No.1 out of 1 parts
# def foo(a, b=1): pass
# sig = inspect.signature(foo)
# print(sig.parameters.items())
# for k,v in sig.parameters.items():
#     print(f'{k} : {v.default} => empty2none => {empty2none(v.default)}')
fdbe.eg = """
def foo(a, b=1): pass
sig = inspect.signature(foo)
print(sig.parameters.items())
for k,v in sig.parameters.items():
    print(f'{k} : {v.default} => empty2none => {empty2none(v.default)}')
"""
fdbe.snoop()
22:14:40.57 >>> Call to empty2none in File "/tmp/empty2none.py", line 3
22:14:40.57 ...... p = <class 'inspect._empty'>
22:14:40.57    3 | def empty2none(p):
22:14:40.57    5 |     return None if p==inspect.Parameter.empty else p
22:14:40.57 <<< Return value from empty2none: None
22:14:40.57 >>> Call to empty2none in File "/tmp/empty2none.py", line 3
22:14:40.57 ...... p = 1
22:14:40.57    3 | def empty2none(p):
22:14:40.57    5 |     return None if p==inspect.Parameter.empty else p
22:14:40.57 <<< Return value from empty2none: 1
========================================================     Investigating empty2none     ========================================================
==============================================================     on line None     ==============================================================
     with example 
def foo(a, b=1): pass
sig = inspect.signature(foo)
print(sig.parameters.items())
for k,v in sig.parameters.items():
    print(f'{k} : {v.default} => empty2none => {empty2none(v.default)}')
     

odict_items([('a', <Parameter "a">), ('b', <Parameter "b=1">)])
a : <class 'inspect._empty'> => empty2none => None
b : 1 => empty2none => 1

_mk_param

fdb = Fastdb(_mk_param)
fdb.print()
========================================================     Investigating _mk_param     =========================================================
==============================================================     on line None     ==============================================================
=============================================================     with example      ==============================================================

def _mk_param(n,d=None): return inspect.Parameter(n, inspect.Parameter.KEYWORD_ONLY, default=d)                                                         (0)
                                                                                                                                                        (1)
fdb.eg = """
print(_mk_param("a", 1))
"""
fdb.snoop()
22:14:40.58 >>> Call to _mk_param in File "/tmp/_mk_param.py", line 3
22:14:40.58 ...... n = 'a'
22:14:40.58 ...... d = 1
22:14:40.58    3 | def _mk_param(n,d=None): return inspect.Parameter(n, inspect.Parameter.KEYWORD_ONLY, default=d)
22:14:40.58    3 | def _mk_param(n,d=None): return inspect.Parameter(n, inspect.Parameter.KEYWORD_ONLY, default=d)
22:14:40.58 <<< Return value from _mk_param: <Parameter "a=1">
========================================================     Investigating _mk_param     =========================================================
==============================================================     on line None     ==============================================================
================================================     with example 
print(_mk_param("a", 1))
     =================================================

a=1
fdb.docsrc(0, "_mk_param is to create a new parameter as KEYWORD_ONLY kind; n is its name in string; d is its default value")
========================================================     Investigating _mk_param     =========================================================
===============================================================     on line 0     ================================================================
================================================     with example 
print(_mk_param("a", 1))
     =================================================

print selected srcline with expands below--------
def _mk_param(n,d=None): return inspect.Parameter(n, inspect.Parameter.KEYWORD_ONLY, default=d)=========================================================(0)
                                                 _mk_param is to create a new parameter as KEYWORD_ONLY kind; n is its name in string; d is its default value
                                                                                                                                                        (1)
a=1

use_kwargs_dict

Reading docs

Replace all **kwargs with named arguments like so:

@use_kwargs_dict(y=1,z=None)
def foo(a, b=1, **kwargs): pass

test_sig(foo, '(a, b=1, *, y=1, z=None)')

Add named arguments, but optionally keep **kwargs by setting keep=True:

@use_kwargs_dict(y=1,z=None, keep=True)
def foo(a, b=1, **kwargs): pass

test_sig(foo, '(a, b=1, *, y=1, z=None, **kwargs)')
print(inspect.getsource(use_kwargs_dict))
def use_kwargs_dict(keep=False, **kwargs):
    "Decorator: replace `**kwargs` in signature with `names` params"
    def _f(f):
        sig = inspect.signature(f)
        sigd = dict(sig.parameters)
        k = sigd.pop('kwargs')
        s2 = {n:_mk_param(n,d) for n,d in kwargs.items() if n not in sigd}
        sigd.update(s2)
        if keep: sigd['kwargs'] = k
        f.__signature__ = sig.replace(parameters=sigd.values())
        return f
    return _f
fdb = Fastdb(use_kwargs_dict)
fdb.eg = """
@use_kwargs_dict(y=1,z=None)
def foo(a, b=1, **kwargs): pass

test_sig(foo, '(a, b=1, *, y=1, z=None)')
"""

fdb.eg = """
@use_kwargs_dict(y=1,z=None, keep=True)
def foo(a, b=1, **kwargs): pass

test_sig(foo, '(a, b=1, *, y=1, z=None, **kwargs)')
"""
fdb.print()
=====================================================     Investigating use_kwargs_dict     ======================================================
==============================================================     on line None     ==============================================================
     with example 
@use_kwargs_dict(y=1,z=None, keep=True)
def foo(a, b=1, **kwargs): pass

test_sig(foo, '(a, b=1, *, y=1, z=None, **kwargs)')
     

def use_kwargs_dict(keep=False, **kwargs):================================================(0)       
    "Decorator: replace `**kwargs` in signature with `names` params"======================(1)       
    def _f(f):============================================================================(2)       
        sig = inspect.signature(f)========================================================(3)       
        sigd = dict(sig.parameters)=======================================================(4)       
        k = sigd.pop('kwargs')============================================================(5)       
        s2 = {n:_mk_param(n,d) for n,d in kwargs.items() if n not in sigd}================(6)       
        sigd.update(s2)===================================================================(7)       
        if keep: sigd['kwargs'] = k=======================================================(8)       
        f.__signature__ = sig.replace(parameters=sigd.values())===========================(9)       
        return f==========================================================================(10)      
    return _f=============================================================================(11)      
                                                                                                                                                        (12)
fdb.docsrc(1, "how to use use_kwargs_dict; use_kwargs_dict is to replace **kwargs with newly created KEYWORD_ONLY params based on a dict; \
f's signature is saved inside f.__signature__")
fdb.docsrc(3, "how to get the signature from an object")
fdb.docsrc(4, "how to get all parameters of a signature; how to make it into a dict; ")
fdb.docsrc(5, "how to pop out an item from a dict")
fdb.docsrc(6, "how to create a dict of params based on a dict")
fdb.docsrc(7, "how to udpate one dict into another dict")
fdb.docsrc(8, "how to create a new item in a dict")
fdb.docsrc(9, "how to update a signature with a new set of parameters in the form of a dict values")
=====================================================     Investigating use_kwargs_dict     ======================================================
===============================================================     on line 1     ================================================================
     with example 
@use_kwargs_dict(y=1,z=None, keep=True)
def foo(a, b=1, **kwargs): pass

test_sig(foo, '(a, b=1, *, y=1, z=None, **kwargs)')
     

print selected srcline with expands below--------
def use_kwargs_dict(keep=False, **kwargs):                                                                                                              (0)
    "Decorator: replace `**kwargs` in signature with `names` params"====================================================================================(1)
how to use use_kwargs_dict; use_kwargs_dict is to replace **kwargs with newly created KEYWORD_ONLY params based on a dict; f's signature is saved inside f.__signature__
    def _f(f):                                                                                                                                          (2)
        sig = inspect.signature(f)                                                                                                                      (3)

Review srcode with all comments added so far======================================================================================================
def use_kwargs_dict(keep=False, **kwargs):================================================(0)       
    "Decorator: replace `**kwargs` in signature with `names` params"======================(1) # how to use use_kwargs_dict; use_kwargs_dict is to replace **kwargs with newly created KEYWORD_ONLY params based on a dict; f's signature is saved inside f.__signature__; 
    def _f(f):============================================================================(2)       
        sig = inspect.signature(f)========================================================(3)       
        sigd = dict(sig.parameters)=======================================================(4)       
        k = sigd.pop('kwargs')============================================================(5)       
        s2 = {n:_mk_param(n,d) for n,d in kwargs.items() if n not in sigd}================(6)       
        sigd.update(s2)===================================================================(7)       
        if keep: sigd['kwargs'] = k=======================================================(8)       
        f.__signature__ = sig.replace(parameters=sigd.values())===========================(9)       
        return f==========================================================================(10)      
    return _f=============================================================================(11)      
                                                                                                                                                        (12)
                                                                                                                                     part No.1 out of 1 parts

=====================================================     Investigating use_kwargs_dict     ======================================================
===============================================================     on line 3     ================================================================
     with example 
@use_kwargs_dict(y=1,z=None, keep=True)
def foo(a, b=1, **kwargs): pass

test_sig(foo, '(a, b=1, *, y=1, z=None, **kwargs)')
     

print selected srcline with expands below--------
    "Decorator: replace `**kwargs` in signature with `names` params"                                                                                    (1)
    def _f(f):                                                                                                                                          (2)
        sig = inspect.signature(f)======================================================================================================================(3)
                                                                                                                      how to get the signature from an object
        sigd = dict(sig.parameters)                                                                                                                     (4)
        k = sigd.pop('kwargs')                                                                                                                          (5)

Review srcode with all comments added so far======================================================================================================
def use_kwargs_dict(keep=False, **kwargs):================================================(0)       
    "Decorator: replace `**kwargs` in signature with `names` params"======================(1) # how to use use_kwargs_dict; use_kwargs_dict is to replace **kwargs with newly created KEYWORD_ONLY params based on a dict; f's signature is saved inside f.__signature__; 
    def _f(f):============================================================================(2)       
        sig = inspect.signature(f)========================================================(3) # how to get the signature from an object; 
        sigd = dict(sig.parameters)=======================================================(4)       
        k = sigd.pop('kwargs')============================================================(5)       
        s2 = {n:_mk_param(n,d) for n,d in kwargs.items() if n not in sigd}================(6)       
        sigd.update(s2)===================================================================(7)       
        if keep: sigd['kwargs'] = k=======================================================(8)       
        f.__signature__ = sig.replace(parameters=sigd.values())===========================(9)       
        return f==========================================================================(10)      
    return _f=============================================================================(11)      
                                                                                                                                                        (12)
                                                                                                                                     part No.1 out of 1 parts

=====================================================     Investigating use_kwargs_dict     ======================================================
===============================================================     on line 4     ================================================================
     with example 
@use_kwargs_dict(y=1,z=None, keep=True)
def foo(a, b=1, **kwargs): pass

test_sig(foo, '(a, b=1, *, y=1, z=None, **kwargs)')
     

print selected srcline with expands below--------
    def _f(f):                                                                                                                                          (2)
        sig = inspect.signature(f)                                                                                                                      (3)
        sigd = dict(sig.parameters)=====================================================================================================================(4)
                                                                                       how to get all parameters of a signature; how to make it into a dict; 
        k = sigd.pop('kwargs')                                                                                                                          (5)
        s2 = {n:_mk_param(n,d) for n,d in kwargs.items() if n not in sigd}                                                                              (6)

Review srcode with all comments added so far======================================================================================================
def use_kwargs_dict(keep=False, **kwargs):================================================(0)       
    "Decorator: replace `**kwargs` in signature with `names` params"======================(1) # how to use use_kwargs_dict; use_kwargs_dict is to replace **kwargs with newly created KEYWORD_ONLY params based on a dict; f's signature is saved inside f.__signature__; 
    def _f(f):============================================================================(2)       
        sig = inspect.signature(f)========================================================(3) # how to get the signature from an object; 
        sigd = dict(sig.parameters)=======================================================(4) # how to get all parameters of a signature; how to make it into a dict; ; 
        k = sigd.pop('kwargs')============================================================(5)       
        s2 = {n:_mk_param(n,d) for n,d in kwargs.items() if n not in sigd}================(6)       
        sigd.update(s2)===================================================================(7)       
        if keep: sigd['kwargs'] = k=======================================================(8)       
        f.__signature__ = sig.replace(parameters=sigd.values())===========================(9)       
        return f==========================================================================(10)      
    return _f=============================================================================(11)      
                                                                                                                                                        (12)
                                                                                                                                     part No.1 out of 1 parts

=====================================================     Investigating use_kwargs_dict     ======================================================
===============================================================     on line 5     ================================================================
     with example 
@use_kwargs_dict(y=1,z=None, keep=True)
def foo(a, b=1, **kwargs): pass

test_sig(foo, '(a, b=1, *, y=1, z=None, **kwargs)')
     

print selected srcline with expands below--------
        sig = inspect.signature(f)                                                                                                                      (3)
        sigd = dict(sig.parameters)                                                                                                                     (4)
        k = sigd.pop('kwargs')==========================================================================================================================(5)
                                                                                                                           how to pop out an item from a dict
        s2 = {n:_mk_param(n,d) for n,d in kwargs.items() if n not in sigd}                                                                              (6)
        sigd.update(s2)                                                                                                                                 (7)

Review srcode with all comments added so far======================================================================================================
def use_kwargs_dict(keep=False, **kwargs):================================================(0)       
    "Decorator: replace `**kwargs` in signature with `names` params"======================(1) # how to use use_kwargs_dict; use_kwargs_dict is to replace **kwargs with newly created KEYWORD_ONLY params based on a dict; f's signature is saved inside f.__signature__; 
    def _f(f):============================================================================(2)       
        sig = inspect.signature(f)========================================================(3) # how to get the signature from an object; 
        sigd = dict(sig.parameters)=======================================================(4) # how to get all parameters of a signature; how to make it into a dict; ; 
        k = sigd.pop('kwargs')============================================================(5) # how to pop out an item from a dict; 
        s2 = {n:_mk_param(n,d) for n,d in kwargs.items() if n not in sigd}================(6)       
        sigd.update(s2)===================================================================(7)       
        if keep: sigd['kwargs'] = k=======================================================(8)       
        f.__signature__ = sig.replace(parameters=sigd.values())===========================(9)       
        return f==========================================================================(10)      
    return _f=============================================================================(11)      
                                                                                                                                                        (12)
                                                                                                                                     part No.1 out of 1 parts

=====================================================     Investigating use_kwargs_dict     ======================================================
===============================================================     on line 6     ================================================================
     with example 
@use_kwargs_dict(y=1,z=None, keep=True)
def foo(a, b=1, **kwargs): pass

test_sig(foo, '(a, b=1, *, y=1, z=None, **kwargs)')
     

print selected srcline with expands below--------
        sigd = dict(sig.parameters)                                                                                                                     (4)
        k = sigd.pop('kwargs')                                                                                                                          (5)
        s2 = {n:_mk_param(n,d) for n,d in kwargs.items() if n not in sigd}==============================================================================(6)
                                                                                                               how to create a dict of params based on a dict
        sigd.update(s2)                                                                                                                                 (7)
        if keep: sigd['kwargs'] = k                                                                                                                     (8)

Review srcode with all comments added so far======================================================================================================
def use_kwargs_dict(keep=False, **kwargs):================================================(0)       
    "Decorator: replace `**kwargs` in signature with `names` params"======================(1) # how to use use_kwargs_dict; use_kwargs_dict is to replace **kwargs with newly created KEYWORD_ONLY params based on a dict; f's signature is saved inside f.__signature__; 
    def _f(f):============================================================================(2)       
        sig = inspect.signature(f)========================================================(3) # how to get the signature from an object; 
        sigd = dict(sig.parameters)=======================================================(4) # how to get all parameters of a signature; how to make it into a dict; ; 
        k = sigd.pop('kwargs')============================================================(5) # how to pop out an item from a dict; 
        s2 = {n:_mk_param(n,d) for n,d in kwargs.items() if n not in sigd}================(6) # how to create a dict of params based on a dict; 
        sigd.update(s2)===================================================================(7)       
        if keep: sigd['kwargs'] = k=======================================================(8)       
        f.__signature__ = sig.replace(parameters=sigd.values())===========================(9)       
        return f==========================================================================(10)      
    return _f=============================================================================(11)      
                                                                                                                                                        (12)
                                                                                                                                     part No.1 out of 1 parts

=====================================================     Investigating use_kwargs_dict     ======================================================
===============================================================     on line 7     ================================================================
     with example 
@use_kwargs_dict(y=1,z=None, keep=True)
def foo(a, b=1, **kwargs): pass

test_sig(foo, '(a, b=1, *, y=1, z=None, **kwargs)')
     

print selected srcline with expands below--------
        k = sigd.pop('kwargs')                                                                                                                          (5)
        s2 = {n:_mk_param(n,d) for n,d in kwargs.items() if n not in sigd}                                                                              (6)
        sigd.update(s2)=================================================================================================================================(7)
                                                                                                                     how to udpate one dict into another dict
        if keep: sigd['kwargs'] = k                                                                                                                     (8)
        f.__signature__ = sig.replace(parameters=sigd.values())                                                                                         (9)

Review srcode with all comments added so far======================================================================================================
def use_kwargs_dict(keep=False, **kwargs):================================================(0)       
    "Decorator: replace `**kwargs` in signature with `names` params"======================(1) # how to use use_kwargs_dict; use_kwargs_dict is to replace **kwargs with newly created KEYWORD_ONLY params based on a dict; f's signature is saved inside f.__signature__; 
    def _f(f):============================================================================(2)       
        sig = inspect.signature(f)========================================================(3) # how to get the signature from an object; 
        sigd = dict(sig.parameters)=======================================================(4) # how to get all parameters of a signature; how to make it into a dict; ; 
        k = sigd.pop('kwargs')============================================================(5) # how to pop out an item from a dict; 
        s2 = {n:_mk_param(n,d) for n,d in kwargs.items() if n not in sigd}================(6) # how to create a dict of params based on a dict; 
        sigd.update(s2)===================================================================(7) # how to udpate one dict into another dict; 
        if keep: sigd['kwargs'] = k=======================================================(8)       
        f.__signature__ = sig.replace(parameters=sigd.values())===========================(9)       
        return f==========================================================================(10)      
    return _f=============================================================================(11)      
                                                                                                                                                        (12)
                                                                                                                                     part No.1 out of 1 parts

=====================================================     Investigating use_kwargs_dict     ======================================================
===============================================================     on line 8     ================================================================
     with example 
@use_kwargs_dict(y=1,z=None, keep=True)
def foo(a, b=1, **kwargs): pass

test_sig(foo, '(a, b=1, *, y=1, z=None, **kwargs)')
     

print selected srcline with expands below--------
        s2 = {n:_mk_param(n,d) for n,d in kwargs.items() if n not in sigd}                                                                              (6)
        sigd.update(s2)                                                                                                                                 (7)
        if keep: sigd['kwargs'] = k=====================================================================================================================(8)
                                                                                                                           how to create a new item in a dict
        f.__signature__ = sig.replace(parameters=sigd.values())                                                                                         (9)
        return f                                                                                                                                        (10)

Review srcode with all comments added so far======================================================================================================
def use_kwargs_dict(keep=False, **kwargs):================================================(0)       
    "Decorator: replace `**kwargs` in signature with `names` params"======================(1) # how to use use_kwargs_dict; use_kwargs_dict is to replace **kwargs with newly created KEYWORD_ONLY params based on a dict; f's signature is saved inside f.__signature__; 
    def _f(f):============================================================================(2)       
        sig = inspect.signature(f)========================================================(3) # how to get the signature from an object; 
        sigd = dict(sig.parameters)=======================================================(4) # how to get all parameters of a signature; how to make it into a dict; ; 
        k = sigd.pop('kwargs')============================================================(5) # how to pop out an item from a dict; 
        s2 = {n:_mk_param(n,d) for n,d in kwargs.items() if n not in sigd}================(6) # how to create a dict of params based on a dict; 
        sigd.update(s2)===================================================================(7) # how to udpate one dict into another dict; 
        if keep: sigd['kwargs'] = k=======================================================(8) # how to create a new item in a dict; 
        f.__signature__ = sig.replace(parameters=sigd.values())===========================(9)       
        return f==========================================================================(10)      
    return _f=============================================================================(11)      
                                                                                                                                                        (12)
                                                                                                                                     part No.1 out of 1 parts

=====================================================     Investigating use_kwargs_dict     ======================================================
===============================================================     on line 9     ================================================================
     with example 
@use_kwargs_dict(y=1,z=None, keep=True)
def foo(a, b=1, **kwargs): pass

test_sig(foo, '(a, b=1, *, y=1, z=None, **kwargs)')
     

print selected srcline with expands below--------
        sigd.update(s2)                                                                                                                                 (7)
        if keep: sigd['kwargs'] = k                                                                                                                     (8)
        f.__signature__ = sig.replace(parameters=sigd.values())=========================================================================================(9)
                                                                          how to update a signature with a new set of parameters in the form of a dict values
        return f                                                                                                                                        (10)
    return _f                                                                                                                                           (11)

Review srcode with all comments added so far======================================================================================================
def use_kwargs_dict(keep=False, **kwargs):================================================(0)       
    "Decorator: replace `**kwargs` in signature with `names` params"======================(1) # how to use use_kwargs_dict; use_kwargs_dict is to replace **kwargs with newly created KEYWORD_ONLY params based on a dict; f's signature is saved inside f.__signature__; 
    def _f(f):============================================================================(2)       
        sig = inspect.signature(f)========================================================(3) # how to get the signature from an object; 
        sigd = dict(sig.parameters)=======================================================(4) # how to get all parameters of a signature; how to make it into a dict; ; 
        k = sigd.pop('kwargs')============================================================(5) # how to pop out an item from a dict; 
        s2 = {n:_mk_param(n,d) for n,d in kwargs.items() if n not in sigd}================(6) # how to create a dict of params based on a dict; 
        sigd.update(s2)===================================================================(7) # how to udpate one dict into another dict; 
        if keep: sigd['kwargs'] = k=======================================================(8) # how to create a new item in a dict; 
        f.__signature__ = sig.replace(parameters=sigd.values())===========================(9) # how to update a signature with a new set of parameters in the form of a dict values; 
        return f==========================================================================(10)      
    return _f=============================================================================(11)      
                                                                                                                                                        (12)
                                                                                                                                     part No.1 out of 1 parts
fdb.snoop(deco=True) # how to use snoop on decorator
22:14:40.62 >>> Call to use_kwargs_dict in File "/tmp/use_kwargs_dict.py", line 3
22:14:40.62 ...... keep = True
22:14:40.62 ...... kwargs = {'y': 1, 'z': None}
22:14:40.62 ...... len(kwargs) = 2
22:14:40.62    3 | def use_kwargs_dict(keep=False, **kwargs):
22:14:40.62    5 |     import snoop
22:14:40.62 .......... snoop = <class 'snoop.configuration.Config.__init__.<locals>.ConfiguredTracer'>
22:14:40.62    6 |     @snoop
22:14:40.62    7 |     def _f(f):
22:14:40.62 .......... _f = <function use_kwargs_dict.<locals>._f>
22:14:40.62   16 |     return _f
22:14:40.62 <<< Return value from use_kwargs_dict: <function use_kwargs_dict.<locals>._f>
22:14:40.62 >>> Call to use_kwargs_dict.<locals>._f in File "/tmp/use_kwargs_dict.py", line 7
22:14:40.62 .......... f = <function foo>
22:14:40.62 .......... keep = True
22:14:40.62 .......... kwargs = {'y': 1, 'z': None}
22:14:40.62 .......... len(kwargs) = 2
22:14:40.62    7 |     def _f(f):
22:14:40.62    8 |         sig = inspect.signature(f)
22:14:40.62 .............. sig = <Signature (a, b=1, **kwargs)>
22:14:40.62    9 |         sigd = dict(sig.parameters)
22:14:40.62 .............. sigd = {'a': <Parameter "a">, 'b': <Parameter "b=1">, 'kwargs': <Parameter "**kwargs">}
22:14:40.62 .............. len(sigd) = 3
22:14:40.62   10 |         k = sigd.pop('kwargs')
22:14:40.62 .............. k = <Parameter "**kwargs">
22:14:40.62 .............. sigd = {'a': <Parameter "a">, 'b': <Parameter "b=1">}
22:14:40.62 .............. len(sigd) = 2
22:14:40.62   11 |         s2 = {n:_mk_param(n,d) for n,d in kwargs.items() if n not in sigd}
    22:14:40.62 Dict comprehension:
    22:14:40.62   11 |         s2 = {n:_mk_param(n,d) for n,d in kwargs.items() if n not in sigd}
    22:14:40.62 .............. Iterating over <dict_itemiterator object>
    22:14:40.62 .............. Values of sigd: {'a': <Parameter "a">, 'b': <Parameter "b=1">}
    22:14:40.62 .............. Values of len(sigd): 2
    22:14:40.62 .............. Values of n: 'y', 'z'
    22:14:40.62 .............. Values of d: 1, None
    22:14:40.62 Result: {'y': <Parameter "y=1">, 'z': <Parameter "z=None">}
22:14:40.62   11 |         s2 = {n:_mk_param(n,d) for n,d in kwargs.items() if n not in sigd}
22:14:40.62 .............. s2 = {'y': <Parameter "y=1">, 'z': <Parameter "z=None">}
22:14:40.62 .............. len(s2) = 2
22:14:40.62   12 |         sigd.update(s2)
22:14:40.62 .............. sigd = {'a': <Parameter "a">, 'b': <Parameter "b=1">, 'y': <Parameter "y=1">, 'z': <Parameter "z=None">}
22:14:40.62 .............. len(sigd) = 4
22:14:40.62   13 |         if keep: sigd['kwargs'] = k
22:14:40.62 ...... sigd = {'a': <Parameter "a">, 'b': <Parameter "b=1">, 'y': <Parameter "y=1">, 'z': <Parameter "z=None">, ...}
22:14:40.62 ...... len(sigd) = 5
22:14:40.62   14 |         f.__signature__ = sig.replace(parameters=sigd.values())
22:14:40.63   15 |         return f
22:14:40.63 <<< Return value from use_kwargs_dict.<locals>._f: <function foo>
=====================================================     Investigating use_kwargs_dict     ======================================================
==============================================================     on line None     ==============================================================
     with example 
@use_kwargs_dict(y=1,z=None, keep=True)
def foo(a, b=1, **kwargs): pass

test_sig(foo, '(a, b=1, *, y=1, z=None, **kwargs)')
     

use_kwargs

Reading docs

use_kwargs is different than use_kwargs_dict as it only replaces **kwargs with named parameters without any default values:

@use_kwargs(['y', 'z'])
def foo(a, b=1, **kwargs): pass

test_sig(foo, '(a, b=1, *, y=None, z=None)')

You may optionally keep the **kwargs argument in your signature by setting keep=True:

@use_kwargs(['y', 'z'], keep=True)
def foo(a, *args, b=1, **kwargs): pass
test_sig(foo, '(a, *args, b=1, y=None, z=None, **kwargs)')
print(inspect.getsource(use_kwargs))
def use_kwargs(names, keep=False):
    "Decorator: replace `**kwargs` in signature with `names` params"
    def _f(f):
        sig = inspect.signature(f)
        sigd = dict(sig.parameters)
        k = sigd.pop('kwargs')
        s2 = {n:_mk_param(n) for n in names if n not in sigd}
        sigd.update(s2)
        if keep: sigd['kwargs'] = k
        f.__signature__ = sig.replace(parameters=sigd.values())
        return f
    return _f
fdb = Fastdb(use_kwargs)
fdb.eg = """
@use_kwargs(['y', 'z'])
def foo(a, b=1, **kwargs): pass

test_sig(foo, '(a, b=1, *, y=None, z=None)')
"""

fdb.eg = """
@use_kwargs(['y', 'z'], keep=True)
def foo(a, *args, b=1, **kwargs): pass
test_sig(foo, '(a, *args, b=1, y=None, z=None, **kwargs)')
"""
fdb.print()
========================================================     Investigating use_kwargs     ========================================================
==============================================================     on line None     ==============================================================
     with example 
@use_kwargs(['y', 'z'], keep=True)
def foo(a, *args, b=1, **kwargs): pass
test_sig(foo, '(a, *args, b=1, y=None, z=None, **kwargs)')
     

def use_kwargs(names, keep=False):========================================================(0)       
    "Decorator: replace `**kwargs` in signature with `names` params"======================(1)       
    def _f(f):============================================================================(2)       
        sig = inspect.signature(f)========================================================(3)       
        sigd = dict(sig.parameters)=======================================================(4)       
        k = sigd.pop('kwargs')============================================================(5)       
        s2 = {n:_mk_param(n) for n in names if n not in sigd}=============================(6)       
        sigd.update(s2)===================================================================(7)       
        if keep: sigd['kwargs'] = k=======================================================(8)       
        f.__signature__ = sig.replace(parameters=sigd.values())===========================(9)       
        return f==========================================================================(10)      
    return _f=============================================================================(11)      
                                                                                                                                                        (12)
fdb.docsrc(0, "How to use use_kwargs; use_kwargs has names as a list of strings; all the newly created params have None as default value; f's signature \
is saved inside f.__signature__")
========================================================     Investigating use_kwargs     ========================================================
===============================================================     on line 0     ================================================================
     with example 
@use_kwargs(['y', 'z'], keep=True)
def foo(a, *args, b=1, **kwargs): pass
test_sig(foo, '(a, *args, b=1, y=None, z=None, **kwargs)')
     

print selected srcline with expands below--------
def use_kwargs(names, keep=False):======================================================================================================================(0)
How to use use_kwargs; use_kwargs has names as a list of strings; all the newly created params have None as default value; f's signature is saved inside f.__signature__
    "Decorator: replace `**kwargs` in signature with `names` params"                                                                                    (1)
    def _f(f):                                                                                                                                          (2)
fdb.snoop(deco=True)
22:14:40.65 >>> Call to use_kwargs in File "/tmp/use_kwargs.py", line 3
22:14:40.65 ...... names = ['y', 'z']
22:14:40.65 ...... len(names) = 2
22:14:40.65 ...... keep = True
22:14:40.65    3 | def use_kwargs(names, keep=False):
22:14:40.65    5 |     import snoop
22:14:40.65 .......... snoop = <class 'snoop.configuration.Config.__init__.<locals>.ConfiguredTracer'>
22:14:40.65    6 |     @snoop
22:14:40.65    7 |     def _f(f):
22:14:40.65 .......... _f = <function use_kwargs.<locals>._f>
22:14:40.65   16 |     return _f
22:14:40.65 <<< Return value from use_kwargs: <function use_kwargs.<locals>._f>
22:14:40.65 >>> Call to use_kwargs.<locals>._f in File "/tmp/use_kwargs.py", line 7
22:14:40.65 .......... f = <function foo>
22:14:40.65 .......... keep = True
22:14:40.65 .......... names = ['y', 'z']
22:14:40.65 .......... len(names) = 2
22:14:40.65    7 |     def _f(f):
22:14:40.65    8 |         sig = inspect.signature(f)
22:14:40.65 .............. sig = <Signature (a, *args, b=1, **kwargs)>
22:14:40.65    9 |         sigd = dict(sig.parameters)
22:14:40.65 .............. sigd = {'a': <Parameter "a">, 'args': <Parameter "*args">, 'b': <Parameter "b=1">, 'kwargs': <Parameter "**kwargs">}
22:14:40.65 .............. len(sigd) = 4
22:14:40.65   10 |         k = sigd.pop('kwargs')
22:14:40.65 .............. k = <Parameter "**kwargs">
22:14:40.65 .............. sigd = {'a': <Parameter "a">, 'args': <Parameter "*args">, 'b': <Parameter "b=1">}
22:14:40.65 .............. len(sigd) = 3
22:14:40.65   11 |         s2 = {n:_mk_param(n) for n in names if n not in sigd}
    22:14:40.65 Dict comprehension:
    22:14:40.65   11 |         s2 = {n:_mk_param(n) for n in names if n not in sigd}
    22:14:40.65 .............. Iterating over <list_iterator object>
    22:14:40.65 .............. Values of sigd: {'a': <Parameter "a">, 'args': <Parameter "*args">, 'b': <Parameter "b=1">}
    22:14:40.65 .............. Values of len(sigd): 3
    22:14:40.65 .............. Values of n: 'y', 'z'
    22:14:40.65 Result: {'y': <Parameter "y=None">, 'z': <Parameter "z=None">}
22:14:40.65   11 |         s2 = {n:_mk_param(n) for n in names if n not in sigd}
22:14:40.65 .............. s2 = {'y': <Parameter "y=None">, 'z': <Parameter "z=None">}
22:14:40.65 .............. len(s2) = 2
22:14:40.65   12 |         sigd.update(s2)
22:14:40.65 .............. sigd = {'a': <Parameter "a">, 'args': <Parameter "*args">, 'b': <Parameter "b=1">, 'y': <Parameter "y=None">, ...}
22:14:40.65 .............. len(sigd) = 5
22:14:40.65   13 |         if keep: sigd['kwargs'] = k
22:14:40.65 ...... len(sigd) = 6
22:14:40.65   14 |         f.__signature__ = sig.replace(parameters=sigd.values())
22:14:40.65   15 |         return f
22:14:40.65 <<< Return value from use_kwargs.<locals>._f: <function foo>
========================================================     Investigating use_kwargs     ========================================================
==============================================================     on line None     ==============================================================
     with example 
@use_kwargs(['y', 'z'], keep=True)
def foo(a, *args, b=1, **kwargs): pass
test_sig(foo, '(a, *args, b=1, y=None, z=None, **kwargs)')