Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warning: Inline literal start-string without end-string in Numpy style Parameters section #8088

Closed
MatthieuDartiailh opened this issue Aug 9, 2020 · 11 comments
Labels
Milestone

Comments

@MatthieuDartiailh
Copy link

Describe the bug
The following docstring generates a warning on the line of the timeout parameter. Removing the quote around default cause the warning to go away.

def lock(
        self,
        timeout: Union[float, Literal["default"]] = "default",
        requested_key: Optional[str] = None,
    ) -> str:
        """Establish a shared lock to the resource.

        Parameters
        ----------
        timeout : Union[float, Literal["default"]], optional
            Absolute time period (in milliseconds) that a resource waits to get
            unlocked by the locking session before returning an error.
            Defaults to "default" which means use self.timeout.
        requested_key : Optional[str], optional
            Access key used by another session with which you want your session
            to share a lock or None to generate a new shared access key.

        Returns
        -------
        str
            A new shared access key if requested_key is None, otherwise, same
            value as the requested_key

        """

To Reproduce
Steps to reproduce the behavior:

$ git clone https://github.com/pyvisa/pyvisa
$ git checkout pytest
$ cd pyvisa
$ pip install -e .
$ cd docs
$ sphinx-build source build -W -b html;

Expected behavior
I do not expect to see a warning there and was not seeing any before 3.2

Your project
The project is build under the Documentation build action. pyvisa/pyvisa#531

Environment info

  • OS: Mac Os and Linux
  • Python version: 3.8.2 and 3.8.5
  • Sphinx version: 3.2.0
  • Sphinx extensions: "sphinx.ext.autodoc", "sphinx.ext.doctest","sphinx.ext.intersphinx", "sphinx.ext.coverage", "sphinx.ext.viewcode", "sphinx.ext.mathjax", "sphinx.ext.napoleon"
@tk0miya
Copy link
Member

tk0miya commented Aug 9, 2020

@keewis Could you check this please? I think this is related to convert_numpy_type_spec.

@keewis
Copy link
Contributor

keewis commented Aug 9, 2020

napoleon converts the docstring to

Establish a shared lock to the resource.

:Parameters: * **timeout** (:class:`Union[float`, :class:`Literal[```"default"``:class:`]]`, *optional*) -- Absolute time period (in milliseconds) that a resource waits to get
               unlocked by the locking session before returning an error.
               Defaults to "default" which means use self.timeout.
             * **requested_key** (:class:`Optional[str]`, *optional*) -- Access key used by another session with which you want your session
               to share a lock or None to generate a new shared access key.

:returns: *str* -- A new shared access key if requested_key is None, otherwise, same
          value as the requested_key

which I guess happens because I never considered typehints when I wrote the preprocessor. To be clear, type hints are not part of the format guide, but then again it also doesn't say they can't be used.

If we allow type hints, we probably want to link those types and thus should extend the preprocessor. Since that would be a new feature, I guess we shouldn't include that in a bugfix release.

For now, I suggest we fix this by introducing a setting that allows opting out of the type preprocessor (could also be opt-in).

@StrikerRUS
Copy link

Faced the same issue in our builds yesterday.

Warning, treated as error:
/home/travis/build/microsoft/LightGBM/docs/../python-package/lightgbm/basic.py:docstring of lightgbm.Booster.dump_model:12:Inline literal start-string without end-string.

conf.py: https://github.com/microsoft/LightGBM/blob/master/docs/conf.py
Logs: https://travis-ci.org/github/microsoft/LightGBM/jobs/716228303

One of the "problem" docstrings: https://github.com/microsoft/LightGBM/blob/ee8ec182010c570c6371a5fc68ab9f4da9c6dc74/python-package/lightgbm/basic.py#L2762-L2782

@keewis
Copy link
Contributor

keewis commented Aug 9, 2020

that's a separate issue: you're using a unsupported notation for default. Supported are currently default <obj> and default: <obj>, while you are using optional (default=<obj>). To be fair, this is currently not standardized, see numpy/numpydoc#289.

Edit: in particular, the type preprocessor chokes on something like string, optional (default="split"), which becomes:

:class:`string`, :class:`optional (default=```"split"``:class:`)`

