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

What does "No referent" error mean? #2

Open
rmorshea opened this issue Oct 20, 2022 · 7 comments
Open

What does "No referent" error mean? #2

rmorshea opened this issue Oct 20, 2022 · 7 comments

Comments

@rmorshea
Copy link
Owner

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

  • This is a class in mymodule.py.
  • The docstring contains no references at all.
  • The class is a subclass of BaseDataAPI, and that's the only reference to BaseDataAPI.
  • BaseDataAPI is imported in mymodule.py with from ...core.base import BaseDataAPI.

mylib.core.base.BaseDataAPI

  • This is a class in base.py.
  • Regarding MySpecificAPI there is no more to say - its simply a subclass and its unknown/unrelated from BaseDataAPI class's perspective.

My Env:

  • Python 3.7
  • Sphinx 5.2.3

@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:

  • Primary access: mylib.exceptions.errors.InvalidError
  • Secondary access: mylib.exceptions.InvalidError, provided via import to simplify public API structure.
  • Referenced in docstring (example): mylib.resources.something.mymodule.MySpecificAPI as relative reference: :raises: InvalidError. It is imported via from ...exceptions import 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 sphinx-doc/sphinx#4961 (comment)

@rmorshea
Copy link
Owner Author

rmorshea commented Oct 20, 2022

@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...

  • doesn't exist
  • exists, but doesn't have a docstring
  • it exists and has a docstring, but we couldn't discover it for some reason

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
Copy link

martinpakosch commented Oct 20, 2022

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:

  • BaseDataAPI exists and has only a single point of definition: mylib.core.base.BaseDataAPI
  • The class has a docstring with title, description and come :cvar xyz: tags.

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
Copy link

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:

  • mylib.core.base.BaseDataObject
    • mylib.core.base.BaseDataAPI
      • mylib.resources.backbone.mymodule.MySpecificAPI

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
Copy link
Owner Author

Two other things to check.

  • Can you confirm that BaseDataAPI has docs that were generated for it by Sphinx?
  • Did you clone from this repo or the one from the 23andMe org?

@martinpakosch
Copy link

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
Copy link
Owner Author

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
Copy link

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?

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