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

Support cross-refs in attributes signatures / Support stringified types in base classes subscripts #586

Open
llucax opened this issue Jul 7, 2023 · 10 comments
Labels
bug Something isn't working docs Improvements or additions to documentation extractor: griffe Related to griffe feature New feature or request

Comments

@llucax
Copy link

llucax commented Jul 7, 2023

Describe the bug

Nested classes attribute types don't get properly linked.

To Reproduce

I hope it is enough to show an open source repo with the issue.

Expected behavior

The Event attribute types get properly linked.

Screenshots

image


Even for pathlib.Path that is a Python standard library, for which the cross-linking is properly configured doesn't work in the nested class. But in other parts it works perfectly.

image

Information (please complete the following information):

  • OS: Linux
  • Browser: firefox
  • mkdocstrings: 0.22.0
  • mkdocstrings-python: 1.1.2
@llucax llucax added the unconfirmed This bug was not reproduced yet label Jul 7, 2023
@llucax
Copy link
Author

llucax commented Jul 7, 2023

Related but probably different issue, it doesn't get linked either as a generic type instance:

image

But I'm not sure if that is because the type is specified as a string, or because it is a type defined inside the class itself (yeah, probably this is not the cleanest pattern, but if Python can deal with it maybe mkdocstrings should too?).

Let me know if I should create a separate issue for this.

@pawamoy
Copy link
Member

pawamoy commented Jul 7, 2023

Hello, thanks for the report. Yes, a public repo is perfect, thank you!

However I don't think this is a bug, but just a current limitation. If you look at this heading https://frequenz-floss.github.io/frequenz-channels-python/v0.16/reference/frequenz/channels/util/#frequenz.channels.util._event.Event.is_set, you'll see that bool isn't transformed into a link either. That's because currently we don't write cross-refs in attributes types. There's no reason not to do it, it's just that I didn't think about it previously, and didn't get time to work on it yet 🙂

I'll keep this issue open as a reminder!

@pawamoy
Copy link
Member

pawamoy commented Jul 7, 2023

About Receiver['FileWatcher.Event'], do you use a string annotation in your source code too? Do you import annotations from __future__ in that module? EDIT: yes and yes, I checked the source. OK, this one needs investigation.

A bit of explanation: since you import future annotations, Griffe concludes that you don't need to use stringified annotations since all annotations are already postponed. However in your case you're inheriting from a class which uses a non-defined yet type as subscript. So you don't have a choice but to use a string. And Griffe does not understand that. I'll see if there's something we can do to improve support for such a scenario.

In the meantime, yes, you can probably avoid nesting classes in such a cyclic way.

@pawamoy pawamoy added bug Something isn't working feature New feature or request and removed unconfirmed This bug was not reproduced yet labels Jul 7, 2023
@pawamoy pawamoy changed the title autodoc: Nested classes don't render properly Support cross-refs in attributes signatures / Support stringified types in base classes subscripts Jul 7, 2023
@llucax
Copy link
Author

llucax commented Jul 7, 2023

Hi @pawamoy, thanks for the quick reply!

However I don't think this is a bug, but just a current limitation. If you look at this heading frequenz-floss.github.io/frequenz-channels-python/v0.16/reference/frequenz/channels/util/#frequenz.channels.util._event.Event.is_set, you'll see that bool isn't transformed into a link either. That's because currently we don't write cross-refs in attributes types. There's no reason not to do it, it's just that I didn't think about it previously, and didn't get time to work on it yet slightly_smiling_face

Yeah, after I write the issue I noticed there were quite a few other places where links were missing. Thanks for the clarification!

A bit of explanation: since you import future annotations, Griffe concludes that you don't need to use stringified annotations since all annotations are already postponed. However in your case you're inheriting from a class which uses a non-defined yet type as subscript. So you don't have a choice but to use a string. And Griffe does not understand that. I'll see if there's something we can do to improve support for such a scenario.

I see, thanks. Yes, I know is not a very happy thing to do, so I totally understand if it is not worth investing the effort on supporting this, but since Python does support it, maybe you still want to support it too :)

@pawamoy
Copy link
Member

pawamoy commented Jul 7, 2023

The issue with "Python supports it" is that Python supports a lot of things 🤣 Being a very dynamic language, we will never be able to statically support everything it does. Some examples are wildcard imports (PITA), dynamic base classes, and really anything that modifies attributes/functions/classes with several levels of indirection.

Besides, here it's more about what mypy supports rather than Python itself. And we will definitely never be as clever as mypy regarding type inference and semantics.

For these difficult cases, there's always the option to fall back on introspection, but it has a cost, and it cannot even ensure better results (especially regarding type annotations).

In the end, what we must do on Griffe's side it to properly document these limitations 🙂 I'll add a doc label to this issue 😄

@pawamoy pawamoy added docs Improvements or additions to documentation extractor: griffe Related to griffe labels Jul 7, 2023
@llucax
Copy link
Author

llucax commented Jul 7, 2023

Besides, here it's more about what mypy supports rather than Python itself. And we will definitely never be as clever as mypy regarding type inference and semantics.

Yeah, I mainly meant mypy supports it, which should be reasonable set of features that work mostly statically, but I understand even then mypy has a lot of special cases to support built-ins, etc. So I know it is a pretty ambitious goal to cover that subset too :)

In the end, what we must do on Griffe's side it to properly document these limitations slightly_smiling_face I'll add a doc label to this issue smile

Yeah, this makes sense too.

We are trying to find out a subset of Python that we can use and play well with the different tools we use, which is not trivial. 👍

@matankley
Copy link

Hey! Thanks for the detailed explanation in this thread. I came across it while searching how to fix the limitation that in attribute there are no cross-refs.

I face the same issue that you discussed above. Is it planned to be prioritized ?

@pawamoy
Copy link
Member

pawamoy commented Aug 23, 2023

Sure, thanks for the reminder. Right now I'm working on preserving the paths of members through aliases, and I'll work on this next 🙂

@pawamoy
Copy link
Member

pawamoy commented Aug 27, 2023

Done in mkdocstrings-python insiders v1.6.0.1.4.0 🙂

@matankley
Copy link

@pawamoy Amazing!!! thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working docs Improvements or additions to documentation extractor: griffe Related to griffe feature New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants