mpkocher/pydantic-cli

Problem witn --debug

arzamas500 opened this issue · 2 comments

Strangely, this one doesn't show title and description and ignores --debug option (works only with the short one, -d).

    debug: bool = Field(
        False,
        title="Debug",
        description="Debug-level output",
        extras={"cli": ("-d", "--debug")}
    )

Expected:

  -d DEBUG, --debug DEBUG
                                  Debug-level output

Actual result:

  --d                         Set debug to True 

Boolean opts have different semantics than non-bool flags.

https://github.com/mpkocher/pydantic-cli#defining-boolean-flags

The current design is trying to have parity for the case where you have a boolean flag that is required and the case where a boolean flag has a default.

Unfortunately this design choice of explicitly providing the +/- form of the flag doesn't let you set the 'short' option of each the +/- form. This probably should be improved and the issue of a custom description not being propagated to the help message needs to be fixed.

Here's an example of a few different boolean option use cases and the --help output.

#!/usr/bin/env python
from pydantic import BaseModel, Field
from pydantic_cli import run_and_exit


class Example(BaseModel):
    debug: bool = Field(
        False,
        title="Debug",
        description="Debug-level output",
        extras={"cli": ("--enable-debug", "--disable-debug")}
    )
    filtering: bool = Field(..., extras={"cli": ("--enable-filtering", "--no-filtering")})
    scoring: bool


def example(opt: Example) -> int:
    print(f"Mock running {opt}")
    return 0


if __name__ == '__main__':
    run_and_exit(Example, example)

Yields

usage: example.py [--enable-debug] (--enable-filtering | --no-filtering) (--enable-scoring | --disable-scoring) [--help]

optional arguments:
  --enable-debug      Set debug to True (--enable-debug)
  --enable-filtering  Set filtering to True (--enable-filtering)
  --no-filtering      Set filtering to False (--no-filtering)
  --enable-scoring    Set scoring to True (--enable-scoring)
  --disable-scoring   Set scoring to False (--disable-scoring)
  --help              Print Help and Exit

There's a change in >= 4.0.0 that address the common case of a boolean field with a default value. It's possible to now provide the negation of the default value with the (--short, --long) format.

There's an example:

https://github.com/mpkocher/pydantic-cli/blob/master/pydantic_cli/examples/simple_with_boolean_custom.py

beta_filter: bool = Field(
        False,
        description="Enable beta filter mode",
        cli=("-b", "--beta-filter"),
    )

However, this does create an inconsistency with cases where Field is given as Optional[bool] or a required bool. These both use the same key format of (--enable, --disable). Short options are not supported in these case because the tuple usage can start to become confusing/ambiguous and too nested.