From 6d5e43a0ffc99830c91e37c026d89a6d70fe52c8 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 6 Nov 2020 01:36:04 +0900 Subject: [PATCH 1/3] Drop code for supporting py35 --- sphinx/domains/python.py | 12 ++++----- sphinx/pycode/parser.py | 9 ++----- tests/test_ext_autodoc.py | 37 +++++++++----------------- tests/test_ext_autodoc_autofunction.py | 27 +++++++------------ tests/test_pycode_parser.py | 3 +-- tests/test_util_inspect.py | 5 +--- 6 files changed, 32 insertions(+), 61 deletions(-) diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py index 03edce922c7..fb00b8dad2d 100644 --- a/sphinx/domains/python.py +++ b/sphinx/domains/python.py @@ -102,6 +102,11 @@ def _parse_annotation(annotation: str, env: BuildEnvironment = None) -> List[Nod def unparse(node: ast.AST) -> List[Node]: if isinstance(node, ast.Attribute): return [nodes.Text("%s.%s" % (unparse(node.value)[0], node.attr))] + elif isinstance(node, ast.Constant): # type: ignore + if node.value is Ellipsis: + return [addnodes.desc_sig_punctuation('', "...")] + else: + return [nodes.Text(node.value)] elif isinstance(node, ast.Expr): return unparse(node.value) elif isinstance(node, ast.Index): @@ -137,13 +142,6 @@ def unparse(node: ast.AST) -> List[Node]: return result else: - if sys.version_info >= (3, 6): - if isinstance(node, ast.Constant): # type: ignore - if node.value is Ellipsis: - return [addnodes.desc_sig_punctuation('', "...")] - else: - return [nodes.Text(node.value)] - if sys.version_info < (3, 8): if isinstance(node, ast.Ellipsis): return [addnodes.desc_sig_punctuation('', "...")] diff --git a/sphinx/pycode/parser.py b/sphinx/pycode/parser.py index a417b5a1b26..78715f7777f 100644 --- a/sphinx/pycode/parser.py +++ b/sphinx/pycode/parser.py @@ -27,12 +27,6 @@ emptyline_re = re.compile('^\\s*(#.*)?$') -if sys.version_info >= (3, 6): - ASSIGN_NODES = (ast.Assign, ast.AnnAssign) -else: - ASSIGN_NODES = (ast.Assign) - - def filter_whitespace(code: str) -> str: return code.replace('\f', ' ') # replace FF (form feed) with whitespace @@ -408,7 +402,8 @@ def visit_AnnAssign(self, node: ast.AnnAssign) -> None: def visit_Expr(self, node: ast.Expr) -> None: """Handles Expr node and pick up a comment if string.""" - if (isinstance(self.previous, ASSIGN_NODES) and isinstance(node.value, ast.Str)): + if (isinstance(self.previous, (ast.Assign, ast.AnnAssign)) and + isinstance(node.value, ast.Str)): try: targets = get_assign_targets(self.previous) varnames = get_lvar_names(targets[0], self.get_self()) diff --git a/tests/test_ext_autodoc.py b/tests/test_ext_autodoc.py index 703cc13f6a8..bc3d07660dd 100644 --- a/tests/test_ext_autodoc.py +++ b/tests/test_ext_autodoc.py @@ -290,7 +290,6 @@ def foo3(self, d='\n'): '(b, c=42, *d, **e)' -@pytest.mark.skipif(sys.version_info < (3, 5), reason='typing is available since python3.5.') @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_autodoc_process_signature_typing_generic(app): actual = do_autodoc(app, 'class', 'target.generic_class.A', {}) @@ -1559,7 +1558,6 @@ def test_partialmethod_undoc_members(app): assert list(actual) == expected -@pytest.mark.skipif(sys.version_info < (3, 6), reason='py36+ is available since python3.6.') @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_autodoc_typed_instance_variables(app): options = {"members": None, @@ -1653,7 +1651,6 @@ def test_autodoc_typed_instance_variables(app): ] -@pytest.mark.skipif(sys.version_info < (3, 6), reason='py36+ is available since python3.6.') @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_autodoc_typed_inherited_instance_variables(app): options = {"members": None, @@ -1783,7 +1780,6 @@ def test_autodoc_Annotated(app): ] -@pytest.mark.skipif(sys.version_info < (3, 6), reason='py36+ is required.') @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_autodoc_TYPE_CHECKING(app): options = {"members": None, @@ -1832,26 +1828,19 @@ def test_autodoc_for_egged_code(app): def test_singledispatch(app): options = {"members": None} actual = do_autodoc(app, 'module', 'target.singledispatch', options) - if sys.version_info < (3, 6): - # check the result via "in" because the order of singledispatch signatures is - # usually changed (because dict is not OrderedDict yet!) - assert '.. py:function:: func(arg, kwarg=None)' in actual - assert ' func(arg: int, kwarg=None)' in actual - assert ' func(arg: str, kwarg=None)' in actual - else: - assert list(actual) == [ - '', - '.. py:module:: target.singledispatch', - '', - '', - '.. py:function:: func(arg, kwarg=None)', - ' func(arg: int, kwarg=None)', - ' func(arg: str, kwarg=None)', - ' :module: target.singledispatch', - '', - ' A function for general use.', - '', - ] + assert list(actual) == [ + '', + '.. py:module:: target.singledispatch', + '', + '', + '.. py:function:: func(arg, kwarg=None)', + ' func(arg: int, kwarg=None)', + ' func(arg: str, kwarg=None)', + ' :module: target.singledispatch', + '', + ' A function for general use.', + '', + ] @pytest.mark.skipif(sys.version_info < (3, 8), diff --git a/tests/test_ext_autodoc_autofunction.py b/tests/test_ext_autodoc_autofunction.py index 3c8165995c7..4d69442527a 100644 --- a/tests/test_ext_autodoc_autofunction.py +++ b/tests/test_ext_autodoc_autofunction.py @@ -118,23 +118,16 @@ def test_decorated(app): def test_singledispatch(app): options = {} actual = do_autodoc(app, 'function', 'target.singledispatch.func', options) - if sys.version_info < (3, 6): - # check the result via "in" because the order of singledispatch signatures is - # usually changed (because dict is not OrderedDict yet!) - assert '.. py:function:: func(arg, kwarg=None)' in actual - assert ' func(arg: int, kwarg=None)' in actual - assert ' func(arg: str, kwarg=None)' in actual - else: - assert list(actual) == [ - '', - '.. py:function:: func(arg, kwarg=None)', - ' func(arg: int, kwarg=None)', - ' func(arg: str, kwarg=None)', - ' :module: target.singledispatch', - '', - ' A function for general use.', - '', - ] + assert list(actual) == [ + '', + '.. py:function:: func(arg, kwarg=None)', + ' func(arg: int, kwarg=None)', + ' func(arg: str, kwarg=None)', + ' :module: target.singledispatch', + '', + ' A function for general use.', + '', + ] @pytest.mark.sphinx('html', testroot='ext-autodoc') diff --git a/tests/test_pycode_parser.py b/tests/test_pycode_parser.py index 71847f04f57..2ef3c2311ed 100644 --- a/tests/test_pycode_parser.py +++ b/tests/test_pycode_parser.py @@ -95,8 +95,7 @@ def test_comment_picker_location(): ('Foo', 'attr3'): 'comment for attr3(3)'} -@pytest.mark.skipif(sys.version_info < (3, 6), reason='tests for py36+ syntax') -def test_annotated_assignment_py36(): +def test_annotated_assignment(): source = ('a: str = "Sphinx" #: comment\n' 'b: int = 1\n' '"""string on next line"""\n' diff --git a/tests/test_util_inspect.py b/tests/test_util_inspect.py index c21eaaa1671..58aa2198418 100644 --- a/tests/test_util_inspect.py +++ b/tests/test_util_inspect.py @@ -220,10 +220,7 @@ def test_signature_annotations(): # type hints by string sig = inspect.signature(Node.children) - if (3, 5, 0) <= sys.version_info < (3, 5, 3): - assert stringify_signature(sig) == '(self) -> List[Node]' - else: - assert stringify_signature(sig) == '(self) -> List[typing_test_data.Node]' + assert stringify_signature(sig) == '(self) -> List[typing_test_data.Node]' sig = inspect.signature(Node.__init__) assert stringify_signature(sig) == '(self, parent: Optional[Node]) -> None' From b1caecda3954d9128509fb9830a81ecb68be65b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Sat, 7 Nov 2020 11:53:30 +0100 Subject: [PATCH 2/3] Remove additional mentions of Python 3.5 --- setup.py | 2 +- sphinx/util/inspect.py | 2 +- sphinx/util/typing.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index a5f48afa607..dcd79630d14 100644 --- a/setup.py +++ b/setup.py @@ -51,7 +51,7 @@ 'pytest', 'pytest-cov', 'html5lib', - 'typed_ast', # for py35-37 + 'typed_ast', # for py36-37 'cython', ], } diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py index 75cc5c6007f..ca82186eee4 100644 --- a/sphinx/util/inspect.py +++ b/sphinx/util/inspect.py @@ -271,7 +271,7 @@ def is_singledispatch_method(obj: Any) -> bool: try: from functools import singledispatchmethod # type: ignore return isinstance(obj, singledispatchmethod) - except ImportError: # py35-37 + except ImportError: # py36-37 return False diff --git a/sphinx/util/typing.py b/sphinx/util/typing.py index c4a145818c2..f77c3300ba4 100644 --- a/sphinx/util/typing.py +++ b/sphinx/util/typing.py @@ -22,7 +22,7 @@ from typing import _ForwardRef # type: ignore class ForwardRef: - """A pseudo ForwardRef class for py35 and py36.""" + """A pseudo ForwardRef class for py36.""" def __init__(self, arg: Any, is_argument: bool = True) -> None: self.arg = arg From 342c808af3195f03fa6f816e0cca7ea1f48b3705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Sat, 7 Nov 2020 13:32:37 +0100 Subject: [PATCH 3/3] Fix flake8 issue --- sphinx/pycode/parser.py | 1 - 1 file changed, 1 deletion(-) diff --git a/sphinx/pycode/parser.py b/sphinx/pycode/parser.py index 78715f7777f..2d454cc96a9 100644 --- a/sphinx/pycode/parser.py +++ b/sphinx/pycode/parser.py @@ -10,7 +10,6 @@ import inspect import itertools import re -import sys import tokenize from collections import OrderedDict from inspect import Signature