mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2026-10-14 01:12:10 -05:00
Split autodoc name parsing utilities to a new module (#14033)
This commit is contained in:
1 parent
6de23cd95e
commit
4d2bd1e862
6 files changed
+286
-231
No files matched your search
@@ -25,6 +25,7 @@ from sphinx.ext.autodoc._directive_options import (
|
||||
)
|
||||
from sphinx.ext.autodoc._event_listeners import between, cut_lines
|
||||
from sphinx.ext.autodoc._member_finder import ObjectMember, special_member_re
|
||||
from sphinx.ext.autodoc._names import py_ext_sig_re
|
||||
from sphinx.ext.autodoc._sentinels import ALL, EMPTY, SUPPRESS, UNINITIALIZED_ATTR
|
||||
from sphinx.ext.autodoc._sentinels import (
|
||||
INSTANCE_ATTR as INSTANCEATTR,
|
||||
@@ -33,7 +34,6 @@ from sphinx.ext.autodoc._sentinels import (
|
||||
SLOTS_ATTR as SLOTSATTR,
|
||||
)
|
||||
from sphinx.ext.autodoc.directive import AutodocDirective
|
||||
from sphinx.ext.autodoc.importer import py_ext_sig_re
|
||||
from sphinx.ext.autodoc.typehints import _merge_typehints
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
"""Importer utilities for autodoc"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from sphinx.locale import __
|
||||
from sphinx.util import logging
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Mapping, Sequence
|
||||
|
||||
from sphinx.environment import _CurrentDocument
|
||||
from sphinx.ext.autodoc._property_types import _AutodocObjType
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
#: extended signature RE: with explicit module name separated by ::
|
||||
py_ext_sig_re = re.compile(
|
||||
r"""^ ([\w.]+::)? # explicit module name
|
||||
([\w.]+\.)? # module and/or class name(s)
|
||||
(\w+) \s* # thing name
|
||||
(?: \[\s*(.*?)\s*])? # optional: type parameters list
|
||||
(?: \((.*)\) # optional: arguments
|
||||
(?:\s* -> \s* (.*))? # return annotation
|
||||
)? $ # and nothing more
|
||||
""",
|
||||
re.VERBOSE,
|
||||
)
|
||||
|
||||
|
||||
def _parse_name(
|
||||
*,
|
||||
name: str,
|
||||
objtype: _AutodocObjType,
|
||||
current_document: _CurrentDocument,
|
||||
ref_context: Mapping[str, str | None],
|
||||
) -> tuple[str, tuple[str, ...], str | None, str | None] | None:
|
||||
"""Parse *name* into module name, path, arguments, and return annotation."""
|
||||
# Parse the definition in *name*.
|
||||
# autodoc directives for classes and functions can contain a signature,
|
||||
# which overrides the autogenerated one.
|
||||
matched = py_ext_sig_re.match(name)
|
||||
if matched is None:
|
||||
logger.warning(
|
||||
__('invalid signature for auto%s (%r)'),
|
||||
objtype,
|
||||
name,
|
||||
type='autodoc',
|
||||
)
|
||||
# need a module to import
|
||||
logger.warning(
|
||||
__(
|
||||
"don't know which module to import for autodocumenting "
|
||||
'%r (try placing a "module" or "currentmodule" directive '
|
||||
'in the document, or giving an explicit module name)'
|
||||
),
|
||||
name,
|
||||
type='autodoc',
|
||||
)
|
||||
return None
|
||||
|
||||
explicit_modname, path, base, _tp_list, args, retann = matched.groups()
|
||||
if args is not None:
|
||||
args = f'({args})'
|
||||
|
||||
# Support explicit module and class name separation via ``::``
|
||||
if explicit_modname is not None:
|
||||
module_name = explicit_modname.removesuffix('::')
|
||||
parents = path.rstrip('.').split('.') if path else ()
|
||||
else:
|
||||
module_name = None
|
||||
parents = ()
|
||||
|
||||
resolved = _resolve_name(
|
||||
objtype=objtype,
|
||||
module_name=module_name,
|
||||
path=path,
|
||||
base=base,
|
||||
parents=parents,
|
||||
current_document=current_document,
|
||||
ref_context_py_module=ref_context.get('py:module'),
|
||||
ref_context_py_class=ref_context.get('py:class', ''), # type: ignore[arg-type]
|
||||
)
|
||||
if resolved is None:
|
||||
return None
|
||||
module_name, parts = resolved
|
||||
|
||||
if objtype == 'module' and args:
|
||||
msg = __("signature arguments given for automodule: '%s'")
|
||||
logger.warning(msg, name, type='autodoc')
|
||||
return None
|
||||
if objtype == 'module' and retann:
|
||||
msg = __("return annotation given for automodule: '%s'")
|
||||
logger.warning(msg, name, type='autodoc')
|
||||
return None
|
||||
|
||||
if not module_name:
|
||||
# Could not resolve a module to import
|
||||
logger.warning(
|
||||
__(
|
||||
"don't know which module to import for autodocumenting "
|
||||
'%r (try placing a "module" or "currentmodule" directive '
|
||||
'in the document, or giving an explicit module name)'
|
||||
),
|
||||
name,
|
||||
type='autodoc',
|
||||
)
|
||||
return None
|
||||
|
||||
return module_name, parts, args, retann
|
||||
|
||||
|
||||
def _resolve_name(
|
||||
*,
|
||||
objtype: _AutodocObjType,
|
||||
module_name: str | None,
|
||||
path: str | None,
|
||||
base: str,
|
||||
parents: Sequence[str],
|
||||
current_document: _CurrentDocument,
|
||||
ref_context_py_module: str | None,
|
||||
ref_context_py_class: str,
|
||||
) -> tuple[str | None, tuple[str, ...]] | None:
|
||||
"""Resolve the module and name of the object to document given by the
|
||||
arguments and the current module/class.
|
||||
|
||||
Must return a pair of the module name and a chain of attributes; for
|
||||
example, it would return ``('zipfile', ('ZipFile', 'open'))`` for the
|
||||
``zipfile.ZipFile.open`` method.
|
||||
"""
|
||||
if objtype == 'module':
|
||||
if module_name is not None:
|
||||
logger.warning(
|
||||
__('"::" in automodule name doesn\'t make sense'), type='autodoc'
|
||||
)
|
||||
return (path or '') + base, ()
|
||||
|
||||
if objtype in {'class', 'exception', 'function', 'decorator', 'data', 'type'}:
|
||||
if module_name is not None:
|
||||
return module_name, (*parents, base)
|
||||
if path:
|
||||
module_name = path.rstrip('.')
|
||||
return module_name, (*parents, base)
|
||||
|
||||
# if documenting a toplevel object without explicit module,
|
||||
# it can be contained in another auto directive ...
|
||||
module_name = current_document.autodoc_module
|
||||
# ... or in the scope of a module directive
|
||||
if not module_name:
|
||||
module_name = ref_context_py_module
|
||||
# ... else, it stays None, which means invalid
|
||||
return module_name, (*parents, base)
|
||||
|
||||
if objtype in {'method', 'property', 'attribute'}:
|
||||
if module_name is not None:
|
||||
return module_name, (*parents, base)
|
||||
|
||||
if path:
|
||||
mod_cls = path.rstrip('.')
|
||||
else:
|
||||
# if documenting a class-level object without path,
|
||||
# there must be a current class, either from a parent
|
||||
# auto directive ...
|
||||
mod_cls = current_document.autodoc_class
|
||||
# ... or from a class directive
|
||||
if not mod_cls:
|
||||
mod_cls = ref_context_py_class
|
||||
# ... if still falsy, there's no way to know
|
||||
if not mod_cls:
|
||||
return None, ()
|
||||
module_name, _sep, cls = mod_cls.rpartition('.')
|
||||
parents = [cls]
|
||||
# if the module name is still missing, get it like above
|
||||
if not module_name:
|
||||
module_name = current_document.autodoc_module
|
||||
if not module_name:
|
||||
module_name = ref_context_py_module
|
||||
# ... else, it stays None, which means invalid
|
||||
return module_name, (*parents, base)
|
||||
|
||||
return None
|
||||
@@ -7,6 +7,7 @@ from inspect import Parameter, Signature
|
||||
from typing import TYPE_CHECKING, NewType, TypeVar
|
||||
|
||||
from sphinx.errors import PycodeError
|
||||
from sphinx.ext.autodoc._names import py_ext_sig_re
|
||||
from sphinx.ext.autodoc._property_types import _AssignStatementProperties
|
||||
from sphinx.ext.autodoc.preserve_defaults import update_default_value
|
||||
from sphinx.ext.autodoc.type_comment import _update_annotations_using_type_comments
|
||||
@@ -336,8 +337,6 @@ def _extract_signatures_from_docstrings(
|
||||
props: _ItemProperties,
|
||||
tab_width: int,
|
||||
) -> list[_FormattedSignature]:
|
||||
from sphinx.ext.autodoc.importer import py_ext_sig_re
|
||||
|
||||
signatures: list[_FormattedSignature] = []
|
||||
|
||||
# candidates of the object name
|
||||
|
||||
@@ -23,6 +23,7 @@ from sphinx.ext.autodoc._docstrings import (
|
||||
_docstring_lines_for_props,
|
||||
_get_docstring_lines,
|
||||
)
|
||||
from sphinx.ext.autodoc._names import _parse_name
|
||||
from sphinx.ext.autodoc._property_types import (
|
||||
_AssignStatementProperties,
|
||||
_ClassDefProperties,
|
||||
@@ -68,19 +69,6 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
_hide_value_re = re.compile(r'^:meta \s*hide-value:( +|$)')
|
||||
|
||||
#: extended signature RE: with explicit module name separated by ::
|
||||
py_ext_sig_re = re.compile(
|
||||
r"""^ ([\w.]+::)? # explicit module name
|
||||
([\w.]+\.)? # module and/or class name(s)
|
||||
(\w+) \s* # thing name
|
||||
(?: \[\s*(.*?)\s*])? # optional: type parameters list
|
||||
(?: \((.*)\) # optional: arguments
|
||||
(?:\s* -> \s* (.*))? # return annotation
|
||||
)? $ # and nothing more
|
||||
""",
|
||||
re.VERBOSE,
|
||||
)
|
||||
|
||||
|
||||
class _ImportedObject:
|
||||
#: module containing the object to document
|
||||
@@ -933,160 +921,6 @@ def _load_object_by_name(
|
||||
return props
|
||||
|
||||
|
||||
def _parse_name(
|
||||
*,
|
||||
name: str,
|
||||
objtype: _AutodocObjType,
|
||||
current_document: _CurrentDocument,
|
||||
ref_context: Mapping[str, str | None],
|
||||
) -> tuple[str, tuple[str, ...], str | None, str | None] | None:
|
||||
"""Parse *name* into module name, path, arguments, and return annotation."""
|
||||
# Parse the definition in *name*.
|
||||
# autodoc directives for classes and functions can contain a signature,
|
||||
# which overrides the autogenerated one.
|
||||
matched = py_ext_sig_re.match(name)
|
||||
if matched is None:
|
||||
logger.warning(
|
||||
__('invalid signature for auto%s (%r)'),
|
||||
objtype,
|
||||
name,
|
||||
type='autodoc',
|
||||
)
|
||||
# need a module to import
|
||||
logger.warning(
|
||||
__(
|
||||
"don't know which module to import for autodocumenting "
|
||||
'%r (try placing a "module" or "currentmodule" directive '
|
||||
'in the document, or giving an explicit module name)'
|
||||
),
|
||||
name,
|
||||
type='autodoc',
|
||||
)
|
||||
return None
|
||||
|
||||
explicit_modname, path, base, _tp_list, args, retann = matched.groups()
|
||||
if args is not None:
|
||||
args = f'({args})'
|
||||
|
||||
# Support explicit module and class name separation via ``::``
|
||||
if explicit_modname is not None:
|
||||
module_name = explicit_modname.removesuffix('::')
|
||||
parents = path.rstrip('.').split('.') if path else ()
|
||||
else:
|
||||
module_name = None
|
||||
parents = ()
|
||||
|
||||
resolved = _resolve_name(
|
||||
objtype=objtype,
|
||||
module_name=module_name,
|
||||
path=path,
|
||||
base=base,
|
||||
parents=parents,
|
||||
current_document=current_document,
|
||||
ref_context_py_module=ref_context.get('py:module'),
|
||||
ref_context_py_class=ref_context.get('py:class', ''), # type: ignore[arg-type]
|
||||
)
|
||||
if resolved is None:
|
||||
msg = 'must be implemented in subclasses'
|
||||
raise NotImplementedError(msg)
|
||||
module_name, parts = resolved
|
||||
|
||||
if objtype == 'module' and args:
|
||||
msg = __("signature arguments given for automodule: '%s'")
|
||||
logger.warning(msg, name, type='autodoc')
|
||||
return None
|
||||
if objtype == 'module' and retann:
|
||||
msg = __("return annotation given for automodule: '%s'")
|
||||
logger.warning(msg, name, type='autodoc')
|
||||
return None
|
||||
|
||||
if not module_name:
|
||||
# Could not resolve a module to import
|
||||
logger.warning(
|
||||
__(
|
||||
"don't know which module to import for autodocumenting "
|
||||
'%r (try placing a "module" or "currentmodule" directive '
|
||||
'in the document, or giving an explicit module name)'
|
||||
),
|
||||
name,
|
||||
type='autodoc',
|
||||
)
|
||||
return None
|
||||
|
||||
return module_name, parts, args, retann
|
||||
|
||||
|
||||
def _resolve_name(
|
||||
*,
|
||||
objtype: _AutodocObjType,
|
||||
module_name: str | None,
|
||||
path: str | None,
|
||||
base: str,
|
||||
parents: Sequence[str],
|
||||
current_document: _CurrentDocument,
|
||||
ref_context_py_module: str | None,
|
||||
ref_context_py_class: str,
|
||||
) -> tuple[str | None, tuple[str, ...]] | None:
|
||||
"""Resolve the module and name of the object to document given by the
|
||||
arguments and the current module/class.
|
||||
|
||||
Must return a pair of the module name and a chain of attributes; for
|
||||
example, it would return ``('zipfile', ('ZipFile', 'open'))`` for the
|
||||
``zipfile.ZipFile.open`` method.
|
||||
"""
|
||||
if objtype == 'module':
|
||||
if module_name is not None:
|
||||
logger.warning(
|
||||
__('"::" in automodule name doesn\'t make sense'), type='autodoc'
|
||||
)
|
||||
return (path or '') + base, ()
|
||||
|
||||
if objtype in {'class', 'exception', 'function', 'decorator', 'data', 'type'}:
|
||||
if module_name is not None:
|
||||
return module_name, (*parents, base)
|
||||
if path:
|
||||
module_name = path.rstrip('.')
|
||||
return module_name, (*parents, base)
|
||||
|
||||
# if documenting a toplevel object without explicit module,
|
||||
# it can be contained in another auto directive ...
|
||||
module_name = current_document.autodoc_module
|
||||
# ... or in the scope of a module directive
|
||||
if not module_name:
|
||||
module_name = ref_context_py_module
|
||||
# ... else, it stays None, which means invalid
|
||||
return module_name, (*parents, base)
|
||||
|
||||
if objtype in {'method', 'property', 'attribute'}:
|
||||
if module_name is not None:
|
||||
return module_name, (*parents, base)
|
||||
|
||||
if path:
|
||||
mod_cls = path.rstrip('.')
|
||||
else:
|
||||
# if documenting a class-level object without path,
|
||||
# there must be a current class, either from a parent
|
||||
# auto directive ...
|
||||
mod_cls = current_document.autodoc_class
|
||||
# ... or from a class directive
|
||||
if not mod_cls:
|
||||
mod_cls = ref_context_py_class
|
||||
# ... if still falsy, there's no way to know
|
||||
if not mod_cls:
|
||||
return None, ()
|
||||
module_name, _sep, cls = mod_cls.rpartition('.')
|
||||
parents = [cls]
|
||||
# if the module name is still missing, get it like above
|
||||
if not module_name:
|
||||
module_name = current_document.autodoc_module
|
||||
if not module_name:
|
||||
module_name = ref_context_py_module
|
||||
# ... else, it stays None, which means invalid
|
||||
return module_name, (*parents, base)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
_objects_with_type_comment_annotations: WeakSet[Any] = WeakSet()
|
||||
"""Cache of objects with annotations updated from type comments."""
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ source file translated by test_build.
|
||||
from __future__ import annotations
|
||||
|
||||
import itertools
|
||||
import logging
|
||||
import pathlib
|
||||
import sys
|
||||
from typing import TYPE_CHECKING
|
||||
@@ -17,7 +16,6 @@ import pytest
|
||||
from docutils.statemachine import StringList
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.environment import _CurrentDocument
|
||||
from sphinx.ext.autodoc._directive_options import (
|
||||
_AutoDocumenterOptions,
|
||||
inherited_members_option,
|
||||
@@ -28,7 +26,7 @@ from sphinx.ext.autodoc._generate import _generate_directives
|
||||
from sphinx.ext.autodoc._property_types import _ItemProperties
|
||||
from sphinx.ext.autodoc._sentinels import ALL
|
||||
from sphinx.ext.autodoc.directive import _AutodocAttrGetter
|
||||
from sphinx.ext.autodoc.importer import _load_object_by_name, _parse_name
|
||||
from sphinx.ext.autodoc.importer import _load_object_by_name
|
||||
from sphinx.util.inspect import safe_getattr
|
||||
|
||||
from tests.test_ext_autodoc.autodoc_util import do_autodoc
|
||||
@@ -48,64 +46,6 @@ if TYPE_CHECKING:
|
||||
processed_signatures: list[tuple[str, str]] = []
|
||||
|
||||
|
||||
def test_parse_name(caplog: pytest.LogCaptureFixture) -> None:
|
||||
# work around sphinx.util.logging.setup()
|
||||
logger = logging.getLogger('sphinx')
|
||||
logger.handlers[:] = [caplog.handler]
|
||||
|
||||
current_document = _CurrentDocument()
|
||||
ref_context: dict[str, Any] = {}
|
||||
|
||||
def parse(objtype, name):
|
||||
parsed = _parse_name(
|
||||
name=name,
|
||||
objtype=objtype,
|
||||
current_document=current_document,
|
||||
ref_context=ref_context,
|
||||
)
|
||||
if parsed is None:
|
||||
return None
|
||||
module_name, parts, args, retann = parsed
|
||||
return module_name, list(parts), args, retann
|
||||
|
||||
# for modules
|
||||
parsed = parse('module', 'test_ext_autodoc')
|
||||
assert parsed == ('test_ext_autodoc', [], None, None)
|
||||
parsed = parse('module', 'test.test_ext_autodoc')
|
||||
assert parsed == ('test.test_ext_autodoc', [], None, None)
|
||||
parsed = parse('module', 'test(arg)')
|
||||
assert parsed is None
|
||||
assert 'signature arguments given for automodule' in caplog.messages[0]
|
||||
|
||||
# for functions/classes
|
||||
parsed = parse('function', 'test_ext_autodoc.raises')
|
||||
assert parsed == ('test_ext_autodoc', ['raises'], None, None)
|
||||
parsed = parse('function', 'test_ext_autodoc.raises(exc) -> None')
|
||||
assert parsed == ('test_ext_autodoc', ['raises'], '(exc)', 'None')
|
||||
current_document.autodoc_module = 'test_ext_autodoc'
|
||||
parsed = parse('function', 'raises')
|
||||
assert parsed == ('test_ext_autodoc', ['raises'], None, None)
|
||||
current_document.autodoc_module = ''
|
||||
|
||||
ref_context['py:module'] = 'test_ext_autodoc'
|
||||
parsed = parse('function', 'raises')
|
||||
assert parsed == ('test_ext_autodoc', ['raises'], None, None)
|
||||
parsed = parse('class', 'Base')
|
||||
assert parsed == ('test_ext_autodoc', ['Base'], None, None)
|
||||
|
||||
# for members
|
||||
ref_context['py:module'] = 'sphinx.testing.util'
|
||||
parsed = parse('method', 'SphinxTestApp.cleanup')
|
||||
assert parsed == ('sphinx.testing.util', ['SphinxTestApp', 'cleanup'], None, None)
|
||||
ref_context['py:module'] = 'sphinx.testing.util'
|
||||
ref_context['py:class'] = 'Foo'
|
||||
current_document.autodoc_class = 'SphinxTestApp'
|
||||
parsed = parse('method', 'cleanup')
|
||||
assert parsed == ('sphinx.testing.util', ['SphinxTestApp', 'cleanup'], None, None)
|
||||
parsed = parse('method', 'SphinxTestApp.cleanup')
|
||||
assert parsed == ('sphinx.testing.util', ['SphinxTestApp', 'cleanup'], None, None)
|
||||
|
||||
|
||||
def get_docstring_lines(obj_type, obj, *, config):
|
||||
parent = object # dummy
|
||||
props = _ItemProperties(
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
"""Test the autodoc extension. This mainly tests name resolution & parsing."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from sphinx.environment import _CurrentDocument
|
||||
from sphinx.ext.autodoc._names import _parse_name
|
||||
|
||||
TYPE_CHECKING = False
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Mapping
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
|
||||
from sphinx.ext.autodoc._property_types import _AutodocObjType
|
||||
|
||||
|
||||
def parse_name(
|
||||
objtype: _AutodocObjType,
|
||||
name: str,
|
||||
*,
|
||||
current_document: _CurrentDocument | None = None,
|
||||
ref_context: Mapping[str, str | None] | None = None,
|
||||
) -> tuple[str, list[str], str | None, str | None] | None:
|
||||
if current_document is None:
|
||||
current_document = _CurrentDocument()
|
||||
if ref_context is None:
|
||||
ref_context = {}
|
||||
|
||||
parsed = _parse_name(
|
||||
name=name,
|
||||
objtype=objtype,
|
||||
current_document=current_document,
|
||||
ref_context=ref_context,
|
||||
)
|
||||
if parsed is None:
|
||||
return None
|
||||
module_name, parts, args, retann = parsed
|
||||
return module_name, list(parts), args, retann
|
||||
|
||||
|
||||
def test_parse_module_names(caplog: pytest.LogCaptureFixture) -> None:
|
||||
# work around sphinx.util.logging.setup()
|
||||
logger = logging.getLogger('sphinx')
|
||||
logger.handlers[:] = [caplog.handler]
|
||||
|
||||
parsed = parse_name('module', 'test_ext_autodoc')
|
||||
assert parsed == ('test_ext_autodoc', [], None, None)
|
||||
parsed = parse_name('module', 'test.test_ext_autodoc')
|
||||
assert parsed == ('test.test_ext_autodoc', [], None, None)
|
||||
parsed = parse_name('module', 'test(arg)')
|
||||
assert parsed is None
|
||||
assert 'signature arguments given for automodule' in caplog.messages[0]
|
||||
|
||||
|
||||
def test_parse_function_names() -> None:
|
||||
parsed = parse_name('function', 'test_ext_autodoc.raises')
|
||||
assert parsed == ('test_ext_autodoc', ['raises'], None, None)
|
||||
parsed = parse_name('function', 'test_ext_autodoc.raises(exc) -> None')
|
||||
assert parsed == ('test_ext_autodoc', ['raises'], '(exc)', 'None')
|
||||
|
||||
|
||||
def test_parse_function_names_current_document() -> None:
|
||||
current_document = _CurrentDocument()
|
||||
current_document.autodoc_module = 'test_ext_autodoc'
|
||||
parsed = parse_name('function', 'raises', current_document=current_document)
|
||||
assert parsed == ('test_ext_autodoc', ['raises'], None, None)
|
||||
|
||||
|
||||
def test_parse_function_names_ref_context() -> None:
|
||||
ref_context: dict[str, Any] = {'py:module': 'test_ext_autodoc'}
|
||||
parsed = parse_name('function', 'raises', ref_context=ref_context)
|
||||
assert parsed == ('test_ext_autodoc', ['raises'], None, None)
|
||||
parsed = parse_name('class', 'Base', ref_context=ref_context)
|
||||
assert parsed == ('test_ext_autodoc', ['Base'], None, None)
|
||||
|
||||
|
||||
def test_parse_name_members() -> None:
|
||||
# for members
|
||||
ref_context: dict[str, Any] = {'py:module': 'sphinx.testing.util'}
|
||||
parsed = parse_name('method', 'SphinxTestApp.cleanup', ref_context=ref_context)
|
||||
assert parsed == ('sphinx.testing.util', ['SphinxTestApp', 'cleanup'], None, None)
|
||||
|
||||
current_document = _CurrentDocument()
|
||||
current_document.autodoc_class = 'SphinxTestApp'
|
||||
ref_context['py:class'] = 'Foo'
|
||||
parsed = parse_name(
|
||||
'method', 'cleanup', current_document=current_document, ref_context=ref_context
|
||||
)
|
||||
assert parsed == ('sphinx.testing.util', ['SphinxTestApp', 'cleanup'], None, None)
|
||||
parsed = parse_name(
|
||||
'method',
|
||||
'SphinxTestApp.cleanup',
|
||||
current_document=current_document,
|
||||
ref_context=ref_context,
|
||||
)
|
||||
assert parsed == ('sphinx.testing.util', ['SphinxTestApp', 'cleanup'], None, None)
|
||||
Reference in new issue
Block a user