From e5dad73cf231b014f6f6146387f271e1551d04b4 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Tue, 31 Mar 2020 00:16:20 +0900 Subject: py domain: Add :canonical: option --- tests/test_domain_py.py | 63 +++++++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 23 deletions(-) (limited to 'tests/test_domain_py.py') diff --git a/tests/test_domain_py.py b/tests/test_domain_py.py index 5a1d73cfe..6f91323a6 100644 --- a/tests/test_domain_py.py +++ b/tests/test_domain_py.py @@ -192,20 +192,22 @@ def test_domain_py_find_obj(app, status, warning): assert (find_obj(None, None, 'NONEXISTANT', 'class') == []) assert (find_obj(None, None, 'NestedParentA', 'class') == - [('NestedParentA', ('roles', 'NestedParentA', 'class'))]) + [('NestedParentA', ('roles', 'NestedParentA', 'class', False))]) assert (find_obj(None, None, 'NestedParentA.NestedChildA', 'class') == - [('NestedParentA.NestedChildA', ('roles', 'NestedParentA.NestedChildA', 'class'))]) + [('NestedParentA.NestedChildA', + ('roles', 'NestedParentA.NestedChildA', 'class', False))]) assert (find_obj(None, 'NestedParentA', 'NestedChildA', 'class') == - [('NestedParentA.NestedChildA', ('roles', 'NestedParentA.NestedChildA', 'class'))]) + [('NestedParentA.NestedChildA', + ('roles', 'NestedParentA.NestedChildA', 'class', False))]) assert (find_obj(None, None, 'NestedParentA.NestedChildA.subchild_1', 'meth') == [('NestedParentA.NestedChildA.subchild_1', - ('roles', 'NestedParentA.NestedChildA.subchild_1', 'method'))]) + ('roles', 'NestedParentA.NestedChildA.subchild_1', 'method', False))]) assert (find_obj(None, 'NestedParentA', 'NestedChildA.subchild_1', 'meth') == [('NestedParentA.NestedChildA.subchild_1', - ('roles', 'NestedParentA.NestedChildA.subchild_1', 'method'))]) + ('roles', 'NestedParentA.NestedChildA.subchild_1', 'method', False))]) assert (find_obj(None, 'NestedParentA.NestedChildA', 'subchild_1', 'meth') == [('NestedParentA.NestedChildA.subchild_1', - ('roles', 'NestedParentA.NestedChildA.subchild_1', 'method'))]) + ('roles', 'NestedParentA.NestedChildA.subchild_1', 'method', False))]) def test_get_full_qualified_name(): @@ -464,7 +466,7 @@ def test_pydata(app): [desc, ([desc_signature, desc_name, "var"], [desc_content, ()])])) assert 'var' in domain.objects - assert domain.objects['var'] == ('index', 'var', 'data') + assert domain.objects['var'] == ('index', 'var', 'data', False) def test_pyfunction(app): @@ -494,9 +496,9 @@ def test_pyfunction(app): entries=[('single', 'func2() (in module example)', 'example.func2', '', None)]) assert 'func1' in domain.objects - assert domain.objects['func1'] == ('index', 'func1', 'function') + assert domain.objects['func1'] == ('index', 'func1', 'function', False) assert 'example.func2' in domain.objects - assert domain.objects['example.func2'] == ('index', 'example.func2', 'function') + assert domain.objects['example.func2'] == ('index', 'example.func2', 'function', False) def test_pyclass_options(app): @@ -518,13 +520,13 @@ def test_pyclass_options(app): 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') + assert domain.objects['Class1'] == ('index', 'Class1', 'class', False) # :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') + assert domain.objects['Class2'] == ('index', 'Class2', 'class', False) def test_pymethod_options(app): @@ -570,7 +572,7 @@ def test_pymethod_options(app): [desc_parameterlist, ()])], [desc_content, ()])) assert 'Class.meth1' in domain.objects - assert domain.objects['Class.meth1'] == ('index', 'Class.meth1', 'method') + assert domain.objects['Class.meth1'] == ('index', 'Class.meth1', 'method', False) # :classmethod: assert_node(doctree[1][1][2], addnodes.index, @@ -580,7 +582,7 @@ def test_pymethod_options(app): [desc_parameterlist, ()])], [desc_content, ()])) assert 'Class.meth2' in domain.objects - assert domain.objects['Class.meth2'] == ('index', 'Class.meth2', 'method') + assert domain.objects['Class.meth2'] == ('index', 'Class.meth2', 'method', False) # :staticmethod: assert_node(doctree[1][1][4], addnodes.index, @@ -590,7 +592,7 @@ def test_pymethod_options(app): [desc_parameterlist, ()])], [desc_content, ()])) assert 'Class.meth3' in domain.objects - assert domain.objects['Class.meth3'] == ('index', 'Class.meth3', 'method') + assert domain.objects['Class.meth3'] == ('index', 'Class.meth3', 'method', False) # :async: assert_node(doctree[1][1][6], addnodes.index, @@ -600,7 +602,7 @@ def test_pymethod_options(app): [desc_parameterlist, ()])], [desc_content, ()])) assert 'Class.meth4' in domain.objects - assert domain.objects['Class.meth4'] == ('index', 'Class.meth4', 'method') + assert domain.objects['Class.meth4'] == ('index', 'Class.meth4', 'method', False) # :property: assert_node(doctree[1][1][8], addnodes.index, @@ -609,7 +611,7 @@ def test_pymethod_options(app): [desc_name, "meth5"])], [desc_content, ()])) assert 'Class.meth5' in domain.objects - assert domain.objects['Class.meth5'] == ('index', 'Class.meth5', 'method') + assert domain.objects['Class.meth5'] == ('index', 'Class.meth5', 'method', False) # :abstractmethod: assert_node(doctree[1][1][10], addnodes.index, @@ -619,7 +621,7 @@ def test_pymethod_options(app): [desc_parameterlist, ()])], [desc_content, ()])) assert 'Class.meth6' in domain.objects - assert domain.objects['Class.meth6'] == ('index', 'Class.meth6', 'method') + assert domain.objects['Class.meth6'] == ('index', 'Class.meth6', 'method', False) # :final: assert_node(doctree[1][1][12], addnodes.index, @@ -629,7 +631,7 @@ def test_pymethod_options(app): [desc_parameterlist, ()])], [desc_content, ()])) assert 'Class.meth7' in domain.objects - assert domain.objects['Class.meth7'] == ('index', 'Class.meth7', 'method') + assert domain.objects['Class.meth7'] == ('index', 'Class.meth7', 'method', False) def test_pyclassmethod(app): @@ -650,7 +652,7 @@ def test_pyclassmethod(app): [desc_parameterlist, ()])], [desc_content, ()])) assert 'Class.meth' in domain.objects - assert domain.objects['Class.meth'] == ('index', 'Class.meth', 'method') + assert domain.objects['Class.meth'] == ('index', 'Class.meth', 'method', False) def test_pystaticmethod(app): @@ -671,7 +673,7 @@ def test_pystaticmethod(app): [desc_parameterlist, ()])], [desc_content, ()])) assert 'Class.meth' in domain.objects - assert domain.objects['Class.meth'] == ('index', 'Class.meth', 'method') + assert domain.objects['Class.meth'] == ('index', 'Class.meth', 'method', False) def test_pyattribute(app): @@ -694,7 +696,7 @@ def test_pyattribute(app): [desc_annotation, " = ''"])], [desc_content, ()])) assert 'Class.attr' in domain.objects - assert domain.objects['Class.attr'] == ('index', 'Class.attr', 'attribute') + assert domain.objects['Class.attr'] == ('index', 'Class.attr', 'attribute', False) def test_pydecorator_signature(app): @@ -709,7 +711,7 @@ def test_pydecorator_signature(app): domain="py", objtype="function", noindex=False) assert 'deco' in domain.objects - assert domain.objects['deco'] == ('index', 'deco', 'function') + assert domain.objects['deco'] == ('index', 'deco', 'function', False) def test_pydecoratormethod_signature(app): @@ -724,7 +726,22 @@ def test_pydecoratormethod_signature(app): domain="py", objtype="method", noindex=False) assert 'deco' in domain.objects - assert domain.objects['deco'] == ('index', 'deco', 'method') + assert domain.objects['deco'] == ('index', 'deco', 'method', False) + + +def test_canonical(app): + text = (".. py:class:: io.StringIO\n" + " :canonical: _io.StringIO") + domain = app.env.get_domain('py') + doctree = restructuredtext.parse(app, text) + assert_node(doctree, (addnodes.index, + [desc, ([desc_signature, ([desc_annotation, "class "], + [desc_addname, "io."], + [desc_name, "StringIO"])], + desc_content)])) + assert 'io.StringIO' in domain.objects + assert domain.objects['io.StringIO'] == ('index', 'io.StringIO', 'class', False) + assert domain.objects['_io.StringIO'] == ('index', 'io.StringIO', 'class', True) @pytest.mark.sphinx(freshenv=True) -- cgit v1.2.1 From 9cac2001f789a095101b8834ce09fcbb02e741e2 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 1 Jan 2021 18:14:43 +0900 Subject: test: py domain: Add a testcase for :var: field --- tests/test_domain_py.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'tests/test_domain_py.py') diff --git a/tests/test_domain_py.py b/tests/test_domain_py.py index e0c690518..14e933448 100644 --- a/tests/test_domain_py.py +++ b/tests/test_domain_py.py @@ -838,6 +838,32 @@ def test_info_field_list(app): **{"py:module": "example", "py:class": "Class"}) +def test_info_field_list_var(app): + text = (".. py:class:: Class\n" + "\n" + " :var int attr: blah blah\n") + doctree = restructuredtext.parse(app, text) + + assert_node(doctree, (addnodes.index, + [desc, (desc_signature, + [desc_content, nodes.field_list, nodes.field])])) + assert_node(doctree[1][1][0][0], ([nodes.field_name, "Variables"], + [nodes.field_body, nodes.paragraph])) + + # :var int attr: + assert_node(doctree[1][1][0][0][1][0], + ([pending_xref, addnodes.literal_strong, "attr"], + " (", + [pending_xref, addnodes.literal_emphasis, "int"], + ")", + " -- ", + "blah blah")) + assert_node(doctree[1][1][0][0][1][0][0], pending_xref, + refdomain="py", reftype="obj", reftarget="attr", **{"py:class": "Class"}) + assert_node(doctree[1][1][0][0][1][0][2], pending_xref, + refdomain="py", reftype="class", reftarget="int", **{"py:class": "Class"}) + + @pytest.mark.sphinx(freshenv=True) def test_module_index(app): text = (".. py:module:: docutils\n" -- cgit v1.2.1 From 918086b5590763663c1627578085e528f1358384 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 1 Jan 2021 19:51:59 +0900 Subject: Close #5977: :var: field do not create a cross-reference Since its beginning, `:var:` field has created a cross-reference to the attribute having the same name. It is meaningful only if the attribute is documented by `py:attribute` directive. It means the `:var:` field and `:attr:` role are almost the same and conflicted. Additionally, the cross-reference points incorrect variable if the target is not documented. Thus, the cross-reference feature of `:var:` field is disabled. --- tests/test_domain_py.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'tests/test_domain_py.py') diff --git a/tests/test_domain_py.py b/tests/test_domain_py.py index 14e933448..537bae15b 100644 --- a/tests/test_domain_py.py +++ b/tests/test_domain_py.py @@ -852,14 +852,12 @@ def test_info_field_list_var(app): # :var int attr: assert_node(doctree[1][1][0][0][1][0], - ([pending_xref, addnodes.literal_strong, "attr"], + ([addnodes.literal_strong, "attr"], " (", [pending_xref, addnodes.literal_emphasis, "int"], ")", " -- ", "blah blah")) - assert_node(doctree[1][1][0][0][1][0][0], pending_xref, - refdomain="py", reftype="obj", reftarget="attr", **{"py:class": "Class"}) assert_node(doctree[1][1][0][0][1][0][2], pending_xref, refdomain="py", reftype="class", reftarget="int", **{"py:class": "Class"}) -- cgit v1.2.1 From 930a880294dc935a7320d64ecbe219c18e005536 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 15 Nov 2020 23:15:01 +0900 Subject: Fix #7199: py domain: Add a new confval: python_use_unqualified_type_names Add a new config variable: python_use_unqualified_type_names. If enabled, it goes to suppress the module name of the python reference if it can be resolved. --- tests/test_domain_py.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'tests/test_domain_py.py') diff --git a/tests/test_domain_py.py b/tests/test_domain_py.py index 448c2c954..03e865e84 100644 --- a/tests/test_domain_py.py +++ b/tests/test_domain_py.py @@ -999,6 +999,25 @@ def test_noindexentry(app): assert_node(doctree[2], addnodes.index, entries=[]) +@pytest.mark.sphinx('html', testroot='domain-py-python_use_unqualified_type_names') +def test_python_python_use_unqualified_type_names(app, status, warning): + app.build() + content = (app.outdir / 'index.html').read_text() + assert ('' + 'Name' in content) + assert 'foo.Age' in content + + +@pytest.mark.sphinx('html', testroot='domain-py-python_use_unqualified_type_names', + confoverrides={'python_use_unqualified_type_names': False}) +def test_python_python_use_unqualified_type_names_disabled(app, status, warning): + app.build() + content = (app.outdir / 'index.html').read_text() + assert ('' + 'foo.Name' in content) + assert 'foo.Age' in content + + @pytest.mark.sphinx('dummy', testroot='domain-py-xref-warning') def test_warn_missing_reference(app, status, warning): app.build() -- cgit v1.2.1 From 204f86f736ae59b7f2a26ef31ba48f8165fcd10e Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Thu, 12 Mar 2020 00:54:39 +0900 Subject: py domain: Add py:property directive to describe a property (refs: #7068) --- tests/test_domain_py.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'tests/test_domain_py.py') diff --git a/tests/test_domain_py.py b/tests/test_domain_py.py index 03e865e84..f5df9084b 100644 --- a/tests/test_domain_py.py +++ b/tests/test_domain_py.py @@ -201,6 +201,10 @@ def test_resolve_xref_for_properties(app, status, warning): ' title="module_a.submodule.ModTopLevel.prop">' '' 'prop method' in content) + assert ('Link to ' + '' + 'prop attribute' in content) @pytest.mark.sphinx('dummy', testroot='domain-py') @@ -798,6 +802,29 @@ def test_pyattribute(app): assert domain.objects['Class.attr'] == ('index', 'Class.attr', 'attribute', False) +def test_pyproperty(app): + text = (".. py:class:: Class\n" + "\n" + " .. py:property:: prop\n" + " :abstractmethod:\n" + " :type: str\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, "Class"])], + [desc_content, (addnodes.index, + desc)])])) + assert_node(doctree[1][1][0], addnodes.index, + entries=[('single', 'prop (Class property)', 'Class.prop', '', None)]) + assert_node(doctree[1][1][1], ([desc_signature, ([desc_annotation, "abstract property "], + [desc_name, "prop"], + [desc_annotation, ": str"])], + [desc_content, ()])) + assert 'Class.prop' in domain.objects + assert domain.objects['Class.prop'] == ('index', 'Class.prop', 'property', False) + + def test_pydecorator_signature(app): text = ".. py:decorator:: deco" domain = app.env.get_domain('py') -- cgit v1.2.1