0001_Fastcore.meta.delegates

# from IPython.core.display import display, HTML # a depreciated import
from IPython.display import display, HTML 

display(HTML("<style>.container { width:100% !important; }</style>"))

Import

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

Initiate Fastdb and example in str

g = locals() # this is a must
fdb = Fastdb(delegates, outloc=g)

Example

def low(a, b=1): pass
@delegates(low) # this format is fine too
def mid(c, d=1, **kwargs): pass
pprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug
<Signature (c, d=1, *, b=1)>
def low(a, b=1): pass
def mid(c, d=1, **kwargs): pass
pprint(inspect.signature(delegates(low)(mid)))
<Signature (c, d=1, *, b=1)>
fdb.eg = """
def low(a, b=1): pass
def mid(c, d=1, **kwargs): pass
pprint(inspect.signature(delegates(low)(mid)))
"""
fdb.eg = """
def low(a, b=1): pass
@delegates(low)
def mid(c, d=1, **kwargs): pass
pprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug
"""
fdb.eg = """
class Foo:
    @classmethod
    def clsm(a, b=1): pass
    
    @delegates(clsm)
    def instm(c, d=1, **kwargs): pass
f = Foo()
pprint(inspect.signature(f.instm)) # pprint and inspect is loaded from fastdebug
"""
fdb.eg = """
def low(a, b:int=1): pass
@delegates(low)
def mid(c, d:list=None, **kwargs): pass
pprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug
"""

docsrc

fdb.eg
'\ndef low(a, b:int=1): pass\n@delegates(low)\ndef mid(c, d:list=None, **kwargs): pass\npprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug\n'
fdb.print()
========================================================     Investigating delegates     =========================================================
==============================================================     on line None     ==============================================================
     with example 
def low(a, b:int=1): pass
@delegates(low)
def mid(c, d:list=None, **kwargs): pass
pprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug
     

def delegates(to:FunctionType=None, # Delegatee===========================================(0)       
              keep=False, # Keep `kwargs` in decorated function?==========================(1)       
              but:list=None): # Exclude these parameters from signature===================(2)       
    "Decorator: replace `**kwargs` in signature with params from `to`"====================(3)       
    if but is None: but = []==============================================================(4)       
    def _f(f):============================================================================(5)       
        if to is None: to_f,from_f = f.__base__.__init__,f.__init__=======================(6)       
        else:          to_f,from_f = to.__init__ if isinstance(to,type) else to,f=========(7)       
        from_f = getattr(from_f,'__func__',from_f)========================================(8)       
        to_f = getattr(to_f,'__func__',to_f)==============================================(9)       
        if hasattr(from_f,'__delwrap__'): return f========================================(10)      
        sig = inspect.signature(from_f)===================================================(11)      
        sigd = dict(sig.parameters)=======================================================(12)      
        k = sigd.pop('kwargs')============================================================(13)      
        s2 = {k:v.replace(kind=inspect.Parameter.KEYWORD_ONLY) for k,v in inspect.signature(to_f).parameters.items()                                    (14)
              if v.default != inspect.Parameter.empty and k not in sigd and k not in but}=(15)      
        anno = {k:v for k,v in getattr(to_f, "__annotations__", {}).items() if k not in sigd and k not in but}                                          (16)
        sigd.update(s2)===================================================================(17)      
        if keep: sigd['kwargs'] = k=======================================================(18)      
        else: from_f.__delwrap__ = to_f===================================================(19)      
        from_f.__signature__ = sig.replace(parameters=sigd.values())======================(20)      
        if hasattr(from_f, '__annotations__'): from_f.__annotations__.update(anno)========(21)      
        return f==========================================================================(22)      
    return _f=============================================================================(23)      
                                                                                                                                                        (24)
fdb.docsrc(21, "How to check whether a func has __annotations__; How add selected params' annotations from A to B's annotations;")

fdb.docsrc(14, "How to access a signature's parameters as a dict?; How to replace the kind of a parameter with a different kind?; \
how to check whether a parameter has a default value?; How to check whether a string is in a dict and a list?; \
how dict.items() and dict.values() differ", \
"inspect.signature(to_f).parameters.items()", "inspect.signature(to_f).parameters.values()", "inspect.Parameter.empty", \
"for k,v in inspect.signature(to_f).parameters.items():\\n\
    printright(f'v.kind: {v.kind}')\\n\
    printright(f'v.default: {v.default}')\\n\
    v1 = v.replace(kind=inspect.Parameter.KEYWORD_ONLY)\\n\
    printright(f'v1.kind: {v1.kind}')")

fdb.docsrc(16, "How to get A's __annotations__?; How to access it as a dict?; \
How to select annotations of the right params with names?; How to put them into a dict?; How to do it all in a single line", \
          "getattr(to_f, '__annotations__', {})", "getattr(from_f, '__annotations__', {})")
fdb.docsrc(17, "How to add the selected params from A's signature to B's signature; How to add items into a dict;")
fdb.docsrc(18, "How to add a new item into a dict;")
fdb.docsrc(19, "How to create a new attr for a function or obj;")
fdb.docsrc(20, "How to update a signature with a new set of parameters;", "sigd", "sigd.values()", "sig", \
           "sig.replace(parameters=sigd.values())")


