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

Inferred type of function parameters not correctly generating <a> tag #23

Closed
Jonxslays opened this issue May 23, 2023 · 11 comments
Closed

Comments

@Jonxslays
Copy link

I've been using mkdocstrings[python] and mkdocs-material with autorefs for my documentation but in my most recent deployment inferred types of parameters to functions are no longer linking correctly.

Upon examination of the outputted html from mkdocs build the class name is a <span> instead of an <a> tag.

<td><code>_secondary</code></td>
<td>
      <code><a class="autorefs autorefs-internal" href="../secondary/#secondary">secondary</a>.<span title="secondary.Secondary">Secondary</span></code>
</td>

Does anyone have any ideas as to the issue here?

Here is a minimal example of the way the code and docstrings look:

# main.py
import secondary

class Main:
    """The main class."""

    def mutate_secondary(self, _secondary: secondary.Secondary) -> None:
        """Does something with secondary.

        Args:
            _secondary: The secondary instance.
        """
        ...
# secondary.py
class Secondary:
    """Some secondary class."""
    ...

And the resulting docs:

image

Previously both secondary and Secondary would link to the respective module and class, but only the module does now.

My mkdocs config file looks like:

site_name: Mkdocs Bug Test

plugins:
  - search
  - autorefs
  - include-markdown
  - mkdocstrings:
      custom_templates: docs/templates
      handlers:
        python:
          options:
            members_order: alphabetical
            docstring_style: google
            show_signature_annotations: true
            separate_signature: true

markdown_extensions:
  - pymdownx.highlight:
      anchor_linenums: true
  - pymdownx.inlinehilite
  - pymdownx.superfences
  - admonition
  - pymdownx.details
  - footnotes
  - pymdownx.tabbed:
      alternate_style: true

watch:
  - modules

theme:
  name: material

  palette:
    - scheme: slate
      primary: deep purple
      accent: purple
      toggle:
        icon: material/weather-night
        name: Switch to light mode

    - media: "(prefers-color-scheme: light)"
      scheme: default
      primary: light blue
      accent: purple
      toggle:
        icon: material/weather-sunny
        name: Switch to dark mode

  font:
    text: Noto Sans
    code: Noto Sans Mono

  features:
    - navigation.instant
    - navigation.tabs
    - navigation.tabs.sticky
    - navigation.top
    - content.tabs.link

  icon:
    repo: fontawesome/brands/github

nav:
  - "index.md"
  - "Modules":
    - "reference/main.md"
    - "reference/secondary.md"
@pawamoy
Copy link
Member

pawamoy commented May 23, 2023

Is secondary.Secondary actually rendered somewhere in your API reference? You only get a span when there's no heading to link to.

@Jonxslays
Copy link
Author

Jonxslays commented May 23, 2023

Yes it is, I can manually type the link with #modules.secondary.Secondary and I go directly to the Secondary class. It just isn't linked properly back in the Main class.

image

Here is my actual live documentation where you can see this occurring. All the classes experiencing this do have their own direct link.

https://jonxslays.github.io/wom.py/v0.4.1/reference/services/

Note the Serializer parameter to BaseService there, and its direct link is here: https://jonxslays.github.io/wom.py/v0.4.1/reference/serializer/#wom.serializer.Serializer


I went ahead and uploaded the minimal example and /site dir to a repo here in case it helps with debugging.

@pawamoy
Copy link
Member

pawamoy commented May 23, 2023

OK thanks I was able to identify the issue.

The issue is (at least in the reproduction repository you provided) that you import secondary with import secondary instead of from modules import secondary. Therefore the static analysis tool used by the Python handler thinks that secondary is an entirely different package.

The link to secondary happens to work because that's how autorefs works: it encountered a heading with id secondary (the title of the secondary markdown page), and since you fully enabled autorefs by listing it in mkdocs plugins, it registered it, and was later able to update the cross-reference using it.

But for secondary.Secondary, there's no heading (the object's actual heading id is modules.secondary.Secondary), so autorefs falls back to trying to find an object with a corresponding id, through the Python handler, which does not find it. So the cross-reference is not resolved.

To fix this, use the "new kind of absolute" imports, i.e. always use from pkg import thing or from . import thing, but not import thing. By the way I'm not sure how your code works: are you using Python 2? These old relative imports are not supported in Python 3 I think:

% python3.7
Python 3.7.15 (default, Nov  5 2022, 23:33:40) 
[GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from modules import main
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/media/data/dev/mkdocs-bug-test/modules/main.py", line 1, in <module>
    import secondary
ModuleNotFoundError: No module named 'secondary'

@pawamoy
Copy link
Member

pawamoy commented May 23, 2023

Alternatively, if your main and secondary modules are supposed to be standalone modules in a collection of modules, then the modules folder should not contain an __init__.py module, and you should add the modules folder to the search paths of the Python handler, see https://mkdocstrings.github.io/python/usage/#paths. Then instead of ::: modules.main and ::: modules.secondary, just use ::: main and ::: secondary.

@Jonxslays
Copy link
Author

Let me lead with a huge thanks for helping me troubleshoot this issue, and your contributions to open source.

Good catch that I used an incorrect import pattern in the repro example. I never actually ran that code just used it to generate docs. In my actual repository i do use the from x import y syntax, and all type hints are of the style y.Class.

I just tried this pattern you described of specifying paths, and removing the modules prefix in the markdown files ::: secondary.

This does fix the link for the Secondary class itself but then the module is no longer a link.

image

Is there a way to get the best of both worlds? Whats odd is that in my previous release both links just worked using the pattern I had before. I didn't change anything and it broke out of nowhere.

This is my actual repository: https://github.com/Jonxslays/wom.py

If you compare docs v0.4.1 with v0.4.0 you'll see the difference I'm describing.

@pawamoy
Copy link
Member

pawamoy commented May 24, 2023

I've updated your mkdocs-bug-test repo locally and it works fine on my side. Both secondary and Secondary link to the respective object.

# main

::: main
# secondary

::: secondary
rm modules/__init__.py
plugins:
  - search
  - autorefs
  - include-markdown
  - mkdocstrings:
      handlers:
        python:
          paths: [modules]
          options:
            members_order: alphabetical
            docstring_style: google
            show_signature_annotations: true
            separate_signature: true

@pawamoy
Copy link
Member

pawamoy commented May 24, 2023

I'll check what happens in your Wise Old Man project now 🙂

@pawamoy
Copy link
Member

pawamoy commented May 24, 2023

Found the issue as well. This is a regression in Griffe, the static analysis tool. Will fix and push a release today 🙂

pawamoy added a commit to mkdocstrings/griffe that referenced this issue May 24, 2023
@pawamoy
Copy link
Member

pawamoy commented May 24, 2023

0.28.2 is out, closing!

@pawamoy pawamoy closed this as completed May 24, 2023
@Jonxslays
Copy link
Author

Thanks again for all your help! Everythings looking good with 0.28.2.

@pawamoy
Copy link
Member

pawamoy commented May 24, 2023

You're welcome, thank you for making the investigation easy by providing all the necessary info!

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

No branches or pull requests

2 participants