Skip to content

Commit

Permalink
tmp
Browse files Browse the repository at this point in the history
  • Loading branch information
AA-Turner committed Nov 15, 2024
1 parent 15b46dc commit d4a84e3
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 70 deletions.
17 changes: 9 additions & 8 deletions sphinx/builders/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -605,22 +605,23 @@ def merge(docs: list[str], otherenv: bytes) -> None:
@final
def read_doc(self, docname: str, *, _cache: bool = True) -> None:
"""Parse a file and add/update inventory entries for the doctree."""
self.env.prepare_settings(docname)
env = self.env
env.prepare_settings(docname)

# Add confdir/docutils.conf to dependencies list if exists
docutilsconf = os.path.join(self.confdir, 'docutils.conf')
if os.path.isfile(docutilsconf):
self.env.note_dependency(docutilsconf)
env.note_dependency(docutilsconf)

filename = str(self.env.doc2path(docname))
filename = str(env.doc2path(docname))
filetype = get_filetype(self.app.config.source_suffix, filename)
publisher = self.app.registry.get_publisher(self.app, filetype)
self.env.temp_data['_parser'] = publisher.parser
env.temp_data['_parser'] = publisher.parser
# record_dependencies is mutable even though it is in settings,
# explicitly re-initialise for each document
publisher.settings.record_dependencies = DependencyList()
with (
sphinx_domains(self.env),
sphinx_domains(domains=env.domains, temp_data=env.temp_data),
rst.default_role(docname, self.config.default_role),
):
# set up error_handler for the target document
Expand All @@ -632,11 +633,11 @@ def read_doc(self, docname: str, *, _cache: bool = True) -> None:
doctree = publisher.document

# store time of reading, for outdated files detection
self.env.all_docs[docname] = time.time_ns() // 1_000
env.all_docs[docname] = time.time_ns() // 1_000

# cleanup
self.env.temp_data.clear()
self.env.ref_context.clear()
env.temp_data.clear()
env.ref_context.clear()

self.write_doctree(docname, doctree, _cache=_cache)

Expand Down
9 changes: 2 additions & 7 deletions sphinx/directives/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,13 +358,8 @@ class DefaultDomain(SphinxDirective):

def run(self) -> list[Node]:
domain_name = self.arguments[0].lower()
# if domain_name not in env.domains:
# # try searching by label
# for domain in env.domains.sorted():
# if domain.label.lower() == domain_name:
# domain_name = domain.name
# break
self.env.temp_data['default_domain'] = self.env.domains.get(domain_name)
default_domain = self.env.domains.get(domain_name)
self.env.temp_data['default_domain'] = default_domain
return []


Expand Down
7 changes: 4 additions & 3 deletions sphinx/domains/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ class Domain:
data_version = 0

def __init__(self, env: BuildEnvironment) -> None:
domaindata = env.domaindata
self.env: BuildEnvironment = env
self._role_cache: dict[str, Callable] = {}
self._directive_cache: dict[str, Callable] = {}
Expand All @@ -119,13 +120,13 @@ def __init__(self, env: BuildEnvironment) -> None:
self.roles = dict(self.roles)
self.indices = list(self.indices)

if self.name not in env.domaindata:
if self.name not in domaindata:
assert isinstance(self.initial_data, dict)
new_data = copy.deepcopy(self.initial_data)
new_data['version'] = self.data_version
self.data = env.domaindata[self.name] = new_data
self.data = domaindata[self.name] = new_data
else:
self.data = env.domaindata[self.name]
self.data = domaindata[self.name]
if self.data['version'] != self.data_version:
raise OSError('data of %r domain out of date' % self.label)
for name, obj in self.object_types.items():
Expand Down
15 changes: 8 additions & 7 deletions sphinx/domains/python/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -560,16 +560,13 @@ class PythonModuleIndex(Index):
shortname = _('modules')
domain: PythonDomain

def generate(self, docnames: Iterable[str] | None = None,
) -> tuple[list[tuple[str, list[IndexEntry]]], bool]:
def generate(
self, docnames: Iterable[str] | None = None
) -> tuple[list[tuple[str, list[IndexEntry]]], bool]:
doc_names = frozenset(docnames) if docnames is not None else None

content: dict[str, list[IndexEntry]] = {}
# list of prefixes to ignore
ignores: list[str] = sorted(
self.domain.env.config['modindex_common_prefix'], key=len, reverse=True
)

ignores: list[str] = sorted(self.domain.modindex_common_prefix, key=len, reverse=True)
# list of all modules, sorted by module name
modules = sorted(self.domain.modules.items(), key=lambda t: t[0].lower())

Expand Down Expand Up @@ -706,6 +703,10 @@ class PythonDomain(Domain):
PythonModuleIndex,
]

def __init__(self, env: BuildEnvironment) -> None:
super().__init__(env)
self.modindex_common_prefix = env.config.modindex_common_prefix

@property
def objects(self) -> dict[str, ObjectEntry]:
return self.data.setdefault('objects', {}) # fullname -> ObjectEntry
Expand Down
1 change: 1 addition & 0 deletions sphinx/environment/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ def setup(self, app: Sphinx) -> None:
)
# setup domains (must do after all initialization)
self.domains._setup()
_a = 1

# Initialise config.
# The old config is self.config, restored from the pickled environment.
Expand Down
9 changes: 5 additions & 4 deletions sphinx/testing/restructuredtext.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,26 @@