fdb.docsrc(2, "how to make delegates(to, but) to have 'but' as list and default as None")
fdb.docsrc(0, "how to make delegates(to) to have to as FunctionType and default as None")
fdb.docsrc(6, "how to write 2 ifs and elses in 2 lines")
fdb.docsrc(7, "how to assign a,b together with if and else")
fdb.docsrc(8, "Is classmethod callable; does classmethod has __func__; can we do inspect.signature(clsmethod); \
how to use getattr(obj, attr, default)", \
           "from_f", "to_f", \
           "hasattr(from_f, '__func__')", "from_f = getattr(from_f,'__func__',from_f)", \
           "hasattr(to_f, '__func__')", "from_f = getattr(to_f,'__func__',to_f)", "callable(to_f)")

fdb.docsrc(10, "if B has __delwrap__, can we do delegates(A)(B) again?; hasattr(obj, '__delwrap__')")
fdb.docsrc(11, "how to get signature obj of B; what does a signature look like; what is the type", "inspect.signature(from_f)", "type(inspect.signature(from_f))")
fdb.docsrc(12, "How to access parameters of a signature?; How to turn parameters into a dict?", "sig.parameters", "dict(sig.parameters)")
fdb.docsrc(13, "How to remove an item from a dict?; How to get the removed item from a dict?; How to add the removed item back to the dict?; \
when writing expressions, as they share environment, so they may affect the following code", "sigd", "k = sigd.pop('kwargs')", "sigd", "sigd['kwargs'] = k")


# fdb.docsrc(3,"Personal Docs: delegates(A)(B), given B has kwargs in sig; delegating params of A to B; A and B can be funcs, methods, classes; \
# when A or B are classmethod or if they have __func__, then __func__ shall be used to get sig/params; \
# when A and B are classes, A.__init__ is actually used to get sig/params, B offers sig/params as a class; \
# B only take wanted and missing params with default values; B can keep its kwargs, if not, B will store A in __delwrap__ to prevent delegates(A)(B) again;\
# B will get __signature__ and store its new sig; if B has __annotations__, then add what B want from A's __annotations__")
========================================================     Investigating delegates     =========================================================
===============================================================     on line 21     ===============================================================
     with example 
def low(a, b:int=1): pass
@delegates(low)
def mid(c, d:list=None, **kwargs): pass
pprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug
     

print selected srcline with expands below--------
        else: from_f.__delwrap__ = to_f                                                                                                                 (19)
        from_f.__signature__ = sig.replace(parameters=sigd.values())                                                                                    (20)
        if hasattr(from_f, '__annotations__'): from_f.__annotations__.update(anno)======================================================================(21)
                                             How to check whether a func has __annotations__; How add selected params' annotations from A to B's annotations;
        return f                                                                                                                                        (22)
    return _f                                                                                                                                           (23)
========================================================     Investigating delegates     =========================================================
===============================================================     on line 14     ===============================================================
     with example 
def low(a, b:int=1): pass
@delegates(low)
def mid(c, d:list=None, **kwargs): pass
pprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug
     

print selected srcline with expands below--------
        sigd = dict(sig.parameters)                                                                                                                     (12)
        k = sigd.pop('kwargs')                                                                                                                          (13)
        s2 = {k:v.replace(kind=inspect.Parameter.KEYWORD_ONLY) for k,v in inspect.signature(to_f).parameters.items()====================================(14)
How to access a signature's parameters as a dict?; How to replace the kind of a parameter with a different kind?; how to check whether a parameter has a default value?; How to check whether a string is in a dict and a list?; how dict.items() and dict.values() differ
              if v.default != inspect.Parameter.empty and k not in sigd and k not in but}                                                               (15)
        anno = {k:v for k,v in getattr(to_f, "__annotations__", {}).items() if k not in sigd and k not in but}                                          (16)

==================================================================================================================Start of my srcline exploration:


inspect.signature(to_f).parameters.items() => inspect.signature(to_f).parameters.items() : odict_items([('a', <Parameter "a">), ('b', <Parameter "b: int = 1">)])


       inspect.signature(to_f).parameters.values() => inspect.signature(to_f).parameters.values() : odict_values([<Parameter "a">, <Parameter "b: int = 1">])


                                                                                inspect.Parameter.empty => inspect.Parameter.empty : <class 'inspect._empty'>


for k,v in inspect.signature(to_f).parameters.items():
    printright(f'v.kind: {v.kind}')
    printright(f'v.default: {v.default}')
    v1 = v.replace(kind=inspect.Parameter.KEYWORD_ONLY)
    printright(f'v1.kind: {v1.kind}')

Running the code block above => ====================================================================

                                                                                                                                v.kind: POSITIONAL_OR_KEYWORD
                                                                                                                          v.default: <class 'inspect._empty'>
                                                                                                                                        v1.kind: KEYWORD_ONLY
                                                                                                                                v.kind: POSITIONAL_OR_KEYWORD
                                                                                                                                                 v.default: 1
                                                                                                                                        v1.kind: KEYWORD_ONLY
====================================================================================================================End of my srcline exploration:

<Signature (c, d: list = None, *, b: int = 1)>

