rmorshea / sphinx-resolve-py-references

A sphinx extension that fixes or warns about missing references to Python objects
BSD 2-Clause "Simplified" License
2 stars 0 forks source link

What does "No referent" error mean? #2

Open rmorshea opened 1 year ago

rmorshea commented 1 year ago

Hi @rmorshea,

I came across this issue as I am affected myself and across your extension. I gave it a try, simply pulled the source into my venv as I wanted to try the latest updates. ;-)

However, as soon as I activate this extension I get additional warnings on my builds while the cross-reference warnings still persist. My new warnings look like this:

WARNING: No referent for name 'mylib.core.base.BaseDataAPI' in 'C:\\<...>\\src\\mylib\\resources\\something\\mymodule.py:docstring of mylib.resources.something.mymodule.MySpecificAPI' via module 'mylib.resources.something'

The question is, what does this mean? My structure:

mylib.resources.backbone.mymodule.MySpecificAPI

mylib.core.base.BaseDataAPI

My Env:

@AA-Turner Regarding the cross-reference warnings (to share some experience): My usecase is fairly simple. Example with one warning regarding my custom exception InvalidError:

So this is fairly simple in terms of complexity. My expectation would be, that Sphinx sees this docstring reference, tries to find InvalidError locally in module.py where it is referenced, then looks at the imports and traces it back to its secondary access point. But without warnings. :D Hopefully this will work at least with rmorshea's extension after it's included to the Sphinx core. Right now it's not working in my case.

Kind regards, Martin

Originally posted by @martinpakosch in https://github.com/sphinx-doc/sphinx/issues/4961#issuecomment-1285161174

rmorshea commented 1 year ago

@martinpakosch apologies for the cryptic error message this puts out. I'll try and clean those up at some point. In general you'll get a "No referent" error in the following cases where the thing being referred to...

It's worth noting that, depending on your configuration, even though you haven't explicitly referenced BaseDataAPI in a docstring, when Sphinx generates documentation for MySpecificAPI it may try and link to BaseDataAPI. For example, in autodoc, if you use the show-inheritance flag Sphinx will try and create a link to the base class.

Given this, my suspicion is that BaseDataAPI just lacks a docstring. This might seem annoying, but part of my goal with this extension was to give me a way to get notified when I have docs that refer to things without a docstring and thus won't be linked to in the documentation.

martinpakosch commented 1 year ago

Hi Ryan,

thanks for picking up. Ok, now I got the point. Your extensions works somehow as a hook and yes, I use apidoc, which generates rst-files with show-inheritance. So I understand that there is the reference from Sphinx perspective.

What I do not understand is why it emits your warning, because:

So why does the discovery fail? Can this be because of the relative import in mylib.resources.backbone.mymodule when you analyse the ast? Edit: Or any issue with windows paths as I do not know if you need file system access during analysis.

martinpakosch commented 1 year ago

Hi Ryan,

once more... regarding my suspicion about the relative imports... I have noticed some more referent warnings, but all come from modules, that import BaseDataAPI.

Now, my subclassing looks like this:

The file mymodule.py also imports BaseDataObject as it is used by different subclasses. However, I see referent warnings for BaseDataAPI and BaseDataObject in mymodule.py. But I do not see any warning for BaseDataObject in base.py although it is the parent class for BaseDataAPI and therefore Sphinx creates also links to it due to the show-inheritance flag. So I think I do not see the later warnings because both base classes are defined in the same file. So I assume your extension does not have to analyse imports in this case.

rmorshea commented 1 year ago

Two other things to check.

martinpakosch commented 1 year ago

Ok, you got me... :-/ Unfortunately you are right, I accidentally grabbed the repo from 23andMe. I repeated the test with this one and it looks fine. No referent warnings for my base classes, although they were indeed excluded from Sphinx docs due to an empty __all__. Sorry, forgot about that detail. But nevertheless it works with your newer code. Sorry for bothering you with false-positives. :D

However, with your newer code I noticed a new referent warning related to a type annotation. It seems it is emitted due to a lack of support for lazy annotations (or what they are called) - or in this case multiple inheritance:

class MyAPI(BaseDataAPI[List[Dict[str, Any]], 'MyObject']):

Am I right? I mean I can overcome this by reordering my code, but in some cases (self-references) this might be difficult. Is this due to your extension or is it a sphinx problem? I do not use the from __future__ import annotations statement... but maybe I should in general due to the known Self problem.

rmorshea commented 1 year ago

I don't think self reference should be an issue because all sphinx is concerned with is where the definition for a given symbol resides. What is the specific warning message?

martinpakosch commented 1 year ago

WARNING: No referent for name 'MyOtherClass' at C:\<...>\src\mylib\resources\something\__init__.py:docstring of TIKPyLib.resources.something

The point is, there I'm importing MySpecificAPI from mylib.resources.something.mymodule and its class signature looks like class MySpecificAPI(BaseDataAPI[List[Dict[str, Any]], 'MyOtherClass']) where 'MyOtherClass' uses single quotes for "postponed" type evaluation. However, I guess this warning occures because there is no additional import/reference in __init__.py pointing to MyOtherClass, right? However, I would have expected this reference to work anyways and the same way as if the code would be in the same file - due to correct "postponed" type evaluation. Am I right? Or is the problem that at this point __init__.py is evaluated before any of the package's submodules so at this point Sphinx has not any specific index of this particular type yet?