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

TypeError: '<' not supported between instances of 'NoneType' and 'NoneType' #137

Open
morcef opened this issue Aug 8, 2022 · 25 comments
Open
Assignees
Labels
bug Something isn't working enhancement New feature or request help wanted Extra attention is needed

Comments

@morcef
Copy link

morcef commented Aug 8, 2022

Hi,

I have encountered a simmilar issue as discussed in #78.
My Pydantic models have fields with type of other Pydantic models, and when using autodoc_pydantic_model_summary_list_order = 'bysource' I still seem to get the same error.

Is there any other way to find the exact model that fails, except for the elimination method?

I am not sure what more should be provided to find my edge case, but here is the Sphinx traceback:

# Sphinx version: 5.1.1
# Python version: 3.6.8 (CPython)
# Docutils version: 0.17.1 release
# Jinja2 version: 3.0.3
# Last messages:
#   reading sources... [ 56%] index
#   
#   reading sources... [ 62%] reference/api
#   
# Loaded extensions:
#   sphinx.ext.mathjax (5.1.1) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\ext\mathjax.py
#   sphinxcontrib.applehelp (1.0.2) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\applehelp\__init__.py
#   sphinxcontrib.devhelp (1.0.2) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\devhelp\__init__.py
#   sphinxcontrib.htmlhelp (2.0.0) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\htmlhelp\__init__.py
#   sphinxcontrib.serializinghtml (1.1.5) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\serializinghtml\__init__.py
#   sphinxcontrib.qthelp (1.0.3) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\qthelp\__init__.py
#   alabaster (0.7.12) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\alabaster\__init__.py
#   sphinx.ext.autodoc.preserve_defaults (1.0) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\ext\autodoc\preserve_defaults.py
#   sphinx.ext.autodoc.type_comment (5.1.1) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\ext\autodoc\type_comment.py
#   sphinx.ext.autodoc (5.1.1) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\ext\autodoc\__init__.py
#   sphinx.ext.intersphinx (5.1.1) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\ext\intersphinx.py
#   sphinx_autodoc_typehints (unknown version) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx_autodoc_typehints.py
#   sphinx_click (unknown version) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx_click\__init__.py
#   sphinx_rtd_dark_mode (1.2.4) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx_rtd_dark_mode\__init__.py
#   sphinxcontrib.autodoc_pydantic (1.7.2) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\autodoc_pydantic\__init__.py
#   sphinx_rtd_theme (unknown version) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx_rtd_theme\__init__.py
Traceback (most recent call last):
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\cmd\build.py", line 277, in build_main
    app.build(args.force_all, filenames)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\application.py", line 349, in build
    self.builder.build_update()
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\builders\__init__.py", line 303, in build_update
    len(to_build))
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\builders\__init__.py", line 317, in build
    updated_docnames = set(self.read())
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\builders\__init__.py", line 424, in read
    self._read_serial(docnames)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\builders\__init__.py", line 445, in _read_serial
    self.read_doc(docname)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\builders\__init__.py", line 498, in read_doc
    publisher.publish()
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\core.py", line 218, in publish
    self.settings)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\io.py", line 104, in read
    self.parse()
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\readers\__init__.py", line 78, in parse
    self.parser.parse(self.input, document)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\parsers.py", line 78, in parse
    self.statemachine.run(inputlines, document, inliner=self.inliner)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 171, in run
    input_source=document['source'])
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\statemachine.py", line 240, in run
    context, state, transitions)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\statemachine.py", line 451, in check_line
    return method(match, context, next_state)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 3008, in text
    self.section(title.lstrip(), source, style, lineno + 1, messages)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 327, in section
    self.new_subsection(title, lineno, messages)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 395, in new_subsection
    node=section_node, match_titles=True)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 282, in nested_parse
    node=node, match_titles=match_titles)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\statemachine.py", line 240, in run
    context, state, transitions)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\statemachine.py", line 451, in check_line
    return method(match, context, next_state)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 3008, in text
    self.section(title.lstrip(), source, style, lineno + 1, messages)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 327, in section
    self.new_subsection(title, lineno, messages)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 395, in new_subsection
    node=section_node, match_titles=True)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 282, in nested_parse
    node=node, match_titles=match_titles)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\statemachine.py", line 240, in run
    context, state, transitions)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\statemachine.py", line 451, in check_line
    return method(match, context, next_state)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 2769, in underline
    self.section(title, source, style, lineno - 1, messages)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 327, in section
    self.new_subsection(title, lineno, messages)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 395, in new_subsection
    node=section_node, match_titles=True)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 282, in nested_parse
    node=node, match_titles=match_titles)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\statemachine.py", line 240, in run
    context, state, transitions)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\statemachine.py", line 451, in check_line
    return method(match, context, next_state)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 2769, in underline
    self.section(title, source, style, lineno - 1, messages)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 327, in section
    self.new_subsection(title, lineno, messages)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 395, in new_subsection
    node=section_node, match_titles=True)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 282, in nested_parse
    node=node, match_titles=match_titles)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\statemachine.py", line 240, in run
    context, state, transitions)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\statemachine.py", line 451, in check_line
    return method(match, context, next_state)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 2342, in explicit_markup
    nodelist, blank_finish = self.explicit_construct(match)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 2354, in explicit_construct
    return method(self, expmatch)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 2097, in directive
    directive_class, match, type_name, option_presets)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 2146, in run_directive
    result = directive_instance.run()
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\ext\autodoc\directive.py", line 148, in run
    documenter.generate(more_content=self.content)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 954, in generate
    self.document_members(all_members)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 832, in document_members
    check_module=members_check_module and not isattr)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 1790, in generate
    all_members=all_members)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 951, in generate
    self.add_content(more_content)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\autodoc_pydantic\directives\autodocumenters.py", line 221, in add_content
    self.add_validators_summary()
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\autodoc_pydantic\directives\autodocumenters.py", line 344, in add_validators_summary
    sorted_references = self._get_validator_summary_references()
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\autodoc_pydantic\directives\autodocumenters.py", line 316, in _get_validator_summary_references
    sort_func = self._get_reference_sort_func()
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\autodoc_pydantic\directives\autodocumenters.py", line 295, in _get_reference_sort_func
    idx_fields = self._get_idx_mappings(all_fields)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\autodoc_pydantic\directives\autodocumenters.py", line 280, in _get_idx_mappings
    sorted_members = self._sort_summary_list(members)
  File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\autodoc_pydantic\directives\autodocumenters.py", line 405, in _sort_summary_list
    return sorted(names, key=sort_func)