Review srcode with all comments added so far======================================================================================================
def delegates(to:FunctionType=None, # Delegatee===========================================(0)       
              keep=False, # Keep `kwargs` in decorated function?==========================(1)       
              but:list=None): # Exclude these parameters from signature===================(2)       
    "Decorator: replace `**kwargs` in signature with params from `to`"====================(3)       
    if but is None: but = []==============================================================(4)       
    def _f(f):============================================================================(5)       
        if to is None: to_f,from_f = f.__base__.__init__,f.__init__=======================(6)       
        else:          to_f,from_f = to.__init__ if isinstance(to,type) else to,f=========(7)       
        from_f = getattr(from_f,'__func__',from_f)========================================(8)       
        to_f = getattr(to_f,'__func__',to_f)==============================================(9)       
        if hasattr(from_f,'__delwrap__'): return f========================================(10)      
        sig = inspect.signature(from_f)===================================================(11)      
        sigd = dict(sig.parameters)=======================================================(12)      
        k = sigd.pop('kwargs')============================================================(13)      
        s2 = {k:v.replace(kind=inspect.Parameter.KEYWORD_ONLY) for k,v in inspect.signature(to_f).parameters.items() # How to access a signature's parameters as a dict?; How to replace the kind of a parameter with a different kind?; how to check whether a parameter has a default value?; How to check whether a string is in a dict and a list?; how dict.items() and dict.values() differ;  (14)
              if v.default != inspect.Parameter.empty and k not in sigd and k not in but}=(15)      
        anno = {k:v for k,v in getattr(to_f, "__annotations__", {}).items() if k not in sigd and k not in but}                                          (16)
        sigd.update(s2)===================================================================(17)      
        if keep: sigd['kwargs'] = k=======================================================(18)      
        else: from_f.__delwrap__ = to_f===================================================(19)      
                                                                                                                                     part No.1 out of 2 parts

========================================================     Investigating delegates     =========================================================
===============================================================     on line 16     ===============================================================
     with example 
def low(a, b:int=1): pass
@delegates(low)
def mid(c, d:list=None, **kwargs): pass
pprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug
     

print selected srcline with expands below--------
        s2 = {k:v.replace(kind=inspect.Parameter.KEYWORD_ONLY) for k,v in inspect.signature(to_f).parameters.items()                                    (14)
              if v.default != inspect.Parameter.empty and k not in sigd and k not in but}                                                               (15)
        anno = {k:v for k,v in getattr(to_f, "__annotations__", {}).items() if k not in sigd and k not in but}==========================================(16)
How to get A's __annotations__?; How to access it as a dict?; How to select annotations of the right params with names?; How to put them into a dict?; How to do it all in a single line
        sigd.update(s2)                                                                                                                                 (17)
        if keep: sigd['kwargs'] = k                                                                                                                     (18)

==================================================================================================================Start of my srcline exploration:


                                                          getattr(to_f, '__annotations__', {}) => getattr(to_f, '__annotations__', {}) : {'b': <class 'int'>}


                                                     getattr(from_f, '__annotations__', {}) => getattr(from_f, '__annotations__', {}) : {'d': <class 'list'>}
====================================================================================================================End of my srcline exploration:

<Signature (c, d: list = None, *, b: int = 1)>

Review srcode with all comments added so far======================================================================================================
def delegates(to:FunctionType=None, # Delegatee===========================================(0)       
              keep=False, # Keep `kwargs` in decorated function?==========================(1)       
              but:list=None): # Exclude these parameters from signature===================(2)       
    "Decorator: replace `**kwargs` in signature with params from `to`"====================(3)       
    if but is None: but = []==============================================================(4)       
    def _f(f):============================================================================(5)       
        if to is None: to_f,from_f = f.__base__.__init__,f.__init__=======================(6)       
        else:          to_f,from_f = to.__init__ if isinstance(to,type) else to,f=========(7)       
        from_f = getattr(from_f,'__func__',from_f)========================================(8)       
        to_f = getattr(to_f,'__func__',to_f)==============================================(9)       
        if hasattr(from_f,'__delwrap__'): return f========================================(10)      
        sig = inspect.signature(from_f)===================================================(11)      
        sigd = dict(sig.parameters)=======================================================(12)      
        k = sigd.pop('kwargs')============================================================(13)      
        s2 = {k:v.replace(kind=inspect.Parameter.KEYWORD_ONLY) for k,v in inspect.signature(to_f).parameters.items() # How to access a signature's parameters as a dict?; How to replace the kind of a parameter with a different kind?; how to check whether a parameter has a default value?; How to check whether a string is in a dict and a list?; how dict.items() and dict.values() differ;  (14)
              if v.default != inspect.Parameter.empty and k not in sigd and k not in but}=(15)      
        anno = {k:v for k,v in getattr(to_f, "__annotations__", {}).items() if k not in sigd and k not in but} # How to get A's __annotations__?; How to access it as a dict?; How to select annotations of the right params with names?; How to put them into a dict?; How to do it all in a single line;  (16)
        sigd.update(s2)===================================================================(17)      
        if keep: sigd['kwargs'] = k=======================================================(18)      
        else: from_f.__delwrap__ = to_f===================================================(19)      
                                                                                                                                     part No.1 out of 2 parts

========================================================     Investigating delegates     =========================================================
===============================================================     on line 17     ===============================================================
     with example 
def low(a, b:int=1): pass
@delegates(low)
def mid(c, d:list=None, **kwargs): pass
pprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug
     

print selected srcline with expands below--------
              if v.default != inspect.Parameter.empty and k not in sigd and k not in but}                                                               (15)
        anno = {k:v for k,v in getattr(to_f, "__annotations__", {}).items() if k not in sigd and k not in but}                                          (16)
        sigd.update(s2)=================================================================================================================================(17)
                                                            How to add the selected params from A's signature to B's signature; How to add items into a dict;
        if keep: sigd['kwargs'] = k                                                                                                                     (18)
        else: from_f.__delwrap__ = to_f                                                                                                                 (19)
