anntzer / defopt

Effortless argument parser
https://pypi.org/project/defopt/
MIT License
214 stars 11 forks source link

Using keyword only dataclass with `defopt.run` gives a docutils warning #120

Closed lmmx closed 2 years ago

lmmx commented 2 years ago

When using the new Python 3.10 KW_ONLY sentinel value in a dataclass, wrapping it with defopt.run, the CLI gives a warning (originating from docutils):

<string>:1: (WARNING/2) Inline emphasis start-string without end-string.

A small reproducible example can be found in this commit:

The code can be reduced to

import defopt

from .new_home import Rehome

__all__ = ["cli"]

def cli():
    home = defopt.run(Rehome)
    if home.debug:
        breakpoint()

and the module new_home.py

from dataclasses import KW_ONLY, dataclass, field
from pathlib import Path

__all__ = ["Rehome"]

@dataclass
class Rehome:
    path: Path
    _: KW_ONLY
    colocate: list[str] = field(default_factory=list)
    debug: bool = False

    @property
    def name_groups(self) -> list[list[str]]:
        """
        Names which should be kept together
        """
        return [c.split() for c in self.colocate]

I tried to filter it with the warnings module but it didn't work, which I think means it didn't come from there.

There are 57 hits for this in the docutils package, I'm not sure where exactly it's coming from

Without this I don't have as much control over the creation of CLIs from dataclasses, which is a shame as it'd be very convenient.

More info on the feature at StackOverflow and the official Python docs

Update: I was trying to use this to control the generation of positional vs. optional CLI flags, but I've now discovered I can do this by passing cli_options="has_default" to defopt.run so this is more of a courtesy note, and please feel free to close if not useful. I suspect the source is when the help message is generated, and the * for the keyword only signature is interpreted as the italics start symbol

anntzer commented 2 years ago

This is because dataclasses default to autogenerating a docstring which is the signature of the constructor, and which as a consequence is not valid rst (as it contains the asterisk to mark kwonly args). You can override that invalid docstring by putting in your own.