Drop python 3.6 support (#10468)

This commit is contained in:
Takeshi KOMIYA
2022-06-17 03:33:55 +09:00
committed by GitHub
parent 0d2a989517
commit 7e68154e49
24 changed files with 201 additions and 414 deletions

View File

@@ -11,7 +11,7 @@ jobs:
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v1 uses: actions/setup-python@v1
with: with:
python-version: 3.6 python-version: 3.8
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt update sudo apt update

View File

@@ -15,7 +15,7 @@ jobs:
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v1 uses: actions/setup-python@v1
with: with:
python-version: 3.6 python-version: 3.8
- name: Install dependencies - name: Install dependencies
run: pip install -U tox run: pip install -U tox
- name: Run Tox - name: Run Tox

View File

@@ -10,8 +10,6 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
- python: "3.6"
docutils: du14
- python: "3.7" - python: "3.7"
docutils: du15 docutils: du15
- python: "3.8" - python: "3.8"

View File

@@ -4,6 +4,8 @@ Release 6.0.0 (in development)
Dependencies Dependencies
------------ ------------
* Drop python 3.6 support
Incompatible changes Incompatible changes
-------------------- --------------------

View File

@@ -172,19 +172,19 @@ of targets and allows testing against multiple different Python environments:
tox -av tox -av
* To run unit tests for a specific Python version, such as Python 3.6:: * To run unit tests for a specific Python version, such as Python 3.10::
tox -e py36 tox -e py310
* To run unit tests for a specific Python version and turn on deprecation * To run unit tests for a specific Python version and turn on deprecation
warnings on so they're shown in the test output:: warnings on so they're shown in the test output::
PYTHONWARNINGS=all tox -e py36 PYTHONWARNINGS=all tox -e py310
* Arguments to ``pytest`` can be passed via ``tox``, e.g. in order to run a * Arguments to ``pytest`` can be passed via ``tox``, e.g. in order to run a
particular test:: particular test::
tox -e py36 tests/test_module.py::test_new_feature tox -e py310 tests/test_module.py::test_new_feature
You can also test by installing dependencies in your local environment:: You can also test by installing dependencies in your local environment::

View File

@@ -109,16 +109,16 @@ Ubuntu <https://ubuntu.com/about/release-cycle>`_ that has standard support.
For example, as of July 2021, Ubuntu 16.04 has just entered extended For example, as of July 2021, Ubuntu 16.04 has just entered extended
security maintenance (therefore, it doesn't count as standard support) and security maintenance (therefore, it doesn't count as standard support) and
the oldest LTS release to consider is Ubuntu 18.04 LTS, supported until the oldest LTS release to consider is Ubuntu 18.04 LTS, supported until
April 2023 and shipping Python 3.6. April 2023 and shipping Python 3.8.
This is a summary table with the current policy: This is a summary table with the current policy:
========== ========= ====== ========== ========= ======
Date Ubuntu Python Date Ubuntu Python
========== ========= ====== ========== ========= ======
April 2021 18.04 LTS 3.6+
---------- --------- ------
April 2023 20.04 LTS 3.8+ April 2023 20.04 LTS 3.8+
---------- --------- ------
April 2025 22.04 LTS 3.10+
========== ========= ====== ========== ========= ======
Release procedures Release procedures

View File

@@ -12,7 +12,7 @@ Installing Sphinx
Overview Overview
-------- --------
Sphinx is written in `Python`__ and supports Python 3.6+. It builds upon the Sphinx is written in `Python`__ and supports Python 3.7+. It builds upon the
shoulders of many third-party libraries such as `Docutils`__ and `Jinja`__, shoulders of many third-party libraries such as `Docutils`__ and `Jinja`__,
which are installed when Sphinx is installed. which are installed when Sphinx is installed.

View File

@@ -7,8 +7,8 @@ import sphinx
with open('README.rst', encoding='utf-8') as f: with open('README.rst', encoding='utf-8') as f:
long_desc = f.read() long_desc = f.read()
if sys.version_info < (3, 6): if sys.version_info < (3, 7):
print('ERROR: Sphinx requires at least Python 3.6 to run.') print('ERROR: Sphinx requires at least Python 3.7 to run.')
sys.exit(1) sys.exit(1)
install_requires = [ install_requires = [
@@ -85,7 +85,6 @@ setup(
'Programming Language :: Python', 'Programming Language :: Python',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3 :: Only', 'Programming Language :: Python :: 3 :: Only',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.9',
@@ -127,7 +126,7 @@ setup(
'build_sphinx = sphinx.setup_command:BuildDoc', 'build_sphinx = sphinx.setup_command:BuildDoc',
], ],
}, },
python_requires=">=3.6", python_requires=">=3.7",
install_requires=install_requires, install_requires=install_requires,
extras_require=extras_require, extras_require=extras_require,
) )