========================================================     Investigating delegates     =========================================================
===============================================================     on line 18     ===============================================================
     with example 
def low(a, b:int=1): pass
@delegates(low)
def mid(c, d:list=None, **kwargs): pass
pprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug
     

print selected srcline with expands below--------
        anno = {k:v for k,v in getattr(to_f, "__annotations__", {}).items() if k not in sigd and k not in but}                                          (16)
        sigd.update(s2)                                                                                                                                 (17)
        if keep: sigd['kwargs'] = k=====================================================================================================================(18)
                                                                                                                           How to add a new item into a dict;
        else: from_f.__delwrap__ = to_f                                                                                                                 (19)
        from_f.__signature__ = sig.replace(parameters=sigd.values())                                                                                    (20)
========================================================     Investigating delegates     =========================================================
===============================================================     on line 19     ===============================================================
     with example 
def low(a, b:int=1): pass
@delegates(low)
def mid(c, d:list=None, **kwargs): pass
pprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug
     

print selected srcline with expands below--------
        sigd.update(s2)                                                                                                                                 (17)
        if keep: sigd['kwargs'] = k                                                                                                                     (18)
        else: from_f.__delwrap__ = to_f=================================================================================================================(19)
                                                                                                              How to create a new attr for a function or obj;
        from_f.__signature__ = sig.replace(parameters=sigd.values())                                                                                    (20)
        if hasattr(from_f, '__annotations__'): from_f.__annotations__.update(anno)                                                                      (21)
========================================================     Investigating delegates     =========================================================
===============================================================     on line 20     ===============================================================
     with example 
def low(a, b:int=1): pass
@delegates(low)
def mid(c, d:list=None, **kwargs): pass
pprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug
     

print selected srcline with expands below--------
        if keep: sigd['kwargs'] = k                                                                                                                     (18)
        else: from_f.__delwrap__ = to_f                                                                                                                 (19)
        from_f.__signature__ = sig.replace(parameters=sigd.values())====================================================================================(20)
                                                                                                      How to update a signature with a new set of parameters;
        if hasattr(from_f, '__annotations__'): from_f.__annotations__.update(anno)                                                                      (21)
        return f                                                                                                                                        (22)

==================================================================================================================Start of my srcline exploration:


                                                      sigd => sigd : {'c': <Parameter "c">, 'd': <Parameter "d: list = None">, 'b': <Parameter "b: int = 1">}


                                      sigd.values() => sigd.values() : dict_values([<Parameter "c">, <Parameter "d: list = None">, <Parameter "b: int = 1">])


                                                                                                                   sig => sig : (c, d: list = None, **kwargs)


                                           sig.replace(parameters=sigd.values()) => sig.replace(parameters=sigd.values()): (c, d: list = None, *, b: int = 1)
====================================================================================================================End of my srcline exploration:

<Signature (c, d: list = None, *, b: int = 1)>

Review srcode with all comments added so far======================================================================================================
        from_f.__signature__ = sig.replace(parameters=sigd.values())======================(20) # How to update a signature with a new set of parameters;; 
        if hasattr(from_f, '__annotations__'): from_f.__annotations__.update(anno)========(21) # How to check whether a func has __annotations__; How add selected params' annotations from A to B's annotations;; 
        return f==========================================================================(22)      
    return _f=============================================================================(23)      
                                                                                                                                                        (24)
                                                                                                                                     part No.2 out of 2 parts

========================================================     Investigating delegates     =========================================================
===============================================================     on line 2     ================================================================
     with example 
def low(a, b:int=1): pass
@delegates(low)
def mid(c, d:list=None, **kwargs): pass
pprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug
     

print selected srcline with expands below--------
def delegates(to:FunctionType=None, # Delegatee                                                                                                         (0)
              keep=False, # Keep `kwargs` in decorated function?                                                                                        (1)
              but:list=None): # Exclude these parameters from signature=================================================================================(2)
                                                                                     how to make delegates(to, but) to have 'but' as list and default as None
    "Decorator: replace `**kwargs` in signature with params from `to`"                                                                                  (3)
    if but is None: but = []                                                                                                                            (4)
========================================================     Investigating delegates     =========================================================
===============================================================     on line 0     ================================================================
     with example 
def low(a, b:int=1): pass
@delegates(low)
def mid(c, d:list=None, **kwargs): pass
pprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug
     

print selected srcline with expands below--------
def delegates(to:FunctionType=None, # Delegatee=========================================================================================================(0)
                                                                                     how to make delegates(to) to have to as FunctionType and default as None
              keep=False, # Keep `kwargs` in decorated function?                                                                                        (1)
              but:list=None): # Exclude these parameters from signature                                                                                 (2)
========================================================     Investigating delegates     =========================================================
===============================================================     on line 6     ================================================================
     with example 
def low(a, b:int=1): pass
@delegates(low)
def mid(c, d:list=None, **kwargs): pass
pprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug
     

