Skip to content
This repository was archived by the owner on Apr 9, 2025. It is now read-only.

Commit 935a660

Browse files
authored
Merge pull request #60 from readthedocs/humitos/set-translator
2 parents 0facce0 + 8adfe97 commit 935a660

File tree

9 files changed

+165
-56
lines changed

9 files changed

+165
-56
lines changed

hoverxref/domains.py

+10
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@ def _get_docpath(self, builder, docname):
5252
return docpath
5353

5454
def _is_ignored_ref(self, env, target):
55+
# HACK: skip all references if the builder is non-html. We shouldn't
56+
# have overridden the Domain in first instance at ``setup_domains``
57+
# function, but at that time ``app.builder`` is not yet initialized. If
58+
# we suscribe ourselves to ``builder-initied`` it's too late and our
59+
# override does not take effect. Other builders (e.g. LatexBuilder) may
60+
# fail with internal functions we use (e.g. builder.get_outfilename).
61+
# So, we are skipping it here :(
62+
if env.app.builder.format != 'html':
63+
return True
64+
5565
if target in env.config.hoverxref_ignore_refs:
5666
logger.info(
5767
'Ignoring reference in hoverxref_ignore_refs. target=%s',

hoverxref/extension.py

+19-18
Original file line numberDiff line numberDiff line change
@@ -147,31 +147,32 @@ def setup_translators(app):
147147
and our own ``HoverXRefHTMLTranslatorMixin`` that includes the logic to
148148
``_hoverxref`` attributes.
149149
"""
150-
if not app.registry.translators.items():
150+
151+
if app.builder.format != 'html':
152+
# do not modify non-html builders
153+
return
154+
155+
for name, klass in app.registry.translators.items():
151156
translator = types.new_class(
152157
'HoverXRefHTMLTranslator',
153158
(
154159
HoverXRefHTMLTranslatorMixin,
155-
app.builder.default_translator_class,
160+
klass,
156161
),
157162
{},
158163
)
159-
app.set_translator(app.builder.name, translator, override=True)
160-
else:
161-
for name, klass in app.registry.translators.items():
162-
if app.builder.format != 'html':
163-
# Skip translators that are not HTML
164-
continue
165-
166-
translator = types.new_class(
167-
'HoverXRefHTMLTranslator',
168-
(
169-
HoverXRefHTMLTranslatorMixin,
170-
klass,
171-
),
172-
{},
173-
)
174-
app.set_translator(name, translator, override=True)
164+
app.set_translator(name, translator, override=True)
165+
166+
translator = types.new_class(
167+
'HoverXRefHTMLTranslator',
168+
(
169+
HoverXRefHTMLTranslatorMixin,
170+
app.builder.default_translator_class,
171+
),
172+
{},
173+
)
174+
app.set_translator(app.builder.name, translator, override=True)
175+
175176

176177

177178
def is_hoverxref_configured(app, config):

tests/__init__.py

Whitespace-only changes.

tests/conftest.py

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import os
2+
import shutil
3+
import pytest
4+
5+
from .utils import srcdir, prefixdocumentsrcdir, customobjectsrcdir, pythondomainsrcdir
6+
7+
8+
@pytest.fixture(autouse=True, scope='function')
9+
def remove_sphinx_build_output():
10+
"""Remove _build/ folder, if exist."""
11+
for path in (srcdir, prefixdocumentsrcdir, customobjectsrcdir, pythondomainsrcdir):
12+
build_path = os.path.join(path, '_build')
13+
if os.path.exists(build_path):
14+
shutil.rmtree(build_path)

tests/examples/default/conf.py

+5
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,8 @@
55
'sphinx.ext.autosectionlabel',
66
'hoverxref.extension',
77
]
8+
9+
latex_documents = [
10+
(master_doc, 'test.tex', u'test Documentation',
11+
u'test', 'manual'),
12+
]

tests/examples/default/index.rst

+7
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,10 @@ Using ``hoverxref`` (or ``ref`` if ``hoverxref_auto_ref=True``) should add an ``
99
:ref:`This a :ref: to Chapter I <Chapter I>`.
1010

1111
:hoverxref:`This a :hoverxref: to Chapter I, Section I <Section I>`.
12+
13+
.. _example-reference:
14+
15+
Example Reference
16+
-----------------
17+
18+
This is a reference to :ref:`example-reference`.

tests/test_htmltag.py

+1-38
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,6 @@
1-
import os
21
import pytest
3-
import shutil
42

5-
6-
srcdir = os.path.join(
7-
os.path.dirname(os.path.abspath(__file__)),
8-
'examples',
9-
'default',
10-
)
11-
12-
# srcdir with ``autosectionlabel_prefix_document = True`` config
13-
prefixdocumentsrcdir = os.path.join(
14-
os.path.dirname(os.path.abspath(__file__)),
15-
'examples',
16-
'prefixdocument',
17-
)
18-
19-
# srcdir with ``Sphinx.add_object_type`` call
20-
customobjectsrcdir = os.path.join(
21-
os.path.dirname(os.path.abspath(__file__)),
22-
'examples',
23-
'custom-object',
24-
)
25-
26-
# srcdir with ``:py:class:`` call
27-
pythondomainsrcdir = os.path.join(
28-
os.path.dirname(os.path.abspath(__file__)),
29-
'examples',
30-
'python-domain',
31-
)
32-
33-
34-
@pytest.fixture(autouse=True, scope='function')
35-
def remove_sphinx_build_output():
36-
"""Remove _build/ folder, if exist."""
37-
for path in (srcdir, prefixdocumentsrcdir, customobjectsrcdir, pythondomainsrcdir):
38-
build_path = os.path.join(path, '_build')
39-
if os.path.exists(build_path):
40-
shutil.rmtree(build_path)
3+
from .utils import srcdir, prefixdocumentsrcdir, customobjectsrcdir, pythondomainsrcdir
414

425

436
@pytest.mark.sphinx(

tests/test_internals.py

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import inspect
2+
import os
3+
import pytest
4+
import shutil
5+
from unittest import mock
6+
7+
from hoverxref.translators import HoverXRefHTMLTranslatorMixin
8+
9+
from .utils import srcdir
10+
11+
12+
@pytest.mark.sphinx(
13+
srcdir=srcdir,
14+
buildername='latex',
15+
confoverrides={
16+
'hoverxref_project': 'myproject',
17+
'hoverxref_version': 'myversion',
18+
},
19+
)
20+
def test_dont_override_translator_non_html_builder(app, status, warning):
21+
app.build()
22+
path = app.outdir / 'test.tex'
23+
assert path.exists() is True
24+
content = open(path).read()
25+
26+
assert app.builder.format == 'latex'
27+
for name, klass in app.registry.translators.items():
28+
assert not issubclass(klass, HoverXRefHTMLTranslatorMixin)
29+
30+
31+
@pytest.mark.sphinx(
32+
srcdir=srcdir,
33+
buildername='html',
34+
confoverrides={
35+
'hoverxref_project': 'myproject',
36+
'hoverxref_version': 'myversion',
37+
},
38+
)
39+
def test_override_translator_non_html_builder(app, status, warning):
40+
app.build()
41+
path = app.outdir / 'index.html'
42+
assert path.exists() is True
43+
content = open(path).read()
44+
45+
assert app.builder.format == 'html'
46+
for name, klass in app.registry.translators.items():
47+
assert issubclass(klass, HoverXRefHTMLTranslatorMixin)
48+
49+
50+
@pytest.mark.sphinx(
51+
srcdir=srcdir,
52+
buildername='latex',
53+
confoverrides={
54+
'hoverxref_project': 'myproject',
55+
'hoverxref_version': 'myversion',
56+
'hoverxref_auto_ref': True,
57+
},
58+
)
59+
def test_dont_fail_non_html_builder(app, status, warning):
60+
"""
61+
Test our resolver is not used by non-HTML builder.
62+
63+
When running the build with ``latex`` as builder and
64+
``hoverxref_auto_ref=True`` it should not fail with
65+
66+
def _get_docpath(self, builder, docname):
67+
docpath = builder.get_outfilename(docname)
68+
AttributeError: 'LaTeXBuilder' object has no attribute 'get_outfilename'
69+
70+
LaTeXBuilder should never use our resolver.
71+
"""
72+
73+
with mock.patch('hoverxref.domains.HoverXRefBaseDomain._get_docpath') as _get_docpath:
74+
app.build()
75+
assert not _get_docpath.called
76+
path = app.outdir / 'test.tex'
77+
assert path.exists() is True
78+
content = open(path).read()
79+
80+
assert app.builder.format == 'latex'

tests/utils.py

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import os
2+
3+
4+
srcdir = os.path.join(
5+
os.path.dirname(os.path.abspath(__file__)),
6+
'examples',
7+
'default',
8+
)
9+
10+
# srcdir with ``autosectionlabel_prefix_document = True`` config
11+
prefixdocumentsrcdir = os.path.join(
12+
os.path.dirname(os.path.abspath(__file__)),
13+
'examples',
14+
'prefixdocument',
15+
)
16+
17+
# srcdir with ``Sphinx.add_object_type`` call
18+
customobjectsrcdir = os.path.join(
19+
os.path.dirname(os.path.abspath(__file__)),
20+
'examples',
21+
'custom-object',
22+
)
23+
24+
# srcdir with ``:py:class:`` call
25+
pythondomainsrcdir = os.path.join(
26+
os.path.dirname(os.path.abspath(__file__)),
27+
'examples',
28+
'python-domain',
29+
)

0 commit comments

Comments
 (0)