kalekundert / byoc

MIT License
0 stars 0 forks source link

Allow multiple keys to be associated with a single config #3

Closed kalekundert closed 3 years ago

kalekundert commented 3 years ago

It's surprisingly useful to be able to associate a parameter with multiple keys from the same config. For example, --flag and --not-flag might be two ways to set the same parameter. Some possible syntaxes:

appcli.param()\
      .key(DocoptConfig, '--flag',     cast=lambda x: x)\
      .key(DocoptConfig, '--not-flag', cast=lambda x: not x)
appcli.param(
      keys=[
          appcli.Key(DocoptConfig, '--flag',     cast=lambda x: x),
          appcli.Key(DocoptConfig, '--not-flag', cast=lambda x: not x),
      ],
)

This syntax might also be useful even when in cases that are supported by the existing syntax, since it makes it more clear which cast functions are associated with which keys.

Supporting this feature will mean using different data structures under the hood. Right now keys and cast functions are stored in the following data structures:

These parallel data structures make it impossible to associate multiple values with any one config object, and impossible to associate keys with cast functions. To solve these problems, I will need to use the following data structure:

kalekundert commented 3 years ago

The problem with the chained method syntax is that it makes it hard/impossible to ensure that the arguments to param() make sense. What if keys are specified to param() and param.key() is called? How are those keys merged? Or what if no keys are specified to param()? Does the default apply or not? It also might not look as clean if param() has lots of arguments.

I think it'd be better to go with the argument-based syntax.

kalekundert commented 3 years ago

Fixed by 556dfa4