TypeError: '<' not supported between instances of 'NoneType' and 'NoneType'
@mansenfranzen
Copy link
Owner

Sorry for letting you wait for so long. I have been busy otherwise. And thanks for opening the issue anyway.

The issue that you've been describing has bothered me for some time, too. It would be great to easily identify the actual model that causes autodoc_pydantic to fail. I will put it on the roadmap for the 1.9.0 release.

@mansenfranzen mansenfranzen self-assigned this Oct 12, 2022
@mansenfranzen mansenfranzen added bug Something isn't working enhancement New feature or request labels Oct 12, 2022
@mansenfranzen mansenfranzen added this to the v.1.9.0 milestone Oct 12, 2022
@j-carson
Copy link
Contributor

I am hitting this bug in _sort_summary_list, except that it is trying to compare int and None.
Would you be open to a temporary workaround pull-request so that the tool doesn't crash?
Documentation with the fields in a different sort order than intended is better than documentation that doesn't build at all.

Two workaround implementations I thought of:

option 1

At this point:

 tag_order = self.analyzer.tagorder.get(name_with_class) 

if tag_order is None, return a dummy value (-9999 to put these near the top or 9999 to put them near the end)

option 2

At this point

return sorted(names, key=sort_func)  

Put the sort in a try-block. If the sort throws an exception, just pass the input "names" back instead of a sorted list

@mansenfranzen mansenfranzen removed this from the v.1.9.0 milestone Jul 23, 2023
@Cielquan
Copy link

Cielquan commented Sep 9, 2023

I am running into the same issue. For me the reason seems to be inheritance.

I have a model RstcheckConfigFile (source) which inherits from pydantic.BaseModel and has some fields and custom validators. Then I have a second Model RstcheckConfig (source) which inherits from RstcheckConfigFile and only adds some more fields.

The aforementioned sort function then gets the name of a validator function from the first model while documentiong the second model and constructs the full name with the name of the second model. This function does not exist in code as it only exists through inheritance. Therefore it cannot be found in self.analyzer.tagorder and the error occurs.

EDIT: Inheritance seems to be another issue altogether I guess, because after I switched from "bysource" to "alphabetical" I get these errors for the code mentioned above:

