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

AttributeError: 'NoneType' object has no attribute 'Config' #124

Closed
iwishiwasaneagle opened this issue May 26, 2022 · 9 comments
Closed
Assignees
Labels
bug Something isn't working

Comments

@iwishiwasaneagle
Copy link

autodoc_pydantic failing builds without much information or which model is causing the issue.

Exception occurred:
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/inspection.py", line 352, in __init__
    self.attribute: Dict = self.model.Config
AttributeError: 'NoneType' object has no attribute 'Config'
Full log
# Sphinx version: 4.5.0
# Python version: 3.9.12 (CPython)
# Docutils version: 0.17.1 release
# Jinja2 version: 3.1.2
# Last messages:
...
# Loaded extensions:
#   sphinx.ext.mathjax (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/mathjax.py
#   sphinxcontrib.applehelp (1.0.2) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/applehelp/__init__.py
#   sphinxcontrib.devhelp (1.0.2) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/devhelp/__init__.py
#   sphinxcontrib.htmlhelp (2.0.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/htmlhelp/__init__.py
#   sphinxcontrib.serializinghtml (1.1.5) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/serializinghtml/__init__.py
#   sphinxcontrib.qthelp (1.0.3) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/qthelp/__init__.py
#   alabaster (0.7.12) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/alabaster/__init__.py
#   sphinx.ext.autodoc.preserve_defaults (1.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/autodoc/preserve_defaults.py
#   sphinx.ext.autodoc.type_comment (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/autodoc/type_comment.py
#   sphinx.ext.autodoc (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/autodoc/__init__.py
#   sphinx.ext.intersphinx (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/intersphinx.py
#   sphinx.ext.todo (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/todo.py
#   sphinx.ext.autosummary (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/autosummary/__init__.py
#   sphinx.ext.viewcode (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/viewcode.py
#   sphinx.ext.coverage (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/coverage.py
#   sphinx.ext.doctest (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/doctest.py
#   sphinx.ext.ifconfig (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/ifconfig.py
#   sphinx.ext.napoleon (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/napoleon/__init__.py
#   sphinx_rtd_theme (unknown version) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx_rtd_theme/__init__.py
#   nbsphinx (0.8.8) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/nbsphinx.py
#   sphinxcontrib.autodoc_pydantic (1.7.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/__init__.py
#   recommonmark (0.7.1) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/recommonmark/__init__.py
Traceback (most recent call last):
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/cmd/build.py", line 276, in build_main
    app.build(args.force_all, filenames)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/application.py", line 330, in build
    self.builder.build_update()
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/builders/__init__.py", line 286, in build_update
    self.build(to_build,
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/builders/__init__.py", line 300, in build
    updated_docnames = set(self.read())
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/builders/__init__.py", line 407, in read
    self._read_serial(docnames)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/builders/__init__.py", line 428, in _read_serial
    self.read_doc(docname)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/builders/__init__.py", line 468, in read_doc
    doctree = read_doc(self.app, self.env, self.env.doc2path(docname))
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/io.py", line 181, in read_doc
    pub.publish()
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/core.py", line 217, in publish
    self.document = self.reader.read(self.source, self.parser,
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/io.py", line 101, in read
    self.parse()
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/readers/__init__.py", line 78, in parse
    self.parser.parse(self.input, document)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/parsers.py", line 89, in parse
    self.statemachine.run(inputlines, document, inliner=self.inliner)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 170, in run
    results = StateMachineWS.run(self, input_lines, input_offset,
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 239, in run
    context, next_state, result = self.check_line(
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 451, in check_line
    return method(match, context, next_state)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2769, in underline
    self.section(title, source, style, lineno - 1, messages)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 327, in section
    self.new_subsection(title, lineno, messages)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 393, in new_subsection
    newabsoffset = self.nested_parse(
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 281, in nested_parse
    state_machine.run(block, input_offset, memo=self.memo,
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 239, in run
    context, next_state, result = self.check_line(
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 451, in check_line
    return method(match, context, next_state)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2769, in underline
    self.section(title, source, style, lineno - 1, messages)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 327, in section
    self.new_subsection(title, lineno, messages)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 393, in new_subsection
    newabsoffset = self.nested_parse(
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 281, in nested_parse
    state_machine.run(block, input_offset, memo=self.memo,
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 239, in run
    context, next_state, result = self.check_line(
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 451, in check_line
    return method(match, context, next_state)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2342, in explicit_markup
    nodelist, blank_finish = self.explicit_construct(match)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2354, in explicit_construct
    return method(self, expmatch)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2096, in directive
    return self.run_directive(
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2146, in run_directive
    result = directive_instance.run()
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/autodoc/directive.py", line 165, in run
    result = parse_generated_content(self.state, params.result, documenter)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/autodoc/directive.py", line 108, in parse_generated_content
    nested_parse_with_titles(state, content, node)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/util/nodes.py", line 340, in nested_parse_with_titles
    return state.nested_parse(content, 0, node, match_titles=1)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 281, in nested_parse
    state_machine.run(block, input_offset, memo=self.memo,
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 239, in run
    context, next_state, result = self.check_line(
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 451, in check_line
    return method(match, context, next_state)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2342, in explicit_markup
    nodelist, blank_finish = self.explicit_construct(match)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2354, in explicit_construct
    return method(self, expmatch)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2096, in directive
    return self.run_directive(
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2146, in run_directive
    result = directive_instance.run()
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/domains/__init__.py", line 281, in run
    return super().run()
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/directives/__init__.py", line 200, in run
    self.state.nested_parse(self.content, self.content_offset, contentnode)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 281, in nested_parse
    state_machine.run(block, input_offset, memo=self.memo,
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 239, in run
    context, next_state, result = self.check_line(
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 451, in check_line
    return method(match, context, next_state)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2344, in explicit_markup
    self.explicit_list(blank_finish)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2369, in explicit_list
    newline_offset, blank_finish = self.nested_list_parse(
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 318, in nested_list_parse
    state_machine.run(block, input_offset, memo=self.memo,
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 239, in run
    context, next_state, result = self.check_line(
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 451, in check_line
    return method(match, context, next_state)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2647, in explicit_markup
    nodelist, blank_finish = self.explicit_construct(match)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2354, in explicit_construct
    return method(self, expmatch)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2096, in directive
    return self.run_directive(
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2146, in run_directive
    result = directive_instance.run()
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/domains/__init__.py", line 281, in run
    return super().run()
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/directives/__init__.py", line 181, in run
    name = self.handle_signature(sig, signode)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/directives/directives.py", line 266, in handle_signature
    self.replace_return_node(signode)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/directives/directives.py", line 247, in replace_return_node
    inspector = ModelInspector.from_signode(signode)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/inspection.py", line 547, in from_signode
    return cls(model)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/inspection.py", line 533, in __init__
    self.config = ConfigInspector(self)
  File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/inspection.py", line 352, in __init__
    self.attribute: Dict = self.model.Config
AttributeError: 'NoneType' object has no attribute 'Config'
@mansenfranzen
Copy link
Owner

Thanks for opening an issue here.

I won't be able to help you unless you provide some of the pydantic models that cause the error. Perhaps you can narrow it down. This would be of great help. More concretely, watch out for non standard models (e g. Multiple inheritance).

If your repository is public, I can have a look myself.

@mansenfranzen mansenfranzen self-assigned this May 26, 2022
@mansenfranzen mansenfranzen added the bug Something isn't working label May 26, 2022
@iwishiwasaneagle
Copy link
Author

So I narrowed it down to this model:

# Affine.py
import affine as _affine
import pydantic


class Affine(pydantic.BaseModel):
    a: float
    b: float
    c: float
    d: float
    e: float
    f: float

    @classmethod
    def from_affineAffine(cls, _affine: _affine.Affine):
        return cls(
            a=_affine.a, b=_affine.b, c=_affine.c, d=_affine.d, e=_affine.e, f=_affine.f
        )

Which confuses me as it's not even a complex model at that, and works flawlessly in my code and tests.

@iwishiwasaneagle
Copy link
Author

Okay I think I've narrowed it down. When I change the name to anything other than Affine it's fine.

I do have another data model called Affine but that's in a seperate module and not a pydantic class anyway. I also have multiple other "duplicate" classes, one for pydantic one for sqlalchemy ORM which is confusing.

rg "class Affine\(" 
db/Affine.py
13:class Affine(_BaseModel):

Affine.py
8:class Affine(pydantic.BaseModel):

@mansenfranzen
Copy link
Owner

Thanks for providing more information on this.

I took a closer look at it and it seems as if ModelInspector.from_signode is having trouble to find the correct python class. However, it is still hard for me to reproduce your error. Would you mind to provide a simplified/minified example with all of those 3 python modules containing the 3 different Affine class implementations with their corresponding import statements? This would be of great help.

@iwishiwasaneagle
Copy link
Author

Here are my two Affine class implementations. The third one is from this package: https://pypi.org/project/affine/

# src/project/Types/db/Affine.py

from project.Types import Affine as pd_Affine

import affine as _affine
from sqlalchemy import Column
from sqlalchemy import Float
from sqlalchemy import Integer
from .BaseModel import _BaseModel


class Affine(_BaseModel):
    __tablename__ = "affine"
    __table_args__ = {"extend_existing": True}

    id = Column(Integer, primary_key=True)

    a = Column(Float(32))
    b = Column(Float(32))
    d = Column(Float(32))
    e = Column(Float(32))

    xoff = Column(Float(32))
    yoff = Column(Float(32))

    @classmethod
    def from_affineAffine(cls, _affine: _affine.Affine):
        affine = cls()
        affine.a = _affine.a
        affine.b = _affine.b
        affine.d = _affine.d
        affine.e = _affine.e
        affine.xoff = _affine.c
        affine.yoff = _affine.f
        return affine

# src/project/Types/Affine.py

import affine as _affine
import pydantic

class Affine(pydantic.BaseModel):
    a: float
    b: float
    c: float
    d: float
    e: float
    f: float

    @classmethod
    def from_affineAffine(cls, _affine: _affine.Affine):
        return cls(
            a=_affine.a, b=_affine.b, c=_affine.c, d=_affine.d, e=_affine.e, f=_affine.f
        )

@mansenfranzen
Copy link
Owner

This bug is addressed via #131.

Before merging the related PR, it would be great if you could test the bugfix on your site. To do so, please install the current dev release in your doc-building-environment via pip install git+https://github.com/mansenfranzen/autodoc_pydantic.git@v1.7.2-a.1 and rebuild your docs.

I'm not 100% sure if it fixes your problem because I couldn't reproduce the error given your example. It would require me to investigate your settings in more detail. But #129 had the same error traceback and it wouldn't surprise me if this also applies to your case.

@mansenfranzen
Copy link
Owner

@all-contributors please add @iwishiwasaneagle for bug

@allcontributors
Copy link
Contributor

@mansenfranzen

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

@iwishiwasaneagle
Copy link
Author

@mansenfranzen Changed to 1.7.2-a.1 and the error disappeared. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants