mkdocstrings / pytkdocs

Load Python objects documentation.
https://mkdocstrings.github.io/pytkdocs
ISC License
50 stars 32 forks source link

[BUG] detect_field_model fails for DjangoModelFactory from factory-boy #142

Open mschoettle opened 2 years ago

mschoettle commented 2 years ago

Describe the bug

I use mkdocstrings and have a Django project where I started using factory-boy. Once I added a factory class (sub-class of factory.django.DjangoModelFactory) the following error occurs:

Traceback (most recent call last):
    File "<snip>/.venv/lib/python3.10/site-packages/pytkdocs/cli.py", line 205, in main
    output = json.dumps(process_json(line))
    File "<snip>/.venv/lib/python3.10/site-packages/pytkdocs/cli.py", line 114, in process_json
    return process_config(json.loads(json_input))
    File "<snip>/.venv/lib/python3.10/site-packages/pytkdocs/cli.py", line 91, in process_config
    obj = loader.get_object_documentation(path, members)
    File "<snip>/.venv/lib/python3.10/site-packages/pytkdocs/loader.py", line 358, in get_object_documentation
    root_object = self.get_module_documentation(leaf, members)
    File "<snip>/.venv/lib/python3.10/site-packages/pytkdocs/loader.py", line 426, in get_module_documentation
    root_object.add_child(self.get_class_documentation(child_node))
    File "<snip>/.venv/lib/python3.10/site-packages/pytkdocs/loader.py", line 542, in get_class_documentation
    if self.detect_field_model(attr_name, direct_members, all_members):
    File "<snip>/.venv/lib/python3.10/site-packages/pytkdocs/loader.py", line 577, in detect_field_model
    if remainder and not attrgetter(remainder)(all_members[first_order_attr_name]):
AttributeError: 'DjangoOptions' object has no attribute 'get_fields'

To Reproduce

Creating a factory class for Django's user model should be sufficient:

from django.contrib.auth import get_user_model
from factory.django import DjangoModelFactory

User = get_user_model()

class UserFactory(DjangoModelFactory):
    class Meta:
        model = User

Expected behavior

Not sure if it is a bug in retrieving information from the class. I think simply ignoring should be sufficient.

System (please complete the following information):

Additional context

I was able to workaround this problem by ensuring that the attr exists:

if not hasattr(all_members[first_order_attr_name], remainder):
        return False
pawamoy commented 2 years ago

Hi @mschoettle, thank you for the report.

Would you like to send a pull request? An alternative is that you try the new handler, which does not suffer from this kind of introspection issues, but also doesn't have special support for Django either (yet). See https://mkdocstrings.github.io/handlers/overview/#about-the-python-handlers

mschoettle commented 2 years ago

I should be able to send a PR. Long-term I would like to move to the new handler but currently we are using the Django support. Let me know if there is anything that can be contributed for that in the new handler.

pawamoy commented 2 years ago

I had started a prototype for a Django extension, but it didn't take the right approach I think. Let me retry now that the code is a bit more mature.