/home/krys/Projects/.contributions/rstcheck-core/src/rstcheck_core/config.py:docstring of rstcheck_core.config.RstcheckConfig:1: WARNING: py:obj reference target not found: rstcheck_core.config.RstcheckConfig.ignore_messages
/home/krys/Projects/.contributions/rstcheck-core/src/rstcheck_core/config.py:docstring of rstcheck_core.config.RstcheckConfig:1: WARNING: py:obj reference target not found: rstcheck_core.config.RstcheckConfig.ignore_directives
/home/krys/Projects/.contributions/rstcheck-core/src/rstcheck_core/config.py:docstring of rstcheck_core.config.RstcheckConfig:1: WARNING: py:obj reference target not found: rstcheck_core.config.RstcheckConfig.ignore_languages
/home/krys/Projects/.contributions/rstcheck-core/src/rstcheck_core/config.py:docstring of rstcheck_core.config.RstcheckConfig:1: WARNING: py:obj reference target not found: rstcheck_core.config.RstcheckConfig.ignore_roles
/home/krys/Projects/.contributions/rstcheck-core/src/rstcheck_core/config.py:docstring of rstcheck_core.config.RstcheckConfig:1: WARNING: py:obj reference target not found: rstcheck_core.config.RstcheckConfig.ignore_substitutions
/home/krys/Projects/.contributions/rstcheck-core/src/rstcheck_core/config.py:docstring of rstcheck_core.config.RstcheckConfig:1: WARNING: py:obj reference target not found: rstcheck_core.config.RstcheckConfig.report_level

I only have these flags set:

autodoc_pydantic_model_erdantic_figure = False
autodoc_pydantic_model_show_json = False

EDIT2: I am using the lazy way with automodule.

@mansenfranzen
Copy link
Owner

Thanks @morcef @Cielquan for providing more detail! @j-carson started a PR via #190. Currently, we are lacking a minimal reproducible example that covers the incorrect behaviour/s. This will be required in the test suite. Otherwise, a reliable fix is going to be difficult. Any additional input is highly appreciated!

@mansenfranzen mansenfranzen added the help wanted Extra attention is needed label Dec 27, 2023
@j-carson
Copy link
Contributor

j-carson commented Jan 1, 2024

@morcef @Cielquan The PR #190 is getting into better shape now -- if you can test it with your docs that are breaking let me know!

@Cielquan
Copy link

Cielquan commented Mar 3, 2024

  • I took the current state of main in rstcheck-core
  • I installed the PR into my venv pip install git+https://github.com/j-carson/autodoc_pydantic.git@issue_137
  • I added the aformentioned config to sphinx's conf.py file
extensions.append("sphinxcontrib.autodoc_pydantic")
autodoc_pydantic_model_erdantic_figure = False
autodoc_pydantic_model_show_json = False
  • I ran tox -e docs and got this output:
$ tox -e docs
.pkg: _optional_hooks> python /home/user/.local/pipx/venvs/tox/lib/python3.8/site-packages/pyproject_api/_backend.py True setuptools.build_meta
.pkg: get_requires_for_build_sdist> python /home/user/.local/pipx/venvs/tox/lib/python3.8/site-packages/pyproject_api/_backend.py True setuptools.build_meta
.pkg: build_sdist> python /home/user/.local/pipx/venvs/tox/lib/python3.8/site-packages/pyproject_api/_backend.py True setuptools.build_meta
docs: install_package> python -I -m pip install --force-reinstall --no-deps /home/user/Projects/.contributions/rstcheck-core/.tox/.tmp/package/355/rstcheck-core-1.2.1.dev35+g9d7a9b8c73b0.d20240303.tar.gz
docs: commands[0]> sphinx-build --color -b html -aE docs/source docs/build/html
Running Sphinx v7.2.6
/home/user/Projects/.contributions/rstcheck-core/.tox/docs/lib/python3.11/site-packages/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py:21: RemovedInSphinx80Warning: The alias 'sphinx.util.typing.stringify' is deprecated, use 'sphinx.util.typing.stringify_annotation' instead. Check CHANGES for Sphinx API modifications.
  from sphinx.util.typing import get_type_hints, stringify