def parse(app: Sphinx, text: str, docname: str = 'index') -> nodes.document:
"""Parse a string as reStructuredText with Sphinx application."""
env = app.env
try:
app.env.temp_data['docname'] = docname
env.temp_data['docname'] = docname
reader = SphinxStandaloneReader()
reader.setup(app)
parser = RSTParser()
parser.set_application(app)
with sphinx_domains(app.env):
with sphinx_domains(domains=env.domains, temp_data=env.temp_data):
return publish_doctree(
text,
str(app.srcdir / f'{docname}.rst'),
reader=reader,
parser=parser,
settings_overrides={
'env': app.env,
'env': env,
'gettext_compact': True,
'input_encoding': 'utf-8',
'output_encoding': 'unicode',
'traceback': True,
},
)
finally:
app.env.temp_data.pop('docname', None)
env.temp_data.pop('docname', None)
82 changes: 46 additions & 36 deletions sphinx/util/docutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from docutils.utils import Reporter, unescape

from sphinx.errors import SphinxError
from sphinx.locale import _, __
from sphinx.locale import __
from sphinx.util import logging
from sphinx.util.parsing import nested_parse_to_nodes

Expand All @@ -37,6 +37,7 @@

from sphinx.builders import Builder
from sphinx.config import Config
from sphinx.domains import _DomainsContainer
from sphinx.environment import BuildEnvironment
from sphinx.util.typing import RoleFunction

Expand Down Expand Up @@ -262,52 +263,42 @@ class sphinx_domains(CustomReSTDispatcher):
markup takes precedence.
"""

def __init__(self, env: BuildEnvironment) -> None:
self.env = env
def __init__(
self, *, domains: _DomainsContainer, temp_data: dict[str, Any]
) -> None:
self.domains = domains
self.temp_data = temp_data
super().__init__()

def lookup_domain_element(self, type: str, name: str) -> Any:
"""Lookup a markup element (directive or role), given its name which can
be a full name (with domain).
"""
name = name.lower()
def directive(
self,
directive_name: str,
language_module: ModuleType,
document: nodes.document,
) -> tuple[type[Directive] | None, list[system_message]]:
domain_name, _, name = directive_name.lower().rpartition(':')
# explicit domain given?
if ':' in name:
domain_name, name = name.split(':', 1)
if domain_name in self.env.domains:
domain = self.env.get_domain(domain_name)
element = getattr(domain, type)(name)
if domain_name:
if domain_name in self.domains:
element = self.domains[domain_name].directive(name)
if element is not None:
return element, []
else:
logger.warning(
_('unknown directive or role name: %s:%s'), domain_name, name
)
logger.warning(__('unknown directive name: %s'), directive_name.lower())
# else look in the default domain
else:
def_domain = self.env.temp_data.get('default_domain')
if def_domain is not None:
element = getattr(def_domain, type)(name)
default_domain = self.temp_data.get('default_domain')
if default_domain is not None:
element = default_domain.directive(name)
if element is not None:
return element, []

# always look in the std domain
element = getattr(self.env.domains.standard_domain, type)(name)
element = self.domains.standard_domain.directive(name)
if element is not None:
return element, []

raise ElementLookupError

def directive(
self,
directive_name: str,
language_module: ModuleType,
document: nodes.document,
) -> tuple[type[Directive] | None, list[system_message]]:
try:
return self.lookup_domain_element('directive', directive_name)
except ElementLookupError:
return super().directive(directive_name, language_module, document)
return super().directive(directive_name, language_module, document)

def role(
self,
Expand All @@ -316,10 +307,29 @@ def role(
lineno: int,
reporter: Reporter,
) -> tuple[RoleFunction, list[system_message]]:
try:
return self.lookup_domain_element('role', role_name)
except ElementLookupError:
return super().role(role_name, language_module, lineno, reporter)
domain_name, _, name = role_name.lower().rpartition(':')
# explicit domain given?
if domain_name:
if domain_name in self.domains:
element = self.domains[domain_name].role(name)
if element is not None:
return element, []
else:
logger.warning(__('unknown role name: %s'), role_name.lower())
# else look in the default domain
else:
default_domain = self.temp_data.get('default_domain')
if default_domain is not None:
element = default_domain.role(name)
if element is not None:
return element, []

# always look in the std domain
element = self.domains.standard_domain.role(name)
if element is not None:
return element, []

return super().role(role_name, language_module, lineno, reporter)


class WarningStream:
Expand Down
7 changes: 4 additions & 3 deletions tests/test_directives/test_directive_object_description.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@


def _doctree_for_test(builder: Builder, docname: str) -> nodes.document:
builder.env.prepare_settings(docname)
env = builder.env
env.prepare_settings(docname)
publisher = create_publisher(builder.app, 'restructuredtext')
with sphinx_domains(builder.env):
publisher.set_source(source_path=str(builder.env.doc2path(docname)))
with sphinx_domains(domains=env.domains, temp_data=env.temp_data):
publisher.set_source(source_path=str(env.doc2path(docname)))
publisher.publish()
return publisher.document

Expand Down
5 changes: 3 additions & 2 deletions tests/test_markup/test_markup.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

@pytest.fixture
def settings(app):
env = app.builder.env
texescape.init() # otherwise done by the latex builder
with warnings.catch_warnings():
warnings.filterwarnings('ignore', category=DeprecationWarning)
Expand All @@ -35,10 +36,10 @@ def settings(app):
)
settings = optparser.get_default_values()
settings.smart_quotes = True
settings.env = app.builder.env
settings.env = env
settings.env.temp_data['docname'] = 'dummy'
settings.contentsname = 'dummy'
domain_context = sphinx_domains(settings.env)
domain_context = sphinx_domains(domains=env.domains, temp_data=env.temp_data)
domain_context.enable()
yield settings
domain_context.disable()
Expand Down

0 comments on commit d4a84e3

Please sign in to comment.