sphinx-doc / sphinx

The Sphinx documentation generator
https://www.sphinx-doc.org/
Other
6.55k stars 2.12k forks source link

get_relative_uri function doesn't raise NoUri #9791

Open KaKkouo opened 3 years ago

KaKkouo commented 3 years ago

Describe the bug

The get_relative_uri function doesn't raise NoUri. But It is assumed in IndexEntries class.

sphinx/environment/adapters/indexentries.py

 30     def create_index(self, builder: Builder, group_entries: bool = True,
 31                      _fixre: Pattern = re.compile(r'(.*) ([(][^()]*[)])')
 32                      ) -> List[Tuple[str, List[Tuple[str, Any]]]]:
...
 47             elif link:
 48                 try:
 49                     uri = builder.get_relative_uri('genindex', fn) + '#' + tid
 50                 except NoUri:
 51                     pass
 52                 else:
 53                     entry[0].append((main, uri))

sphinx/builders/html/init.py

 171 class StandaloneHTMLBuilder(Builder):

sphinx/builders/init.py

 32 from sphinx.util.osutil import SEP, ensuredir, relative_uri, relpath
...
154     def get_relative_uri(self, from_: str, to: str, typ: str = None) -> str:
155         """Return a relative URI between two source filenames.
156
157         May raise environment.NoUri if there's no way to return a sensible URI.
158         """
159         return relative_uri(self.get_target_uri(from_),
160                             self.get_target_uri(to, typ))

sphinx/util/osutil.py

 47
 48 def relative_uri(base: str, to: str) -> str:
 49     """Return a relative URL from ``base`` to ``to``."""
 50     if to.startswith(SEP):
 51         return to
 52     b2 = base.split('#')[0].split(SEP)
 53     t2 = to.split('#')[0].split(SEP)
 54     # remove common segments (except the last segment)
 55     for x, y in zip(b2[:-1], t2[:-1]):
 56         if x != y:
 57             break
 58         b2.pop(0)
 59         t2.pop(0)
 60     if b2 == t2:
 61         # Special case: relative_uri('f/index.html','f/index.html')
 62         # returns '', not 'index.html'
 63         return ''
 64     if len(b2) == 1 and t2 == ['']:
 65         # Special case: relative_uri('f/index.html','f/') should
 66         # return './', not ''
 67         return '.' + SEP
 68     return ('..' + SEP) * (len(b2) - 1) + SEP.join(t2)
 69

How to Reproduce

There is currently no situation in which NoUri occurs.

Expected behavior

I don't know whether NoUri should be triggered or whether there is no situation to trigger NoUri.

Your project

none

Screenshots

No response

OS

Windows10

Python version

3.8.10

Sphinx version

4.2.0

Sphinx extensions

No response

Extra tools

No response

Additional context

No response

tk0miya commented 3 years ago

It seems TeXInfo and ManPage builders raise NoUri exception: https://github.com/sphinx-doc/sphinx/blob/4c91c038b220d07bbdfe0c1680af42fe897f342c/sphinx/builders/texinfo.py#L62-L70 https://github.com/sphinx-doc/sphinx/blob/4c91c038b220d07bbdfe0c1680af42fe897f342c/sphinx/builders/manpage.py#L51-L54

KaKkouo commented 3 years ago

Thank you for taking the time to write a comment. I'm sorry, but I'm curious about something, so let me check.

Is this understanding correct? If so, I have no further questions.

tk0miya commented 3 years ago

Is this understanding correct? If so, I have no further questions.

No. The IndexEntries class is also used in other builders. For example, LaTeX builder uses it to generate indices: https://github.com/sphinx-doc/sphinx/blob/4c91c038b220d07bbdfe0c1680af42fe897f342c/sphinx/writers/latex.py#L498-L535

It seems texinfo also uses it. At present, manpage does not use it. But it does not mean manpage will not support indices in the future.

$ grep -lr IndexEntry sphinx | grep -v pyc
sphinx/domains/__init__.py
sphinx/domains/python.py
sphinx/writers/texinfo.py
sphinx/writers/latex.py
sphinx/util/nodes.py
sphinx/builders/html/__init__.py

Of course, 3rd party builders can also use it. Nothing prohibited.

KaKkouo commented 3 years ago

The class name is "IndexEngries", not "IndexEntry". All of the content you showed me was about "IndexEntry" and not about "IndexEntries". It seems that "IndexEntries" is only used in "html".

$ find . -name \*.py -exec egrep -n IndexEntries {} \; -print
35:from sphinx.environment.adapters.indexentries import IndexEntries
690:        genindex = IndexEntries(self.env).create_index(self)
./builders/html/__init__.py
26:class IndexEntries:
./environment/adapters/indexentries.py

$