Initializing Spelling Checker 8.0.0
loading intersphinx inventory from https://docs.python.org/3/objects.inv...
loading intersphinx inventory from objects.pattern.inv...
loading intersphinx inventory from objects.pydantic.inv...
loading intersphinx inventory from objects.sphinx.inv...
Creating file /home/user/Projects/.contributions/rstcheck-core/docs/source/autoapidoc/rstcheck_core.rst.
building [mo]: all of 0 po files
writing output... 
building [html]: all source files
updating environment: [new config] 16 added, 0 changed, 0 removed
/home/user/Projects/.contributions/rstcheck-core/.tox/docs/lib/python3.11/site-packages/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py:137: RemovedInSphinx80Warning: The tuple interface of ObjectMember is deprecated. Use (obj.__name__, obj.object) instead.
  return {x[0] for x in self._documenter.get_object_members(True)[1]}
reading sources... [100%] workflows/releases
looking for now-outdated files... none found
pickling environment... done
checking consistency... done
preparing documents... done
copying assets... copying static files... done
copying extra files... done
done
writing output... [100%] workflows/releases
generating indices... genindex py-modindex done
highlighting module code... [100%] rstcheck_core.types
writing additional pages... search done
dumping search index in English (code: en)... done
dumping object inventory... done

====================== slowest reading durations =======================
0.572 autoapidoc/rstcheck_core
0.043 installation
0.038 _badges
0.022 changelog
0.021 usage/config
build succeeded.

The HTML pages are in docs/build/html.
docs: commands[1]> python -c 'from pathlib import Path; index_file = Path(r"/home/user/Projects/.contributions/rstcheck-core")/"docs/build/html/index.html"; print(f"DOCUMENTATION AVAILABLE UNDER: {index_file.as_uri()}")'
DOCUMENTATION AVAILABLE UNDER: file:///home/user/Projects/.contributions/rstcheck-core/docs/build/html/index.html
.pkg: _exit> python /home/user/.local/pipx/venvs/tox/lib/python3.8/site-packages/pyproject_api/_backend.py True setuptools.build_meta
  docs: OK (4.07=setup[2.24]+cmd[1.81,0.02] seconds)
  congratulations :) (4.11 seconds)

So it build the docs.

But there are two deprecation warnings pointing to autodoc_pydantic:

`/home/user/Projects/.contributions/rstcheck-core/.tox/docs/lib/python3.11/site-packages/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py:21: RemovedInSphinx80Warning: The alias 'sphinx.util.typing.stringify' is deprecated, use 'sphinx.util.typing.stringify_annotation' instead. Check CHANGES for Sphinx API modifications.
  from sphinx.util.typing import get_type_hints, stringify`

`/home/user/Projects/.contributions/rstcheck-core/.tox/docs/lib/python3.11/site-packages/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py:137: RemovedInSphinx80Warning: The tuple interface of ObjectMember is deprecated. Use (obj.__name__, obj.object) instead.
  return {x[0] for x in self._documenter.get_object_members(True)[1]}`

PS: I added a branch with the above changes: https://github.com/rstcheck/rstcheck-core/tree/autodoc-pydantic-testing

EDIT: update git link
EDIT2: fix typo

@j-carson
Copy link
Contributor

j-carson commented Mar 3, 2024

Hey @Cielquan these warnings look like your tox environment is not picking up the correct autodoc_pydantic as I did fix first warning and the second one is merged but just not on the pypi release yet:

stringify fix is here https://github.com/j-carson/autodoc_pydantic/blob/f55e3207da9d228e0a3675ff2f6c91b214b0b7dd/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py#L23

using .__name__ is here: https://github.com/j-carson/autodoc_pydantic/blob/f55e3207da9d228e0a3675ff2f6c91b214b0b7dd/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py#L143

Remember that you can't just put autodoc_pydantic in your local virtualenv and call it good because tox creates it's own virtualenvs (in .tox/docs in this case, but it will be in .tox/whatever_tox_env_name_is) and can be picking up the wrong version of autodoc_pydantic if you are not careful.

@Cielquan
Copy link

Cielquan commented Mar 4, 2024

Oh yeah. My bad. Did not think this through. Will test again in the coming days when I got time.

@mansenfranzen
Copy link
Owner

@all-contributors please add @Cielquan for bug

Copy link
Contributor

@mansenfranzen

I've put up a pull request to add @Cielquan! 🎉

@mansenfranzen
Copy link
Owner

@all-contributors please add @morcef for bug

Copy link
Contributor

@mansenfranzen

I've put up a pull request to add @morcef! 🎉

@mansenfranzen
Copy link
Owner

