mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2026-11-02 20:30:30 -06:00
Merge pull request #7561 from tk0miya/7143_typing.final
Support @final decorator
This commit is contained in:
10 files changed
+255
-2
No files matched your search
@@ -0,0 +1,14 @@
|
||||
import typing
|
||||
from typing import final
|
||||
|
||||
|
||||
@typing.final
|
||||
class Class:
|
||||
"""docstring"""
|
||||
|
||||
@final
|
||||
def meth1(self):
|
||||
"""docstring"""
|
||||
|
||||
def meth2(self):
|
||||
"""docstring"""
|
||||
@@ -1691,3 +1691,36 @@ def test_cython():
|
||||
' Docstring.',
|
||||
'',
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.version_info < (3, 8),
|
||||
reason='typing.final is available since python3.8')
|
||||
@pytest.mark.usefixtures('setup_test')
|
||||
def test_final():
|
||||
options = {"members": None}
|
||||
actual = do_autodoc(app, 'module', 'target.final', options)
|
||||
assert list(actual) == [
|
||||
'',
|
||||
'.. py:module:: target.final',
|
||||
'',
|
||||
'',
|
||||
'.. py:class:: Class',
|
||||
' :module: target.final',
|
||||
' :final:',
|
||||
'',
|
||||
' docstring',
|
||||
'',
|
||||
'',
|
||||
' .. py:method:: Class.meth1()',
|
||||
' :module: target.final',
|
||||
' :final:',
|
||||
'',
|
||||
' docstring',
|
||||
'',
|
||||
'',
|
||||
' .. py:method:: Class.meth2()',
|
||||
' :module: target.final',
|
||||
'',
|
||||
' docstring',
|
||||
'',
|
||||
]
|
||||
+43
-1
@@ -499,6 +499,34 @@ def test_pyfunction(app):
|
||||
assert domain.objects['example.func2'] == ('index', 'example.func2', 'function')
|
||||
|
||||
|
||||
def test_pyclass_options(app):
|
||||
text = (".. py:class:: Class1\n"
|
||||
".. py:class:: Class2\n"
|
||||
" :final:\n")
|
||||
domain = app.env.get_domain('py')
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (addnodes.index,
|
||||
[desc, ([desc_signature, ([desc_annotation, "class "],
|
||||
[desc_name, "Class1"])],
|
||||
[desc_content, ()])],
|
||||
addnodes.index,
|
||||
[desc, ([desc_signature, ([desc_annotation, "final class "],
|
||||
[desc_name, "Class2"])],
|
||||
[desc_content, ()])]))
|
||||
|
||||
# class
|
||||
assert_node(doctree[0], addnodes.index,
|
||||
entries=[('single', 'Class1 (built-in class)', 'Class1', '', None)])
|
||||
assert 'Class1' in domain.objects
|
||||
assert domain.objects['Class1'] == ('index', 'Class1', 'class')
|
||||
|
||||
# :final:
|
||||
assert_node(doctree[2], addnodes.index,
|
||||
entries=[('single', 'Class2 (built-in class)', 'Class2', '', None)])
|
||||
assert 'Class2' in domain.objects
|
||||
assert domain.objects['Class2'] == ('index', 'Class2', 'class')
|
||||
|
||||
|
||||
def test_pymethod_options(app):
|
||||
text = (".. py:class:: Class\n"
|
||||
"\n"
|
||||
@@ -512,7 +540,9 @@ def test_pymethod_options(app):
|
||||
" .. py:method:: meth5\n"
|
||||
" :property:\n"
|
||||
" .. py:method:: meth6\n"
|
||||
" :abstractmethod:\n")
|
||||
" :abstractmethod:\n"
|
||||
" .. py:method:: meth7\n"
|
||||
" :final:\n")
|
||||
domain = app.env.get_domain('py')
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (addnodes.index,
|
||||
@@ -529,6 +559,8 @@ def test_pymethod_options(app):
|
||||
addnodes.index,
|
||||
desc,
|
||||
addnodes.index,
|
||||
desc,
|
||||
addnodes.index,
|
||||
desc)])]))
|
||||
|
||||
# method
|
||||
@@ -589,6 +621,16 @@ def test_pymethod_options(app):
|
||||
assert 'Class.meth6' in domain.objects
|
||||
assert domain.objects['Class.meth6'] == ('index', 'Class.meth6', 'method')
|
||||
|
||||
# :final:
|
||||
assert_node(doctree[1][1][12], addnodes.index,
|
||||
entries=[('single', 'meth7() (Class method)', 'Class.meth7', '', None)])
|
||||
assert_node(doctree[1][1][13], ([desc_signature, ([desc_annotation, "final "],
|
||||
[desc_name, "meth7"],
|
||||
[desc_parameterlist, ()])],
|
||||
[desc_content, ()]))
|
||||
assert 'Class.meth7' in domain.objects
|
||||
assert domain.objects['Class.meth7'] == ('index', 'Class.meth7', 'method')
|
||||
|
||||
|
||||
def test_pyclassmethod(app):
|
||||
text = (".. py:class:: Class\n"
|
||||
|
||||
@@ -374,3 +374,81 @@ def test_formfeed_char():
|
||||
parser = Parser(source)
|
||||
parser.parse()
|
||||
assert parser.comments == {('Foo', 'attr'): 'comment'}
|
||||
|
||||
|
||||
def test_typing_final():
|
||||
source = ('import typing\n'
|
||||
'\n'
|
||||
'@typing.final\n'
|
||||
'def func(): pass\n'
|
||||
'\n'
|
||||
'@typing.final\n'
|
||||
'class Foo:\n'
|
||||
' @typing.final\n'
|
||||
' def meth(self):\n'
|
||||
' pass\n')
|
||||
parser = Parser(source)
|
||||
parser.parse()
|
||||
assert parser.finals == ['func', 'Foo', 'Foo.meth']
|
||||
|
||||
|
||||
def test_typing_final_from_import():
|
||||
source = ('from typing import final\n'
|
||||
'\n'
|
||||
'@final\n'
|
||||
'def func(): pass\n'
|
||||
'\n'
|
||||
'@final\n'
|
||||
'class Foo:\n'
|
||||
' @final\n'
|
||||
' def meth(self):\n'
|
||||
' pass\n')
|
||||
parser = Parser(source)
|
||||
parser.parse()
|
||||
assert parser.finals == ['func', 'Foo', 'Foo.meth']
|
||||
|
||||
|
||||
def test_typing_final_import_as():
|
||||
source = ('import typing as foo\n'
|
||||
'\n'
|
||||
'@foo.final\n'
|
||||
'def func(): pass\n'
|
||||
'\n'
|
||||
'@foo.final\n'
|
||||
'class Foo:\n'
|
||||
' @typing.final\n'
|
||||
' def meth(self):\n'
|
||||
' pass\n')
|
||||
parser = Parser(source)
|
||||
parser.parse()
|
||||
assert parser.finals == ['func', 'Foo']
|
||||
|
||||
|
||||
def test_typing_final_from_import_as():
|
||||
source = ('from typing import final as bar\n'
|
||||
'\n'
|
||||
'@bar\n'
|
||||
'def func(): pass\n'
|
||||
'\n'
|
||||
'@bar\n'
|
||||
'class Foo:\n'
|
||||
' @final\n'
|
||||
' def meth(self):\n'
|
||||
' pass\n')
|
||||
parser = Parser(source)
|
||||
parser.parse()
|
||||
assert parser.finals == ['func', 'Foo']
|
||||
|
||||
|
||||
def test_typing_final_not_imported():
|
||||
source = ('@typing.final\n'
|
||||
'def func(): pass\n'
|
||||
'\n'
|
||||
'@typing.final\n'
|
||||
'class Foo:\n'
|
||||
' @final\n'
|
||||
' def meth(self):\n'
|
||||
' pass\n')
|
||||
parser = Parser(source)
|
||||
parser.parse()
|
||||
assert parser.finals == []
|
||||
Reference in new issue
Block a user