Skip to content

Sphinx raises warning about custom typehints_formatter #457

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

Open
jl-wynen opened this issue May 28, 2024 · 1 comment
Open

Sphinx raises warning about custom typehints_formatter #457

jl-wynen opened this issue May 28, 2024 · 1 comment

Comments

@jl-wynen
Copy link

Since Sphinx v7.3.0, there is a warning about config values that are not pickleable. When building with warning_is_error = True, this fails the build. See sphinx-doc/sphinx#12300 for context.

For sphinx-autodoc-typehints, this means that a custom typehints_formatter leads to a build failure.

To reproduce, simply use this conf.py:

project = 'custom_formatter'
extensions = [
    'sphinx.ext.autodoc',
    'sphinx_autodoc_typehints',
]
warning_is_error = True
show_warning_types = True

def formatter(annotation, config):
    return None

typehints_formatter = formatter

It results in this warning:

sphinx.errors.SphinxWarning: cannot cache unpickable configuration value: 'typehints_formatter' (because it contains a function, class, or module object) [config.cache]

Apart from triggering a warning that needs to be silenced, this also prevents caching. So it would be great to have a solution that avoids specifying a callable as typehints_formatter. One option would be using a fully qualified path and make sphinx-autodoc-typehints import a function from that path. E.g. typehints_formatter = 'mypackage.sphinxext.typehints_formatter'. See also this comment: sphinx-doc/sphinx#12300 (comment)

@bckohan
Copy link

bckohan commented Jan 17, 2025

I've had this same issue in sphinxcontrib/typer.

The only way to fix it is the method you suggest, where you load it from a string import path.

I use this function to convert the config value into a function object. If it is already a function object it returns that for backwards compatibility:

import typing as t
from importlib import import_module

def get_function(function: t.Union[str, t.Callable[..., t.Any]]):
    if callable(function):
        return function
    if isinstance(function, str):
        parts = function.split(".")
        return getattr(import_module(".".join(parts[0:-1])), parts[-1])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants