diff options
author | alandonovan <adonovan@google.com> | 2020-07-06 15:40:33 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-06 15:40:33 -0400 |
commit | 901fe11ed3086be213543b3731949583fef4144d (patch) | |
tree | f316fe6b51667c253d53dd3dff5fb3f0ee13e8e0 | |
parent | 50ca820fafb940caeda09b96864b9215f8b84c04 (diff) | |
download | starlark-go-901fe11ed3086be213543b3731949583fef4144d.tar.gz |
starlark: add examples of UnpackArgs (#289)
Fixes #111
-rw-r--r-- | starlark/unpack.go | 54 |
1 files changed, 50 insertions, 4 deletions
diff --git a/starlark/unpack.go b/starlark/unpack.go index 386bbc5..d8f9ec5 100644 --- a/starlark/unpack.go +++ b/starlark/unpack.go @@ -34,10 +34,54 @@ type Unpacker interface { // If the variable implements Value, UnpackArgs may call // its Type() method while constructing the error message. // -// Beware: an optional *List, *Dict, Callable, Iterable, or Value variable that is -// not assigned is not a valid Starlark Value, so the caller must -// explicitly handle such cases by interpreting nil as None or some -// computed default. +// Examples: +// +// var ( +// a Value +// b = MakeInt(42) +// c Value = starlark.None +// ) +// +// // 1. mixed parameters, like def f(a, b=42, c=None). +// err := UnpackArgs("f", args, kwargs, "a", &a, "b?", &b, "c?", &c) +// +// // 2. keyword parameters only, like def f(*, a, b, c=None). +// if len(args) > 0 { +// return fmt.Errorf("f: unexpected positional arguments") +// } +// err := UnpackArgs("f", args, kwargs, "a", &a, "b?", &b, "c?") +// +// // 3. positional parameters only, like def f(a, b=42, c=None, /) in Python 3.8. +// err := UnpackPositionalArgs("f", args, kwargs, 1, &a, &b, &c) +// +// More complex forms such as def f(a, b=42, *args, c, d=123, **kwargs) +// require additional logic, but their need in built-ins is exceedingly rare. +// +// In the examples above, the declaration of b with type Int causes UnpackArgs +// to require that b's argument value, if provided, is also an int. +// To allow arguments of any type, while retaining the default value of 42, +// declare b as a Value: +// +// var b Value = MakeInt(42) +// +// The zero value of a variable of type Value, such as 'a' in the +// examples above, is not a valid Starlark value, so if the parameter is +// optional, the caller must explicitly handle the default case by +// interpreting nil as None or some computed default. The same is true +// for the zero values of variables of type *List, *Dict, Callable, or +// Iterable. For example: +// +// // def myfunc(d=None, e=[], f={}) +// var ( +// d Value +// e *List +// f *Dict +// ) +// err := UnpackArgs("myfunc", args, kwargs, "d?", &d, "e?", &e, "f?", &f) +// if d == nil { d = None; } +// if e == nil { e = new(List); } +// if f == nil { f = new(Dict); } +// func UnpackArgs(fnname string, args Tuple, kwargs []Tuple, pairs ...interface{}) error { nparams := len(pairs) / 2 var defined intset @@ -107,6 +151,8 @@ kwloop: // UnpackPositionalArgs reports an error if the number of arguments is // less than min or greater than len(vars), if kwargs is nonempty, or if // any conversion fails. +// +// See UnpackArgs for general comments. func UnpackPositionalArgs(fnname string, args Tuple, kwargs []Tuple, min int, vars ...interface{}) error { if len(kwargs) > 0 { return fmt.Errorf("%s: unexpected keyword arguments", fnname) |