@@ -471,10 +471,11 @@ def keyword(
471471 name : str , keyword : str = None , accessor : Accessor = None , jsonp = None
472472) -> _Modifier :
473473 """
474- Annotate a :term:`needs ` that (optionally) maps `inputs` name --> *keyword* argument name .
474+ Annotate a :term:`dependency ` that maps to a different name in the underlying function .
475475
476- The value of a *keyword* dependency is passed in as *keyword argument*
477- to the underlying function.
476+ - The value of a *keyword* `needs` dependency is passed in as *keyword argument*
477+ to the underlying function.
478+ - For *keyword* to work in `provides`, the operation must be a :term:`returns dictionary`.
478479
479480 :param keyword:
480481 The argument-name corresponding to this named-input.
@@ -507,30 +508,50 @@ def keyword(
507508
508509 **Example:**
509510
510- In case the name of the function arguments is different from the name in the
511- `inputs ` (or just because the name in the `inputs` is not a valid argument-name),
511+ In case the name of a function input argument is different from the name in the
512+ :term:`graph ` (or just because the name in the `inputs` is not a valid argument-name),
512513 you may *map* it with the 2nd argument of :func:`.keyword`:
513514
514515 >>> from graphtik import operation, compose, keyword
515516
516- >>> @operation(needs=['a', keyword("name-in-inputs", "b ")], provides="sum ")
517- ... def myadd(a, *, b):
518- ... return a + b
519- >>> myadd
520- FnOp(name='myadd ',
521- needs=['a', ' name-in-inputs'(>'b ')],
522- provides=['sum '],
523- fn='myadd ')
517+ >>> @operation(needs=[keyword("name-in-inputs", "fn_name ")], provides="result ")
518+ ... def foo( *, fn_name): # it works also with non-positional args
519+ ... return fn_name
520+ >>> foo
521+ FnOp(name='foo ',
522+ needs=['name-in-inputs'(>'fn_name ')],
523+ provides=['result '],
524+ fn='foo ')
524525
525- >>> graph = compose('mygraph ', myadd )
526- >>> graph
527- Pipeline('mygraph ', needs=['a', ' name-in-inputs'], provides=['sum '], x1 ops: myadd )
526+ >>> pipe = compose('map a need ', foo )
527+ >>> pipe
528+ Pipeline('map a need ', needs=['name-in-inputs'], provides=['result '], x1 ops: foo )
528529
529- >>> sol = graph .compute({"a": 5, " name-in-inputs": 4})['sum']
530- >>> sol
531- 9
530+ >>> sol = pipe .compute({"name-in-inputs": 4})
531+ >>> sol['result']
532+ 4
532533
533534 .. graphtik::
535+
536+ You can do the same thing to the results of a :term:`returns dictionary` operation:
537+
538+ >>> op = operation(lambda: {"fn key": 1},
539+ ... name="renaming `provides` with a `keyword`",
540+ ... provides=keyword("graph key", "fn key"),
541+ ... returns_dict=True)
542+ >>> op
543+ FnOp(name='renaming `provides` with a `keyword`',
544+ provides=['graph key'(>'fn key')],
545+ fn{}='<lambda>')
546+
547+ .. graphtik::
548+
549+ .. hint::
550+ Mapping `provides` names wouldn't make sense for regular operations, since
551+ these are defined arbitrarily at the operation level.
552+ OTOH, the result names of :term:`returns dictionary` operation are decided
553+ by the underlying function, which may lie beyond the control of the user
554+ (e.g. from a 3rd-party object).
534555 """
535556 # Must pass a truthy `keyword` bc cstor cannot not know its keyword.
536557 return _modifier (name , keyword = keyword or name , accessor = accessor , jsonp = jsonp )
0 commit comments