Comments (7)
Seems like an oversight, and I would (probably?) accept a PR fixing it. It should also support Tuple[...] | None
(as that's basically the same thing), and should error out if there is a custom parser registered for NoneType (unless a 1-element tuple type is given), as in that case the arity (number of items to read) is ill-defined.
from defopt.
and should error out if there is a custom parser registered for NoneType
Oh is this only for the optional tuple case? Or any optional container?
And do you mind providing an example of the ambiguity that a 1-element tuple avoids?
from defopt.
Say you have a parser for NoneType (def parse_none(s): return s if s == ":none:" else raise ValueError("not none")
) and a function with hint def main(*, opt: Optional[tuple[str, str]): ...
. Remember that this is equivalent to def main(*, opt: None | tuple[str, str])
(Optional is strictly equivalent to union-with-None, and defopt always special-cases None to go first in the union). Now, the problem is that the invocation $ myscript --opt <some-arg>
is valid if and only if <some-arg>
is :none:
, and the invocation $ myscript --opt <some-arg> <other-arg>
is valid if and only if <some-arg>
is not :none:
, i.e. nargs
for opt
is not well defined (and argparse has no way to represent such options (IIRC there's a bug on CPython's tracker to request support for that)). On the other hand, for 1-element tuples, there is no ambiguity that nargs == 1
.
Your point about other optional containers makes me believe that I have indeed missed that problematic interaction previously; Optional[list[str]]
behaves exactly like list[str]
. On the other hand, in for non-tuple containers, I think we can have a way out because they already have nargs = "*"
anyways and therefore we can just do add a case checking if a single arg was passed and, if so, try to pass it to the none-parser (if it exists). (For tuples, we can't rely on using nargs = "*"
, as we can have multiple positional tuple parameters.)
(PS: this discussion also applies to #116, of course.)
from defopt.
Ahh got it, yeah I'll work on that when I get the chance
from defopt.
So I was able to raise an error when an optional multiple item tuple with a custom none parser is provided, but I'm a bit confused on where to make the change such that the none parser is tried first in the list/one-item tuple case. For optional primitives, trying the none parser first is more straightforward because that can happen via the type set on the ArgumentParser argument. To do this with optional containers, would that need to happen in _bind_or_bind_known
somehow?
from defopt.
From a quick look, this is indeed not trivial to implement :-( and would probably require a bit of rearchitecting. Let's go for the simpler route of erroring out in all cases when a custom noneparser is present, we can always consider adding back support for the one-element case later.
from defopt.
Sure, sounds good. I imagine wanting to have an optional tuple potentially parsed as None via the command line (rather than just using a default value of None) is a pretty rare use case anyway.
from defopt.
Related Issues (20)
- feature request: better support for options that take multiple arguments and have a default HOT 2
- feature request: support "count" action HOT 2
- Documented strong compatibility guarantees HOT 2
- Add a registry class HOT 4
- When subclassing enum with data mixin, choices are not present on CLI HOT 8
- Consume command line arguments in 2 function calls HOT 10
- Support URLs in docstring
- Reject duplicate options for a single parameter rather than silently dropping one HOT 2
- Any way to indent within tool help text without runtime / linting error? HOT 1
- Add support for datetime.date and datetime.datetime parsers HOT 5
- Argument name suffixes as workaround for name collisions HOT 4
- PyInstaller, Nuitka compatibility? HOT 5
- pin setuptools_scm < 6.4 to support python3.6 HOT 2
- Consume command line arguments in 2 calls - help text has only one call's parameters HOT 17
- Using keyword only dataclass with `defopt.run` gives a docutils warning HOT 1
- py.typed file? HOT 3
- NotImplementedError: <class 'defopt._parse_docstring.<locals>.Visitor'> visiting unknown node type: definition_list HOT 3
- TypeError: can only join an iterable HOT 2
- Feature Request: Make Optional[bool] still act as a flag HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from defopt.