print selected srcline with expands below--------
    if but is None: but = []                                                                                                                            (4)
    def _f(f):                                                                                                                                          (5)
        if to is None: to_f,from_f = f.__base__.__init__,f.__init__=====================================================================================(6)
                                                                                                                      how to write 2 ifs and elses in 2 lines
        else:          to_f,from_f = to.__init__ if isinstance(to,type) else to,f                                                                       (7)
        from_f = getattr(from_f,'__func__',from_f)                                                                                                      (8)
========================================================     Investigating delegates     =========================================================
===============================================================     on line 7     ================================================================
     with example 
def low(a, b:int=1): pass
@delegates(low)
def mid(c, d:list=None, **kwargs): pass
pprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug
     

print selected srcline with expands below--------
    def _f(f):                                                                                                                                          (5)
        if to is None: to_f,from_f = f.__base__.__init__,f.__init__                                                                                     (6)
        else:          to_f,from_f = to.__init__ if isinstance(to,type) else to,f=======================================================================(7)
                                                                                                                  how to assign a,b together with if and else
        from_f = getattr(from_f,'__func__',from_f)                                                                                                      (8)
        to_f = getattr(to_f,'__func__',to_f)                                                                                                            (9)
========================================================     Investigating delegates     =========================================================
===============================================================     on line 8     ================================================================
     with example 
def low(a, b:int=1): pass
@delegates(low)
def mid(c, d:list=None, **kwargs): pass
pprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug
     

print selected srcline with expands below--------
        if to is None: to_f,from_f = f.__base__.__init__,f.__init__                                                                                     (6)
        else:          to_f,from_f = to.__init__ if isinstance(to,type) else to,f                                                                       (7)
        from_f = getattr(from_f,'__func__',from_f)======================================================================================================(8)
                       Is classmethod callable; does classmethod has __func__; can we do inspect.signature(clsmethod); how to use getattr(obj, attr, default)
        to_f = getattr(to_f,'__func__',to_f)                                                                                                            (9)
        if hasattr(from_f,'__delwrap__'): return f                                                                                                      (10)

==================================================================================================================Start of my srcline exploration:


                                                                                                             from_f => from_f : <function mid>


                                                                                                                 to_f => to_f : <function low>


                                                                                           hasattr(from_f, '__func__') => hasattr(from_f, '__func__') : False


                                                                          from_f = getattr(from_f,'__func__',from_f) => from_f: <function mid>


                                                                                               hasattr(to_f, '__func__') => hasattr(to_f, '__func__') : False


                                                                              from_f = getattr(to_f,'__func__',to_f) => from_f: <function low>


                                                                                                                      callable(to_f) => callable(to_f) : True
====================================================================================================================End of my srcline exploration:

<Signature (c, d: list = None, *, b: int = 1)>

Review srcode with all comments added so far======================================================================================================
def delegates(to:FunctionType=None, # Delegatee===========================================(0) # how to make delegates(to) to have to as FunctionType and default as None; 
              keep=False, # Keep `kwargs` in decorated function?==========================(1)       
              but:list=None): # Exclude these parameters from signature===================(2) # how to make delegates(to, but) to have 'but' as list and default as None; 
    "Decorator: replace `**kwargs` in signature with params from `to`"====================(3)       
    if but is None: but = []==============================================================(4)       
    def _f(f):============================================================================(5)       
        if to is None: to_f,from_f = f.__base__.__init__,f.__init__=======================(6) # how to write 2 ifs and elses in 2 lines; 
        else:          to_f,from_f = to.__init__ if isinstance(to,type) else to,f=========(7) # how to assign a,b together with if and else; 
        from_f = getattr(from_f,'__func__',from_f)========================================(8) # Is classmethod callable; does classmethod has __func__; can we do inspect.signature(clsmethod); how to use getattr(obj, attr, default); 
        to_f = getattr(to_f,'__func__',to_f)==============================================(9)       
        if hasattr(from_f,'__delwrap__'): return f========================================(10)      
        sig = inspect.signature(from_f)===================================================(11)      
        sigd = dict(sig.parameters)=======================================================(12)      
        k = sigd.pop('kwargs')============================================================(13)      
        s2 = {k:v.replace(kind=inspect.Parameter.KEYWORD_ONLY) for k,v in inspect.signature(to_f).parameters.items() # How to access a signature's parameters as a dict?; How to replace the kind of a parameter with a different kind?; how to check whether a parameter has a default value?; How to check whether a string is in a dict and a list?; how dict.items() and dict.values() differ;  (14)
              if v.default != inspect.Parameter.empty and k not in sigd and k not in but}=(15)      
        anno = {k:v for k,v in getattr(to_f, "__annotations__", {}).items() if k not in sigd and k not in but} # How to get A's __annotations__?; How to access it as a dict?; How to select annotations of the right params with names?; How to put them into a dict?; How to do it all in a single line;  (16)
        sigd.update(s2)===================================================================(17) # How to add the selected params from A's signature to B's signature; How to add items into a dict;; 
        if keep: sigd['kwargs'] = k=======================================================(18) # How to add a new item into a dict;; 
        else: from_f.__delwrap__ = to_f===================================================(19) # How to create a new attr for a function or obj;; 
                                                                                                                                     part No.1 out of 2 parts

========================================================     Investigating delegates     =========================================================
===============================================================     on line 10     ===============================================================
     with example 
def low(a, b:int=1): pass
@delegates(low)
def mid(c, d:list=None, **kwargs): pass
pprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug
     