Before merging the related PR, it would be great if you could test the changed behavior. To do so, please install the current dev release in your doc-building-environment via pip install git+https://github.com/mansenfranzen/[email protected] and rebuild your docs.

Please feel free to reopen if any problem remains. I will release the new version upcoming Monday.

@Cielquan
Copy link

I can confirm the issue is gone.

@juhlinm
Copy link

juhlinm commented Apr 2, 2024

I'm still seeing the issue. Using autodoc_pydantic 2.1.0. I'm not sure if there might be some other package that is causing the issue.

Running Sphinx v7.2.6
making output directory... done
myst v2.0.0: MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions=set(),
 disable_syntax=[], all_links_external=False, url_schemes=('http', 'https', 'mailto', 'ftp'),
 ref_domains=None, fence_as_directive=set(), number_code_blocks=[], title_to_header=False,
 heading_anchors=0, heading_slug_func=None, html_meta={}, footnote_transition=True,
 words_per_minute=200, substitutions={}, linkify_fuzzy_links=True, dmath_allow_labels=True,
 dmath_allow_space=True, dmath_allow_digits=True, dmath_double_inline=False, update_mathjax=True,
 mathjax_classes='tex2jax_process|mathjax_process|math|output_area', enable_checkboxes=False,
 suppress_warnings=[], highlight_code_blocks=True)
building [mo]: targets for 0 po files that are out of date
writing output... 
building [html]: targets for 5 source files that are out of date
updating environment: [new config] 5 added, 0 changed, 0 removed

Exception occurred:  
File "/usr/local/lib/python3.10/site-packages/sphinxcontrib/autodoc_pydantic/directives/
autodocumenters.py", line 594, in _sort_summary_list    
    return sorted(names, key=sort_func)
TypeError: '<' not supported between instances of 'NoneType' and 'NoneType'

@j-carson
Copy link
Contributor

j-carson commented Apr 2, 2024

Do you have a small test case?

@juhlinm When you have a test case, maybe open a new ticket since this one is closed

@mansenfranzen mansenfranzen reopened this Apr 5, 2024
@mansenfranzen
Copy link
Owner

@juhlinm I added an improved error message to the corresponding function in #244 which should provide the name of the model causing the error.

It would be great if you could run your example with the modified version. To do so, please install the current dev release in your doc-building-environment via pip install git+https://github.com/mansenfranzen/[email protected] and rebuild your docs.

@juhlinm
Copy link

juhlinm commented Apr 8, 2024

@mansenfranzen We got an error message, which might be able to help us get further. Thanks.

Exception occurred:  
File "/usr/local/lib/python3.10/site-packages/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py", line 571, in sort_func    
raise ValueError(msg)ValueError: Field item in DynamicDependency not found in tagorder

EDIT:
Here is a minimal example of our code, that will lead to the issue.

from abc import ABC
from typing import Any, ClassVar, Dict, Generic, Optional, Type, TypeVar

from pydantic import BaseModel, ConfigDict

NO_TAG = "__no_tag__"


class BaseItem(BaseModel, ABC):
    __tag__: str = ""
    __group__: str = ""
    __subtypes__: Dict[str, Type['BaseItem']] = dict()
    model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True)

    def __init_subclass__(cls: Type['BaseItem'], *args: Any, **kwargs: Any) -> None:
        if "tag" in kwargs:
            tag = kwargs["tag"]
            if tag == NO_TAG:
                return

            cls.__tag__ = tag if tag else cls.__name__.lower()
            cls.__subtypes__[cls.__tag__] = cls
        else:
            if BaseItem in cls.__bases__:
                cls.__subtypes__ = dict()


ItemT = TypeVar("ItemT", bound=BaseItem)


class DynamicBaseItem(BaseModel, Generic[ItemT]):
    __over__: ClassVar[Any]

    item: ItemT
    """The BaseItem that is wrapped."""

    model_config = ConfigDict(extra="forbid")

    def __init_subclass__(cls: Type['DynamicBaseItem[ItemT]'], over: Type[ItemT] = None) -> None:
        if over:
            cls.__over__ = over  # type: ignore


class Dependency(BaseItem):
    async def run(self) -> Any:
        pass


class DynamicDependency(DynamicBaseItem[Dependency], over=Dependency):
    name: Optional[str] = None

'ValueError: Field item in DynamicDependency not found in tagorder'
'item' seems to be defined in the parent class, but there is some meta-programming going on here, which I'm not fully familiar with. Maybe that affects something.

