ipython / ipython/traitlets

Discussion: optionally restoring argparse nargs/multiplicity support

未关闭
#690 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
主要语言
Python
星标
653
派生
217
平均合并
2 天 21 小时
30 天内合并 PR
2

描述

Hi, I realize this may be re-opening a can of worms, but I was looking for a way to re-support `--key v1 v2 v3` for `Container` traits in `argparse`-based CLI handling, originally added in #322 by @ankostis. That support was one of the main reasons I felt comfortable refactoring a codebase to use `traitlets`. While trying to upgrade to `traitlets==5.1`, I found out that `traitlets` was now silently discarding `v2 v3` due to https://github.com/ipython/traitlets/pull/582#issuecomment-671922717 (none of my applications use positional arguments).

I was able to patch this for my applications in a rather convoluted way by having them inherit a mixin to change the argparse loader, using #360:
```python
class FixNArgsMixin(HasTraits):
def _create_loader(self, ..):
class _DefaultOptionDict(loader._DefaultOptionDict):
def _add_kv_action(self, key):
self[key] = loader._KVAction(
# ..
nargs="+", # not ideal, but not sure what else can be done, unless we restrict ourselves to Application.classes, resolve these traits and look up trait.multiplicity
)
class KVArgParser(argparse.ArgumentParser):
# same as loader.KVArgParser, but with _DefaultOptionDict
class KVArgParseConfigLoader(loader.KVArgParseConfigLoader):
parser_class = KVArgParser
return KVArgParserConfigLoader(..)

class MyApp(FixNArgsMixin, Application):
foo = List(config=True).tag(multiplicity="+")
MyApp().initialize(["--MyApp.foo", "a", "b"])
```
This is pretty verbose and frail since it re-implements a significant amount of the `traitlets.config.loader` internals. One idea I was considering is to support an `allow_nargs=True` argument to `_KVArgParser()` which will set `nargs="+"` in `_DefaultOptionDict`, and that way the above method could be shortened to `return KVArgParserConfigLoader(.., allow_nargs=True)`.

Why I use `nargs="+"`:
1. Compatibility with existing script APIs
2. Principle of least surprise, its natural to python users that lists can be built from CLI via `nargs="+"`, and matches the `argparse` behavior of [consuming `nargs="+"` instead of positional arguments](https://stackoverflow.com/questions/36328769/argparse-nargs-is-eating-positional-argument)
3. Significantly easier to type/autocomplete out `--App.my_long_trait_name 1 2 3 4` vs `--App.my_long_trait_name 1 --App.my_long_trait_name 2 --App.my_long_trait_name 3 --App.my_long_trait_name 4`

Note: I understand that the `multiplicity` feature was buyer-beware since it was not officially released (and that `traitlets` is to an extent "semi-private"), and also the significant complexity in trying to handle `nargs` together with positional arguments, hence why I don't wish to request any changes in the current default behavior.

cc @minrk @Carreau, apologies in advance for wall of text

贡献指南

打开贡献指南

调研方向

Start by reading the argparse loader internals, especially _KVArgParser, _DefaultOptionDict, and _KVAction, along with the changes referenced from #322 and #360. Determine how optional nargs support should interact with positional arguments and trait multiplicity; the issue is ready only after that behavior and its tests are agreed.

由索引模型根据 Issue 内容生成。

评估

技术栈
python
领域
cli
Issue 类型
功能
难度
5/5
预计耗时
一周以上
活跃度
停滞
描述清晰度
基本清楚
新手友好度
30/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。