print selected srcline with expands below--------
        from_f = getattr(from_f,'__func__',from_f)                                                                                                      (8)
        to_f = getattr(to_f,'__func__',to_f)                                                                                                            (9)
        if hasattr(from_f,'__delwrap__'): return f======================================================================================================(10)
                                                                          if B has __delwrap__, can we do delegates(A)(B) again?; hasattr(obj, '__delwrap__')
        sig = inspect.signature(from_f)                                                                                                                 (11)
        sigd = dict(sig.parameters)                                                                                                                     (12)
========================================================     Investigating delegates     =========================================================
===============================================================     on line 11     ===============================================================
     with example 
def low(a, b:int=1): pass
@delegates(low)
def mid(c, d:list=None, **kwargs): pass
pprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug
     

print selected srcline with expands below--------
        to_f = getattr(to_f,'__func__',to_f)                                                                                                            (9)
        if hasattr(from_f,'__delwrap__'): return f                                                                                                      (10)
        sig = inspect.signature(from_f)=================================================================================================================(11)
                                                                             how to get signature obj of B; what does a signature look like; what is the type
        sigd = dict(sig.parameters)                                                                                                                     (12)
        k = sigd.pop('kwargs')                                                                                                                          (13)

==================================================================================================================Start of my srcline exploration:


                                                                       inspect.signature(from_f) => inspect.signature(from_f) : (c, d: list = None, **kwargs)


                                                             type(inspect.signature(from_f)) => type(inspect.signature(from_f)) : <class 'inspect.Signature'>
====================================================================================================================End of my srcline exploration:

<Signature (c, d: list = None, *, b: int = 1)>

Review srcode with all comments added so far======================================================================================================
def delegates(to:FunctionType=None, # Delegatee===========================================(0) # how to make delegates(to) to have to as FunctionType and default as None; 
              keep=False, # Keep `kwargs` in decorated function?==========================(1)       
              but:list=None): # Exclude these parameters from signature===================(2) # how to make delegates(to, but) to have 'but' as list and default as None; 
    "Decorator: replace `**kwargs` in signature with params from `to`"====================(3)       
    if but is None: but = []==============================================================(4)       
    def _f(f):============================================================================(5)       
        if to is None: to_f,from_f = f.__base__.__init__,f.__init__=======================(6) # how to write 2 ifs and elses in 2 lines; 
        else:          to_f,from_f = to.__init__ if isinstance(to,type) else to,f=========(7) # how to assign a,b together with if and else; 
        from_f = getattr(from_f,'__func__',from_f)========================================(8) # Is classmethod callable; does classmethod has __func__; can we do inspect.signature(clsmethod); how to use getattr(obj, attr, default); 
        to_f = getattr(to_f,'__func__',to_f)==============================================(9)       
        if hasattr(from_f,'__delwrap__'): return f========================================(10) # if B has __delwrap__, can we do delegates(A)(B) again?; hasattr(obj, '__delwrap__'); 
        sig = inspect.signature(from_f)===================================================(11) # how to get signature obj of B; what does a signature look like; what is the type; 
        sigd = dict(sig.parameters)=======================================================(12)      
        k = sigd.pop('kwargs')============================================================(13)      
        s2 = {k:v.replace(kind=inspect.Parameter.KEYWORD_ONLY) for k,v in inspect.signature(to_f).parameters.items() # How to access a signature's parameters as a dict?; How to replace the kind of a parameter with a different kind?; how to check whether a parameter has a default value?; How to check whether a string is in a dict and a list?; how dict.items() and dict.values() differ;  (14)
              if v.default != inspect.Parameter.empty and k not in sigd and k not in but}=(15)      
        anno = {k:v for k,v in getattr(to_f, "__annotations__", {}).items() if k not in sigd and k not in but} # How to get A's __annotations__?; How to access it as a dict?; How to select annotations of the right params with names?; How to put them into a dict?; How to do it all in a single line;  (16)
        sigd.update(s2)===================================================================(17) # How to add the selected params from A's signature to B's signature; How to add items into a dict;; 
        if keep: sigd['kwargs'] = k=======================================================(18) # How to add a new item into a dict;; 
        else: from_f.__delwrap__ = to_f===================================================(19) # How to create a new attr for a function or obj;; 
                                                                                                                                     part No.1 out of 2 parts

========================================================     Investigating delegates     =========================================================
===============================================================     on line 12     ===============================================================
     with example 
def low(a, b:int=1): pass
@delegates(low)
def mid(c, d:list=None, **kwargs): pass
pprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug
     