@j-carson
Copy link
Contributor

@juhlinm I'm having problems with causing your test example to fail:
Could I get your sphinx/autodoc configuration settings please? Which of the members are you trying to document? Are you turning on inherited/special/private members? Which versions of pydantic are you on?

@juhlinm
Copy link

juhlinm commented Apr 11, 2024

@j-carson Sure, here is the conf.py used:

from typing import List

project = "XXX"
copyright = "XXX"
author = "XXX"

release = "0.1"

extensions: List[str] = [
    "sphinx.ext.autodoc", "sphinx.ext.napoleon", "sphinx.ext.viewcode", "sphinx.ext.graphviz", "myst_parser",
    'sphinxcontrib.autodoc_pydantic'
]

source_suffix = {
    '.rst': 'restructuredtext',
    '.md': 'markdown',
}

html_static_path = ['static']

exclude_patterns = [
    "install.py",
    "conf.py",
    "**/out",
    "**/.coverage",
    "**/.pytest_cache",
    ".pytest_cache",
    "**/.vscode",
    "**/*.pyc",
    "**/__pycache__",
    "**/*.egg-info",
    "**/.eggs",
    "**/dist",
    "**/build",
    "**/.virtualenv",
    ".virtualenv",
    "**/lib",
    "**/.idea",
    "**/.cache",
    "**/coverage",
    "**/.mypy_cache",
    "**/version.txt",
    "**/pytest_coverage",
    "**/pytest_*",
    "**/.venv",
    "**/.vagrant",
    "**/log.html",
    "**/output.xml",
    "**/report.html",
]

html_theme = "sphinx_rtd_theme"

add_module_names = False
python_use_unqualified_type_names = True

autodoc_pydantic_model_undoc_members = False
autodoc_pydantic_model_show_json = False
autodoc_pydantic_field_list_validators = False
autodoc_pydantic_model_show_validator_summary = False
autodoc_pydantic_field_show_constraints = True
autodoc_pydantic_field_doc_policy = "both"
autodoc_pydantic_model_summary_list_order = "bysource"


def setup(app) -> None:  # type: ignore
    app.add_css_file('style.css')

The error occurs when trying to document the field item of DynamicDependency (inherited).

We have inherited members turned on for BaseModel. Do we need it for DynamicBaseItem as well?

.. autopydantic_model:: proj.DynamicDependency
    :inherited-members: BaseModel

Pydantic 2.6.4

@afdaniele
Copy link

Hi,

I'm seeing the same error. It looks like it only appears when the directive configuration :model-summary-list-order: bysource is used together with :inherited-members: pydantic.BaseModel. If I leave model-summary-list-order to its default configuration it builds without errors.

Hope this helps.

@mansenfranzen
Copy link
Owner

@afdaniele Thanks for sharing your insights!

Do you have a reproducible example, too? This would be highly appreciated to improve our test coverage for this bug.

@afdaniele
Copy link

afdaniele commented Apr 18, 2024

Unfortunately, I came across this issue only as part of a big project developed using jupyter-book, a wrapper around sphinx, so, a long way from a simple sphinx example to share.

If it can be of any help though, the model I'm trying to document is relatively simple and has a hierarchy of 3 levels.
It is a library of messages that are serialized and exchanged over the network. There is a base class called BaseMessage that inherits from pydantic.BaseModel. A class Sensor(BaseMessage) and then finally a class Camera(Sensor).
While BaseMessage does not have fields, both Sensor and Camera do, and so if I do,

.. autopydantic_model:: duckietown_messages.sensors.camera.Camera
    :model-summary-list-order: bysource
    :inherited-members: pydantic.BaseModel

I get the error above.
While,

.. autopydantic_model:: duckietown_messages.sensors.camera.Camera
    :inherited-members: pydantic.BaseModel

works fine, except for the unwanted alphabetical order of the members.
Every other configuration parameter is left at the default value.
Hope this helps.

afdaniele added a commit to duckietown/dt-jupyter-book that referenced this issue Apr 19, 2024
@juhlinm
Copy link

juhlinm commented May 6, 2024

Yeah, removing the :inherited-members: pydantic.BaseModel from the .rst-file made our documentation finish generation.

@j-carson
Copy link
Contributor

@mansenfranzen Were you ever able to turn any of the examples into a failing test?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

6 participants