so it splits the default notation into optional (default=, "split", and )

However, the temporary fix is the same: deactivate the type preprocessor using a new setting. For a long term fix we'd first need to update the numpydoc format guide.

@tk0miya, should I send in a PR that adds that setting?

@tk0miya
Copy link
Member

tk0miya commented Aug 10, 2020

@keewis Yes, please.

If we allow type hints, we probably want to link those types and thus should extend the preprocessor. Since that would be a new feature, I guess we shouldn't include that in a bugfix release.

I think the new option is needed to keep compatibility for some users. So it must be released as a bugfix release. So could you send a PR to 3.2.x branch? I'm still debating which is better to enable or disable the numpy type feature by default. But it should be controlled via user settings.

@MatthieuDartiailh
Copy link
Author

Even if type hints are not clearly supported, the numpy docs format (https://numpydoc.readthedocs.io/en/latest/format.html) mention this as being valid entry for a parameter order : {'C', 'F', 'A'}. Correct me if I am missing something but the error arises from the presence of " and is not related to [] in type hints. As a consequence I assume this example would break in the same way (got no time to test though).

@keewis
Copy link
Contributor

keewis commented Aug 10, 2020

no, I definitely made sure value sets and strings are supported:

def test_convert_numpy_type_spec(self):
translations = {
"DataFrame": "pandas.DataFrame",
}
specs = (
"",
"optional",
"str, optional",
"int or float or None, default: None",
"int, default None",
'{"F", "C", "N"}',
"{'F', 'C', 'N'}, default: 'N'",
"{'F', 'C', 'N'}, default 'N'",
"DataFrame, optional",
)
converted = (
"",
"*optional*",
":class:`str`, *optional*",
":class:`int` or :class:`float` or :obj:`None`, *default*: :obj:`None`",
":class:`int`, *default* :obj:`None`",
'``{"F", "C", "N"}``',
"``{'F', 'C', 'N'}``, *default*: ``'N'``",
"``{'F', 'C', 'N'}``, *default* ``'N'``",
":class:`pandas.DataFrame`, *optional*",
)
for spec, expected in zip(specs, converted):
actual = _convert_numpy_type_spec(spec, translations=translations)
self.assertEqual(expected, actual)

Though of course I can't be sure there is no edge case that breaks the conversion code (I didn't use a fuzzer to check that).

@tk0miya, I just realized we could probably treat [ and ] as normal delimiters (like or) and just make sure the number of opening and closing brackets match (maybe also that the token after ] must be another delimiter).

@MatthieuDartiailh
Copy link
Author

Thanks for clarifying the issue I assumed that [ was not causing an issue since I had to remove " to fix the issue. I think that treating [ as a normal delimiter would go in the right direction. It would provide the benefits of the new pre-processor while avoiding the regression for type hints.

Silly question but moving forward would it make sense to be able to "complete" the docstring when building the documentation from the type annotations to avoid duplicating everything ? Is this planned ?

@tk0miya
Copy link
Member

tk0miya commented Aug 13, 2020

I merged #8095 now. So this warning will be fixed on next release.

@tk0miya tk0miya closed this as completed Aug 13, 2020
@tk0miya
Copy link
Member

tk0miya commented Aug 13, 2020

@MatthieuDartiailh

Silly question but moving forward would it make sense to be able to "complete" the docstring when building the documentation from the type annotations to avoid duplicating everything ? Is this planned ?

What do you mean "complete"?

IMO, type hints (type annotations) is a good friend of developers. They help to our development. Additionally, autodoc detects them and adds them to the document automatically. So I prefer to write them as type annotations instead of docstrings.

@tk0miya tk0miya added this to the 3.2.1 milestone Aug 13, 2020
@MatthieuDartiailh
Copy link
Author

My idea was to stop adding the types in the docstrings and get them directly from the hints to avoid duplication. Somebody pointed me to that project which seems like it can do it: https://github.com/agronholm/sphinx-autodoc-typehints. However the same person pointed out the fact that some tools (IPython) display the source docstring which would then be less readable. I guess what I am looking for is a good linter/formatter to avoid discrepancies between type annotations and docstrings.

Anyway thanks for your help.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 20, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

4 participants