print selected srcline with expands below--------
        if hasattr(from_f,'__delwrap__'): return f                                                                                                      (10)
        sig = inspect.signature(from_f)                                                                                                                 (11)
        sigd = dict(sig.parameters)=====================================================================================================================(12)
                                                                                How to access parameters of a signature?; How to turn parameters into a dict?
        k = sigd.pop('kwargs')                                                                                                                          (13)
        s2 = {k:v.replace(kind=inspect.Parameter.KEYWORD_ONLY) for k,v in inspect.signature(to_f).parameters.items()                                    (14)

==================================================================================================================Start of my srcline exploration:


            sig.parameters => sig.parameters : OrderedDict([('c', <Parameter "c">), ('d', <Parameter "d: list = None">), ('kwargs', <Parameter "**kwargs">)])


                   dict(sig.parameters) => dict(sig.parameters) : {'c': <Parameter "c">, 'd': <Parameter "d: list = None">, 'kwargs': <Parameter "**kwargs">}
====================================================================================================================End of my srcline exploration:

<Signature (c, d: list = None, *, b: int = 1)>

Review srcode with all comments added so far======================================================================================================
def delegates(to:FunctionType=None, # Delegatee===========================================(0) # how to make delegates(to) to have to as FunctionType and default as None; 
              keep=False, # Keep `kwargs` in decorated function?==========================(1)       
              but:list=None): # Exclude these parameters from signature===================(2) # how to make delegates(to, but) to have 'but' as list and default as None; 
    "Decorator: replace `**kwargs` in signature with params from `to`"====================(3)       
    if but is None: but = []==============================================================(4)       
    def _f(f):============================================================================(5)       
        if to is None: to_f,from_f = f.__base__.__init__,f.__init__=======================(6) # how to write 2 ifs and elses in 2 lines; 
        else:          to_f,from_f = to.__init__ if isinstance(to,type) else to,f=========(7) # how to assign a,b together with if and else; 
        from_f = getattr(from_f,'__func__',from_f)========================================(8) # Is classmethod callable; does classmethod has __func__; can we do inspect.signature(clsmethod); how to use getattr(obj, attr, default); 
        to_f = getattr(to_f,'__func__',to_f)==============================================(9)       
        if hasattr(from_f,'__delwrap__'): return f========================================(10) # if B has __delwrap__, can we do delegates(A)(B) again?; hasattr(obj, '__delwrap__'); 
        sig = inspect.signature(from_f)===================================================(11) # how to get signature obj of B; what does a signature look like; what is the type; 
        sigd = dict(sig.parameters)=======================================================(12) # How to access parameters of a signature?; How to turn parameters into a dict?; 
        k = sigd.pop('kwargs')============================================================(13)      
        s2 = {k:v.replace(kind=inspect.Parameter.KEYWORD_ONLY) for k,v in inspect.signature(to_f).parameters.items() # How to access a signature's parameters as a dict?; How to replace the kind of a parameter with a different kind?; how to check whether a parameter has a default value?; How to check whether a string is in a dict and a list?; how dict.items() and dict.values() differ;  (14)
              if v.default != inspect.Parameter.empty and k not in sigd and k not in but}=(15)      
        anno = {k:v for k,v in getattr(to_f, "__annotations__", {}).items() if k not in sigd and k not in but} # How to get A's __annotations__?; How to access it as a dict?; How to select annotations of the right params with names?; How to put them into a dict?; How to do it all in a single line;  (16)
        sigd.update(s2)===================================================================(17) # How to add the selected params from A's signature to B's signature; How to add items into a dict;; 
        if keep: sigd['kwargs'] = k=======================================================(18) # How to add a new item into a dict;; 
        else: from_f.__delwrap__ = to_f===================================================(19) # How to create a new attr for a function or obj;; 
                                                                                                                                     part No.1 out of 2 parts

========================================================     Investigating delegates     =========================================================
===============================================================     on line 13     ===============================================================
     with example 
def low(a, b:int=1): pass
@delegates(low)
def mid(c, d:list=None, **kwargs): pass
pprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug
     

print selected srcline with expands below--------
        sig = inspect.signature(from_f)                                                                                                                 (11)
        sigd = dict(sig.parameters)                                                                                                                     (12)
        k = sigd.pop('kwargs')==========================================================================================================================(13)
How to remove an item from a dict?; How to get the removed item from a dict?; How to add the removed item back to the dict?; when writing expressions, as they share environment, so they may affect the following code
        s2 = {k:v.replace(kind=inspect.Parameter.KEYWORD_ONLY) for k,v in inspect.signature(to_f).parameters.items()                                    (14)
              if v.default != inspect.Parameter.empty and k not in sigd and k not in but}                                                               (15)

==================================================================================================================Start of my srcline exploration:


                                                   sigd => sigd : {'c': <Parameter "c">, 'd': <Parameter "d: list = None">, 'kwargs': <Parameter "**kwargs">}


                                                                                                                        k = sigd.pop('kwargs') => k: **kwargs


                                                                                     sigd => sigd : {'c': <Parameter "c">, 'd': <Parameter "d: list = None">}


                                                                                                               sigd['kwargs'] = k => sigd['kwargs']: **kwargs
====================================================================================================================End of my srcline exploration:

<Signature (c, d: list = None, *, b: int = 1)>

Review srcode with all comments added so far======================================================================================================
def delegates(to:FunctionType=None, # Delegatee===========================================(0) # how to make delegates(to) to have to as FunctionType and default as None; 
              keep=False, # Keep `kwargs` in decorated function?==========================(1)       
              but:list=None): # Exclude these parameters from signature===================(2) # how to make delegates(to, but) to have 'but' as list and default as None; 
    "Decorator: replace `**kwargs` in signature with params from `to`"====================(3)       
    if but is None: but = []==============================================================(4)       
    def _f(f):============================================================================(5)       
        if to is None: to_f,from_f = f.__base__.__init__,f.__init__=======================(6) # how to write 2 ifs and elses in 2 lines; 
        else:          to_f,from_f = to.__init__ if isinstance(to,type) else to,f=========(7) # how to assign a,b together with if and else; 
        from_f = getattr(from_f,'__func__',from_f)========================================(8) # Is classmethod callable; does classmethod has __func__; can we do inspect.signature(clsmethod); how to use getattr(obj, attr, default); 
        to_f = getattr(to_f,'__func__',to_f)==============================================(9)       
        if hasattr(from_f,'__delwrap__'): return f========================================(10) # if B has __delwrap__, can we do delegates(A)(B) again?; hasattr(obj, '__delwrap__'); 
        sig = inspect.signature(from_f)===================================================(11) # how to get signature obj of B; what does a signature look like; what is the type; 
        sigd = dict(sig.parameters)=======================================================(12) # How to access parameters of a signature?; How to turn parameters into a dict?; 
        k = sigd.pop('kwargs')============================================================(13) # How to remove an item from a dict?; How to get the removed item from a dict?; How to add the removed item back to the dict?; when writing expressions, as they share environment, so they may affect the following code; 
        s2 = {k:v.replace(kind=inspect.Parameter.KEYWORD_ONLY) for k,v in inspect.signature(to_f).parameters.items() # How to access a signature's parameters as a dict?; How to replace the kind of a parameter with a different kind?; how to check whether a parameter has a default value?; How to check whether a string is in a dict and a list?; how dict.items() and dict.values() differ;  (14)
              if v.default != inspect.Parameter.empty and k not in sigd and k not in but}=(15)      
        anno = {k:v for k,v in getattr(to_f, "__annotations__", {}).items() if k not in sigd and k not in but} # How to get A's __annotations__?; How to access it as a dict?; How to select annotations of the right params with names?; How to put them into a dict?; How to do it all in a single line;  (16)
        sigd.update(s2)===================================================================(17) # How to add the selected params from A's signature to B's signature; How to add items into a dict;; 
        if keep: sigd['kwargs'] = k=======================================================(18) # How to add a new item into a dict;; 
        else: from_f.__delwrap__ = to_f===================================================(19) # How to create a new attr for a function or obj;; 
                                                                                                                                     part No.1 out of 2 parts
fdb.print()
========================================================     Investigating delegates     =========================================================
===============================================================     on line 13     ===============================================================
     with example 
def low(a, b:int=1): pass
@delegates(low)
def mid(c, d:list=None, **kwargs): pass
pprint(inspect.signature(mid)) # pprint and inspect is loaded from fastdebug
     

def delegates(to:FunctionType=None, # Delegatee===========================================(0) # how to make delegates(to) to have to as FunctionType and default as None; 
              keep=False, # Keep `kwargs` in decorated function?==========================(1)       
              but:list=None): # Exclude these parameters from signature===================(2) # how to make delegates(to, but) to have 'but' as list and default as None; 
    "Decorator: replace `**kwargs` in signature with params from `to`"====================(3)       
    if but is None: but = []==============================================================(4)       
    def _f(f):============================================================================(5)       
        if to is None: to_f,from_f = f.__base__.__init__,f.__init__=======================(6) # how to write 2 ifs and elses in 2 lines; 
        else:          to_f,from_f = to.__init__ if isinstance(to,type) else to,f=========(7) # how to assign a,b together with if and else; 
        from_f = getattr(from_f,'__func__',from_f)========================================(8) # Is classmethod callable; does classmethod has __func__; can we do inspect.signature(clsmethod); how to use getattr(obj, attr, default); 
        to_f = getattr(to_f,'__func__',to_f)==============================================(9)       
        if hasattr(from_f,'__delwrap__'): return f========================================(10) # if B has __delwrap__, can we do delegates(A)(B) again?; hasattr(obj, '__delwrap__'); 
        sig = inspect.signature(from_f)===================================================(11) # how to get signature obj of B; what does a signature look like; what is the type; 
        sigd = dict(sig.parameters)=======================================================(12) # How to access parameters of a signature?; How to turn parameters into a dict?; 
        k = sigd.pop('kwargs')============================================================(13) # How to remove an item from a dict?; How to get the removed item from a dict?; How to add the removed item back to the dict?; when writing expressions, as they share environment, so they may affect the following code; 
        s2 = {k:v.replace(kind=inspect.Parameter.KEYWORD_ONLY) for k,v in inspect.signature(to_f).parameters.items() # How to access a signature's parameters as a dict?; How to replace the kind of a parameter with a different kind?; how to check whether a parameter has a default value?; How to check whether a string is in a dict and a list?; how dict.items() and dict.values() differ;  (14)
              if v.default != inspect.Parameter.empty and k not in sigd and k not in but}=(15)      
        anno = {k:v for k,v in getattr(to_f, "__annotations__", {}).items() if k not in sigd and k not in but} # How to get A's __annotations__?; How to access it as a dict?; How to select annotations of the right params with names?; How to put them into a dict?; How to do it all in a single line;  (16)
        sigd.update(s2)===================================================================(17) # How to add the selected params from A's signature to B's signature; How to add items into a dict;; 
        if keep: sigd['kwargs'] = k=======================================================(18) # How to add a new item into a dict;; 
        else: from_f.__delwrap__ = to_f===================================================(19) # How to create a new attr for a function or obj;; 
        from_f.__signature__ = sig.replace(parameters=sigd.values())======================(20) # How to update a signature with a new set of parameters;; 
        if hasattr(from_f, '__annotations__'): from_f.__annotations__.update(anno)========(21) # How to check whether a func has __annotations__; How add selected params' annotations from A to B's annotations;; 
        return f==========================================================================(22)      
    return _f=============================================================================(23)      
                                                                                                                                                        (24)

Snoop

# fdb.snoop(deco=True) # both examples above works for Fastdb