View File

@@ -18,7 +18,6 @@ Both, the url string and the caption string must escape ``%`` as ``%%``.
""" """
import re import re
import sys
from typing import Any, Dict, List, Tuple from typing import Any, Dict, List, Tuple
from docutils import nodes, utils from docutils import nodes, utils
@@ -64,11 +63,6 @@ class ExternalLinksChecker(SphinxPostTransform):
title = refnode.astext() title = refnode.astext()
for alias, (base_uri, _caption) in self.app.config.extlinks.items(): for alias, (base_uri, _caption) in self.app.config.extlinks.items():
if sys.version_info < (3, 7):
# Replace a leading backslash because re.escape() inserts a backslash before %
# on python 3.6
uri_pattern = re.compile(re.escape(base_uri).replace('\\%s', '(?P<value>.+)'))
else:
uri_pattern = re.compile(re.escape(base_uri).replace('%s', '(?P<value>.+)')) uri_pattern = re.compile(re.escape(base_uri).replace('%s', '(?P<value>.+)'))
match = uri_pattern.match(uri) match = uri_pattern.match(uri)

View File

@@ -15,7 +15,7 @@ from io import StringIO
from types import MethodType, ModuleType from types import MethodType, ModuleType
from typing import Any, Callable, Dict, Mapping, Optional, Sequence, Tuple, Type, cast from typing import Any, Callable, Dict, Mapping, Optional, Sequence, Tuple, Type, cast
from sphinx.pycode.ast import ast # for py36-37 from sphinx.pycode.ast import ast # for py37
from sphinx.pycode.ast import unparse as ast_unparse from sphinx.pycode.ast import unparse as ast_unparse
from sphinx.util import logging from sphinx.util import logging
from sphinx.util.typing import ForwardRef from sphinx.util.typing import ForwardRef
@@ -298,7 +298,7 @@ def is_singledispatch_method(obj: Any) -> bool:
try: try:
from functools import singledispatchmethod # type: ignore from functools import singledispatchmethod # type: ignore
return isinstance(obj, singledispatchmethod) return isinstance(obj, singledispatchmethod)
except ImportError: # py36-37 except ImportError: # py37
return False return False
@@ -568,7 +568,6 @@ def signature(subject: Callable, bound_method: bool = False, type_aliases: Dict
:param bound_method: Specify *subject* is a bound method or not :param bound_method: Specify *subject* is a bound method or not
""" """
try:
try: try:
if _should_unwrap(subject): if _should_unwrap(subject):
signature = inspect.signature(subject) signature = inspect.signature(subject)
@@ -579,15 +578,6 @@ def signature(subject: Callable, bound_method: bool = False, type_aliases: Dict
signature = inspect.signature(subject) signature = inspect.signature(subject)
parameters = list(signature.parameters.values()) parameters = list(signature.parameters.values())
return_annotation = signature.return_annotation return_annotation = signature.return_annotation
except IndexError:
# Until python 3.6.4, cpython has been crashed on inspection for
# partialmethods not having any arguments.
# https://bugs.python.org/issue33009
if hasattr(subject, '_partialmethod'):
parameters = []
return_annotation = Parameter.empty
else:
raise
try: try:
# Resolve annotations using ``get_type_hints()`` and type_aliases. # Resolve annotations using ``get_type_hints()`` and type_aliases.

View File

@@ -2,6 +2,7 @@
import sys import sys
import typing import typing
import warnings
from struct import Struct from struct import Struct
from types import TracebackType from types import TracebackType
from typing import Any, Callable, Dict, Generator, List, Optional, Tuple, Type, TypeVar, Union from typing import Any, Callable, Dict, Generator, List, Optional, Tuple, Type, TypeVar, Union
@@ -9,7 +10,8 @@ from typing import Any, Callable, Dict, Generator, List, Optional, Tuple, Type,
from docutils import nodes from docutils import nodes
from docutils.parsers.rst.states import Inliner from docutils.parsers.rst.states import Inliner
from sphinx.deprecation import RemovedInSphinx60Warning, deprecated_alias from sphinx.deprecation import (RemovedInSphinx60Warning, RemovedInSphinx70Warning,
deprecated_alias)
if sys.version_info > (3, 7): if sys.version_info > (3, 7):
from typing import ForwardRef from typing import ForwardRef
@@ -158,10 +160,7 @@ def restify(cls: Optional[Type], mode: str = 'fully-qualified-except-typing') ->
else: else:
return ':py:class:`%s`' % cls.__name__ return ':py:class:`%s`' % cls.__name__
else: else:
if sys.version_info >= (3, 7): # py37+
return _restify_py37(cls, mode) return _restify_py37(cls, mode)
else:
return _restify_py36(cls, mode)
except (AttributeError, TypeError): except (AttributeError, TypeError):
return inspect.object_description(cls) return inspect.object_description(cls)
@@ -234,6 +233,8 @@ def _restify_py37(cls: Optional[Type], mode: str = 'fully-qualified-except-typin
def _restify_py36(cls: Optional[Type], mode: str = 'fully-qualified-except-typing') -> str: def _restify_py36(cls: Optional[Type], mode: str = 'fully-qualified-except-typing') -> str:
warnings.warn('_restify_py36() is deprecated', RemovedInSphinx70Warning)
if mode == 'smart': if mode == 'smart':
modprefix = '~' modprefix = '~'
else: else:
@@ -390,10 +391,7 @@ def stringify(annotation: Any, mode: str = 'fully-qualified-except-typing') -> s
elif annotation is Ellipsis: elif annotation is Ellipsis:
return '...' return '...'
if sys.version_info >= (3, 7): # py37+
return _stringify_py37(annotation, mode) return _stringify_py37(annotation, mode)
else:
return _stringify_py36(annotation, mode)
def _stringify_py37(annotation: Any, mode: str = 'fully-qualified-except-typing') -> str: def _stringify_py37(annotation: Any, mode: str = 'fully-qualified-except-typing') -> str:
@@ -472,6 +470,8 @@ def _stringify_py37(annotation: Any, mode: str = 'fully-qualified-except-typing'
def _stringify_py36(annotation: Any, mode: str = 'fully-qualified-except-typing') -> str: def _stringify_py36(annotation: Any, mode: str = 'fully-qualified-except-typing') -> str:
"""stringify() for py36.""" """stringify() for py36."""
warnings.warn('_stringify_py36() is deprecated', RemovedInSphinx70Warning)
module = getattr(annotation, '__module__', None) module = getattr(annotation, '__module__', None)
modprefix = '' modprefix = ''
if module == 'typing' and getattr(annotation, '__forward_arg__', None): if module == 'typing' and getattr(annotation, '__forward_arg__', None):

View File

@@ -22,17 +22,10 @@ def nonascii_srcdir(request, rootdir, sphinx_test_tempdir):
# If supported, build in a non-ASCII source dir # If supported, build in a non-ASCII source dir
test_name = '\u65e5\u672c\u8a9e' test_name = '\u65e5\u672c\u8a9e'
basedir = sphinx_test_tempdir / request.node.originalname basedir = sphinx_test_tempdir / request.node.originalname
try:
srcdir = basedir / test_name srcdir = basedir / test_name
if not srcdir.exists(): if not srcdir.exists():
(rootdir / 'test-root').copytree(srcdir) (rootdir / 'test-root').copytree(srcdir)
except UnicodeEncodeError:
# Now Python 3.7+ follows PEP-540 and uses utf-8 encoding for filesystem by default.
# So this error handling will be no longer used (after dropping python 3.6 support).
srcdir = basedir / 'all'
if not srcdir.exists():
(rootdir / 'test-root').copytree(srcdir)
else:
# add a doc with a non-ASCII file name to the source dir # add a doc with a non-ASCII file name to the source dir
(srcdir / (test_name + '.txt')).write_text(dedent(""" (srcdir / (test_name + '.txt')).write_text(dedent("""
nonascii file name page nonascii file name page
@@ -45,6 +38,7 @@ def nonascii_srcdir(request, rootdir, sphinx_test_tempdir):
%(test_name)s/%(test_name)s %(test_name)s/%(test_name)s
""" % {'test_name': test_name}), encoding='utf8') """ % {'test_name': test_name}), encoding='utf8')
return srcdir return srcdir

View File

@@ -1,5 +1,3 @@
import sys
from sphinx.errors import ExtensionError from sphinx.errors import ExtensionError
@@ -10,8 +8,4 @@ def test_extension_error_repr():
def test_extension_error_with_orig_exc_repr(): def test_extension_error_with_orig_exc_repr():
exc = ExtensionError("foo", Exception("bar")) exc = ExtensionError("foo", Exception("bar"))
if sys.version_info < (3, 7): assert repr(exc) == "ExtensionError('foo', Exception('bar'))"
expected = "ExtensionError('foo', Exception('bar',))"
else:
expected = "ExtensionError('foo', Exception('bar'))"
assert repr(exc) == expected

View File

@@ -1860,36 +1860,6 @@ def test_autodoc_GenericAlias(app):
options = {"members": None, options = {"members": None,
"undoc-members": None} "undoc-members": None}
actual = do_autodoc(app, 'module', 'target.genericalias', options) actual = do_autodoc(app, 'module', 'target.genericalias', options)
if sys.version_info < (3, 7):
assert list(actual) == [
'',
'.. py:module:: target.genericalias',
'',
'',
'.. py:class:: Class()',
' :module: target.genericalias',
'',
'',
' .. py:attribute:: Class.T',
' :module: target.genericalias',
'',
' A list of int',
'',
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
'',
'.. py:attribute:: L',
' :module: target.genericalias',
'',
' A list of Class',
'',
'',
'.. py:attribute:: T',
' :module: target.genericalias',
'',
' A list of int',
'',
]
else:
assert list(actual) == [ assert list(actual) == [
'', '',
'.. py:module:: target.genericalias', '.. py:module:: target.genericalias',
@@ -2072,22 +2042,6 @@ def test_autodoc_for_egged_code(app):
def test_singledispatch(app): def test_singledispatch(app):
options = {"members": None} options = {"members": None}
actual = do_autodoc(app, 'module', 'target.singledispatch', options) actual = do_autodoc(app, 'module', 'target.singledispatch', options)
if sys.version_info < (3, 7):
assert list(actual) == [
'',
'.. py:module:: target.singledispatch',
'',
'',
'.. py:function:: func(arg, kwarg=None)',
' func(arg: float, kwarg=None)',
' func(arg: int, kwarg=None)',
' func(arg: str, kwarg=None)',
' :module: target.singledispatch',
'',
' A function for general use.',
'',
]
else:
assert list(actual) == [ assert list(actual) == [
'', '',
'.. py:module:: target.singledispatch', '.. py:module:: target.singledispatch',
@@ -2416,7 +2370,6 @@ def test_name_mangling(app):
] ]
@pytest.mark.skipif(sys.version_info < (3, 7), reason='python 3.7+ is required.')
@pytest.mark.sphinx('html', testroot='ext-autodoc') @pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_type_union_operator(app): def test_type_union_operator(app):
options = {'members': None} options = {'members': None}

View File

@@ -4,8 +4,6 @@ This tests mainly the Documenters; the auto directives are tested in a test
source file translated by test_build. source file translated by test_build.
""" """
import sys
import pytest import pytest
from .test_ext_autodoc import do_autodoc from .test_ext_autodoc import do_autodoc
@@ -141,17 +139,6 @@ def test_autoattribute_slots_variable_str(app):
@pytest.mark.sphinx('html', testroot='ext-autodoc') @pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autoattribute_GenericAlias(app): def test_autoattribute_GenericAlias(app):
actual = do_autodoc(app, 'attribute', 'target.genericalias.Class.T') actual = do_autodoc(app, 'attribute', 'target.genericalias.Class.T')
if sys.version_info < (3, 7):
assert list(actual) == [
'',
'.. py:attribute:: Class.T',
' :module: target.genericalias',
' :value: typing.List[int]',
'',
' A list of int',
'',
]
else:
assert list(actual) == [ assert list(actual) == [
'', '',
'.. py:attribute:: Class.T', '.. py:attribute:: Class.T',

View File

@@ -4,7 +4,6 @@ This tests mainly the Documenters; the auto directives are tested in a test
source file translated by test_build. source file translated by test_build.
""" """
import sys
from typing import List, Union from typing import List, Union
import pytest import pytest
@@ -249,7 +248,6 @@ def test_slots_attribute(app):
] ]
@pytest.mark.skipif(sys.version_info < (3, 7), reason='python 3.7+ is required.')
@pytest.mark.sphinx('html', testroot='ext-autodoc') @pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_show_inheritance_for_subclass_of_generic_type(app): def test_show_inheritance_for_subclass_of_generic_type(app):
options = {'show-inheritance': None} options = {'show-inheritance': None}
@@ -267,7 +265,6 @@ def test_show_inheritance_for_subclass_of_generic_type(app):
] ]
@pytest.mark.skipif(sys.version_info < (3, 7), reason='python 3.7+ is required.')
@pytest.mark.sphinx('html', testroot='ext-autodoc') @pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_show_inheritance_for_decendants_of_generic_type(app): def test_show_inheritance_for_decendants_of_generic_type(app):
options = {'show-inheritance': None} options = {'show-inheritance': None}
@@ -299,18 +296,6 @@ def test_autodoc_process_bases(app):
options = {'show-inheritance': None} options = {'show-inheritance': None}
actual = do_autodoc(app, 'class', 'target.classes.Quux', options) actual = do_autodoc(app, 'class', 'target.classes.Quux', options)
if sys.version_info < (3, 7):
assert list(actual) == [
'',
'.. py:class:: Quux(*args, **kwds)',
' :module: target.classes',
'',
' Bases: :py:class:`int`, :py:class:`str`',
'',
' A subclass of List[Union[int, float]]',
'',
]
else:
assert list(actual) == [ assert list(actual) == [
'', '',
'.. py:class:: Quux(iterable=(), /)', '.. py:class:: Quux(iterable=(), /)',

View File

@@ -4,8 +4,6 @@ This tests mainly the Documenters; the auto directives are tested in a test
source file translated by test_build. source file translated by test_build.
""" """
import sys
import pytest import pytest
from .test_ext_autodoc import do_autodoc from .test_ext_autodoc import do_autodoc
@@ -71,17 +69,6 @@ def test_autodata_type_comment(app):
@pytest.mark.sphinx('html', testroot='ext-autodoc') @pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autodata_GenericAlias(app): def test_autodata_GenericAlias(app):
actual = do_autodoc(app, 'data', 'target.genericalias.T') actual = do_autodoc(app, 'data', 'target.genericalias.T')
if sys.version_info < (3, 7):
assert list(actual) == [
'',
'.. py:data:: T',
' :module: target.genericalias',
' :value: typing.List[int]',
'',
' A list of int',
'',
]
else:
assert list(actual) == [ assert list(actual) == [
'', '',
'.. py:data:: T', '.. py:data:: T',

View File

@@ -4,8 +4,6 @@ This tests mainly the Documenters; the auto directives are tested in a test
source file translated by test_build. source file translated by test_build.
""" """
import sys
import pytest import pytest
from .test_ext_autodoc import do_autodoc from .test_ext_autodoc import do_autodoc
@@ -113,19 +111,6 @@ def test_decorated(app):
def test_singledispatch(app): def test_singledispatch(app):
options = {} options = {}
actual = do_autodoc(app, 'function', 'target.singledispatch.func', options) actual = do_autodoc(app, 'function', 'target.singledispatch.func', options)
if sys.version_info < (3, 7):
assert list(actual) == [
'',
'.. py:function:: func(arg, kwarg=None)',
' func(arg: float, kwarg=None)',
' func(arg: int, kwarg=None)',
' func(arg: str, kwarg=None)',
' :module: target.singledispatch',
'',
' A function for general use.',
'',
]
else:
assert list(actual) == [ assert list(actual) == [
'', '',
'.. py:function:: func(arg, kwarg=None)', '.. py:function:: func(arg, kwarg=None)',

View File

@@ -115,11 +115,6 @@ def test_automodule_special_members(app):
@pytest.mark.sphinx('html', testroot='ext-autodoc') @pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_automodule_inherited_members(app): def test_automodule_inherited_members(app):
if sys.version_info < (3, 7):
args = ''
else:
args = '(iterable=(), /)'
options = {'members': None, options = {'members': None,
'undoc-members': None, 'undoc-members': None,
'inherited-members': 'Base, list'} 'inherited-members': 'Base, list'}
@@ -170,7 +165,7 @@ def test_automodule_inherited_members(app):
' Inherited function.', ' Inherited function.',
'', '',
'', '',
'.. py:class:: MyList%s' % args, '.. py:class:: MyList(iterable=(), /)',
' :module: target.inheritance', ' :module: target.inheritance',
'', '',
'', '',

View File

@@ -1231,7 +1231,6 @@ def test_autodoc_typehints_both(app):
in context) in context)
@pytest.mark.skipif(sys.version_info < (3, 7), reason='python 3.7+ is required.')
@pytest.mark.sphinx('text', testroot='ext-autodoc') @pytest.mark.sphinx('text', testroot='ext-autodoc')
def test_autodoc_type_aliases(app): def test_autodoc_type_aliases(app):
# default # default
@@ -1376,7 +1375,6 @@ def test_autodoc_type_aliases(app):
] ]
@pytest.mark.skipif(sys.version_info < (3, 7), reason='python 3.7+ is required.')
@pytest.mark.sphinx('text', testroot='ext-autodoc', @pytest.mark.sphinx('text', testroot='ext-autodoc',
srcdir='autodoc_typehints_description_and_type_aliases', srcdir='autodoc_typehints_description_and_type_aliases',
confoverrides={'autodoc_typehints': "description", confoverrides={'autodoc_typehints': "description",
@@ -1543,17 +1541,6 @@ def test_autodoc_typehints_format_fully_qualified_for_class_alias(app):
confoverrides={'autodoc_typehints_format': "fully-qualified"}) confoverrides={'autodoc_typehints_format': "fully-qualified"})
def test_autodoc_typehints_format_fully_qualified_for_generic_alias(app): def test_autodoc_typehints_format_fully_qualified_for_generic_alias(app):
actual = do_autodoc(app, 'data', 'target.genericalias.L') actual = do_autodoc(app, 'data', 'target.genericalias.L')
if sys.version_info < (3, 7):
assert list(actual) == [
'',
'.. py:data:: L',
' :module: target.genericalias',
' :value: typing.List[target.genericalias.Class]',
'',
' A list of Class',
'',
]
else:
assert list(actual) == [ assert list(actual) == [
'', '',
'.. py:data:: L', '.. py:data:: L',

View File

@@ -84,7 +84,6 @@ def test_mock_does_not_follow_upper_modules():
import_module('sphinx.unknown') import_module('sphinx.unknown')
@pytest.mark.skipif(sys.version_info < (3, 7), reason='Only for py37 or above')
def test_abc_MockObject(): def test_abc_MockObject():
mock = _MockObject() mock = _MockObject()

View File

@@ -1,6 +1,5 @@
"""Tests for :mod:`sphinx.ext.napoleon.__init__` module.""" """Tests for :mod:`sphinx.ext.napoleon.__init__` module."""
import sys
from collections import namedtuple from collections import namedtuple
from unittest import TestCase, mock from unittest import TestCase, mock
@@ -134,11 +133,6 @@ class SkipMemberTest(TestCase):
mock.Mock())) mock.Mock()))
def test_namedtuple(self): def test_namedtuple(self):
if sys.version_info < (3, 7):
self.assertSkip('class', '_asdict',
SampleNamedTuple._asdict, False,
'napoleon_include_private_with_doc')
else:
# Since python 3.7, namedtuple._asdict() has not been documented # Since python 3.7, namedtuple._asdict() has not been documented
# because there is no way to check the method is a member of the # because there is no way to check the method is a member of the
# namedtuple class. This testcase confirms only it does not # namedtuple class. This testcase confirms only it does not

View File

@@ -163,12 +163,6 @@ def test_signature_annotations():
# TypeVars and generic types with TypeVars # TypeVars and generic types with TypeVars
sig = inspect.signature(f2) sig = inspect.signature(f2)
if sys.version_info < (3, 7):
assert stringify_signature(sig) == ('(x: typing.List[typing.T],'
' y: typing.List[typing.T_co],'
' z: typing.T'
') -> typing.List[typing.T_contra]')
else:
assert stringify_signature(sig) == ('(x: typing.List[tests.typing_test_data.T],' assert stringify_signature(sig) == ('(x: typing.List[tests.typing_test_data.T],'
' y: typing.List[tests.typing_test_data.T_co],' ' y: typing.List[tests.typing_test_data.T_co],'
' z: tests.typing_test_data.T' ' z: tests.typing_test_data.T'
@@ -678,7 +672,6 @@ def test_isproperty(app):
assert inspect.isproperty(func) is False # function assert inspect.isproperty(func) is False # function
@pytest.mark.skipif(sys.version_info < (3, 7), reason='python 3.7+ is required.')
@pytest.mark.sphinx(testroot='ext-autodoc') @pytest.mark.sphinx(testroot='ext-autodoc')
def test_isgenericalias(app): def test_isgenericalias(app):
from target.genericalias import C, T from target.genericalias import C, T

View File

@@ -89,17 +89,10 @@ def test_restify_type_hints_containers():
def test_restify_type_hints_Callable(): def test_restify_type_hints_Callable():
assert restify(Callable) == ":py:class:`~typing.Callable`" assert restify(Callable) == ":py:class:`~typing.Callable`"
if sys.version_info >= (3, 7):
assert restify(Callable[[str], int]) == (":py:class:`~typing.Callable`\\ " assert restify(Callable[[str], int]) == (":py:class:`~typing.Callable`\\ "
"[[:py:class:`str`], :py:class:`int`]") "[[:py:class:`str`], :py:class:`int`]")
assert restify(Callable[..., int]) == (":py:class:`~typing.Callable`\\ " assert restify(Callable[..., int]) == (":py:class:`~typing.Callable`\\ "
"[[...], :py:class:`int`]") "[[...], :py:class:`int`]")
else:
assert restify(Callable[[str], int]) == (":py:class:`~typing.Callable`\\ "
"[:py:class:`str`, :py:class:`int`]")
assert restify(Callable[..., int]) == (":py:class:`~typing.Callable`\\ "
"[..., :py:class:`int`]")
def test_restify_type_hints_Union(): def test_restify_type_hints_Union():
@@ -108,30 +101,20 @@ def test_restify_type_hints_Union():
assert restify(Union[int, str]) == (":py:obj:`~typing.Union`\\ " assert restify(Union[int, str]) == (":py:obj:`~typing.Union`\\ "
"[:py:class:`int`, :py:class:`str`]") "[:py:class:`int`, :py:class:`str`]")
if sys.version_info >= (3, 7):
assert restify(Union[int, Integral]) == (":py:obj:`~typing.Union`\\ " assert restify(Union[int, Integral]) == (":py:obj:`~typing.Union`\\ "
"[:py:class:`int`, :py:class:`numbers.Integral`]") "[:py:class:`int`, :py:class:`numbers.Integral`]")
assert restify(Union[int, Integral], "smart") == (":py:obj:`~typing.Union`\\ " assert restify(Union[int, Integral], "smart") == (":py:obj:`~typing.Union`\\ "
"[:py:class:`int`," "[:py:class:`int`,"
" :py:class:`~numbers.Integral`]") " :py:class:`~numbers.Integral`]")
assert (restify(Union[MyClass1, MyClass2]) == assert (restify(Union[MyClass1, MyClass2]) == (":py:obj:`~typing.Union`\\ "
(":py:obj:`~typing.Union`\\ "
"[:py:class:`tests.test_util_typing.MyClass1`, " "[:py:class:`tests.test_util_typing.MyClass1`, "
":py:class:`tests.test_util_typing.<MyClass2>`]")) ":py:class:`tests.test_util_typing.<MyClass2>`]"))
assert (restify(Union[MyClass1, MyClass2], "smart") == assert (restify(Union[MyClass1, MyClass2], "smart") == (":py:obj:`~typing.Union`\\ "
(":py:obj:`~typing.Union`\\ "
"[:py:class:`~tests.test_util_typing.MyClass1`," "[:py:class:`~tests.test_util_typing.MyClass1`,"
" :py:class:`~tests.test_util_typing.<MyClass2>`]")) " :py:class:`~tests.test_util_typing.<MyClass2>`]"))
else:
assert restify(Union[int, Integral]) == ":py:class:`numbers.Integral`"
assert restify(Union[int, Integral], "smart") == ":py:class:`~numbers.Integral`"
assert restify(Union[MyClass1, MyClass2]) == ":py:class:`tests.test_util_typing.MyClass1`"
assert restify(Union[MyClass1, MyClass2], "smart") == ":py:class:`~tests.test_util_typing.MyClass1`"
@pytest.mark.skipif(sys.version_info < (3, 7), reason='python 3.7+ is required.')
def test_restify_type_hints_typevars(): def test_restify_type_hints_typevars():
T = TypeVar('T') T = TypeVar('T')
T_co = TypeVar('T_co', covariant=True) T_co = TypeVar('T_co', covariant=True)
@@ -172,7 +155,6 @@ def test_restify_type_hints_alias():
assert restify(MyTuple) == ":py:class:`~typing.Tuple`\\ [:py:class:`str`, :py:class:`str`]" assert restify(MyTuple) == ":py:class:`~typing.Tuple`\\ [:py:class:`str`, :py:class:`str`]"
@pytest.mark.skipif(sys.version_info < (3, 7), reason='python 3.7+ is required.')
def test_restify_type_ForwardRef(): def test_restify_type_ForwardRef():
from typing import ForwardRef # type: ignore from typing import ForwardRef # type: ignore
assert restify(ForwardRef("myint")) == ":py:class:`myint`" assert restify(ForwardRef("myint")) == ":py:class:`myint`"
@@ -346,7 +328,6 @@ def test_stringify_type_hints_Callable():
assert stringify(Callable, "fully-qualified") == "typing.Callable" assert stringify(Callable, "fully-qualified") == "typing.Callable"
assert stringify(Callable, "smart") == "~typing.Callable" assert stringify(Callable, "smart") == "~typing.Callable"
if sys.version_info >= (3, 7):
assert stringify(Callable[[str], int]) == "Callable[[str], int]" assert stringify(Callable[[str], int]) == "Callable[[str], int]"
assert stringify(Callable[[str], int], "fully-qualified") == "typing.Callable[[str], int]" assert stringify(Callable[[str], int], "fully-qualified") == "typing.Callable[[str], int]"
assert stringify(Callable[[str], int], "smart") == "~typing.Callable[[str], int]" assert stringify(Callable[[str], int], "smart") == "~typing.Callable[[str], int]"
@@ -354,14 +335,6 @@ def test_stringify_type_hints_Callable():
assert stringify(Callable[..., int]) == "Callable[[...], int]" assert stringify(Callable[..., int]) == "Callable[[...], int]"
assert stringify(Callable[..., int], "fully-qualified") == "typing.Callable[[...], int]" assert stringify(Callable[..., int], "fully-qualified") == "typing.Callable[[...], int]"
assert stringify(Callable[..., int], "smart") == "~typing.Callable[[...], int]" assert stringify(Callable[..., int], "smart") == "~typing.Callable[[...], int]"
else:
assert stringify(Callable[[str], int]) == "Callable[str, int]"
assert stringify(Callable[[str], int], "fully-qualified") == "typing.Callable[str, int]"
assert stringify(Callable[[str], int], "smart") == "~typing.Callable[str, int]"
assert stringify(Callable[..., int]) == "Callable[..., int]"
assert stringify(Callable[..., int], "fully-qualified") == "typing.Callable[..., int]"
assert stringify(Callable[..., int], "smart") == "~typing.Callable[..., int]"
def test_stringify_type_hints_Union(): def test_stringify_type_hints_Union():
@@ -377,7 +350,6 @@ def test_stringify_type_hints_Union():
assert stringify(Union[int, str], "fully-qualified") == "typing.Union[int, str]" assert stringify(Union[int, str], "fully-qualified") == "typing.Union[int, str]"
assert stringify(Union[int, str], "smart") == "~typing.Union[int, str]" assert stringify(Union[int, str], "smart") == "~typing.Union[int, str]"
if sys.version_info >= (3, 7):
assert stringify(Union[int, Integral]) == "Union[int, numbers.Integral]" assert stringify(Union[int, Integral]) == "Union[int, numbers.Integral]"
assert stringify(Union[int, Integral], "fully-qualified") == "typing.Union[int, numbers.Integral]" assert stringify(Union[int, Integral], "fully-qualified") == "typing.Union[int, numbers.Integral]"
assert stringify(Union[int, Integral], "smart") == "~typing.Union[int, ~numbers.Integral]" assert stringify(Union[int, Integral], "smart") == "~typing.Union[int, ~numbers.Integral]"
@@ -388,14 +360,6 @@ def test_stringify_type_hints_Union():
"typing.Union[tests.test_util_typing.MyClass1, tests.test_util_typing.<MyClass2>]") "typing.Union[tests.test_util_typing.MyClass1, tests.test_util_typing.<MyClass2>]")
assert (stringify(Union[MyClass1, MyClass2], "smart") == assert (stringify(Union[MyClass1, MyClass2], "smart") ==
"~typing.Union[~tests.test_util_typing.MyClass1, ~tests.test_util_typing.<MyClass2>]") "~typing.Union[~tests.test_util_typing.MyClass1, ~tests.test_util_typing.<MyClass2>]")
else:
assert stringify(Union[int, Integral]) == "numbers.Integral"
assert stringify(Union[int, Integral], "fully-qualified") == "numbers.Integral"
assert stringify(Union[int, Integral], "smart") == "~numbers.Integral"
assert stringify(Union[MyClass1, MyClass2]) == "tests.test_util_typing.MyClass1"
assert stringify(Union[MyClass1, MyClass2], "fully-qualified") == "tests.test_util_typing.MyClass1"
assert stringify(Union[MyClass1, MyClass2], "smart") == "~tests.test_util_typing.MyClass1"
def test_stringify_type_hints_typevars(): def test_stringify_type_hints_typevars():
@@ -403,19 +367,6 @@ def test_stringify_type_hints_typevars():
T_co = TypeVar('T_co', covariant=True) T_co = TypeVar('T_co', covariant=True)
T_contra = TypeVar('T_contra', contravariant=True) T_contra = TypeVar('T_contra', contravariant=True)
if sys.version_info < (3, 7):
assert stringify(T) == "T"
assert stringify(T, "smart") == "T"
assert stringify(T_co) == "T_co"
assert stringify(T_co, "smart") == "T_co"
assert stringify(T_contra) == "T_contra"
assert stringify(T_contra, "smart") == "T_contra"
assert stringify(List[T]) == "List[T]"
assert stringify(List[T], "smart") == "~typing.List[T]"
else:
assert stringify(T) == "tests.test_util_typing.T" assert stringify(T) == "tests.test_util_typing.T"
assert stringify(T, "smart") == "~tests.test_util_typing.T" assert stringify(T, "smart") == "~tests.test_util_typing.T"