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
uses: actions/setup-python@v1
with:
python-version: 3.6
python-version: 3.8
- name: Install dependencies
run: |
sudo apt update

View File

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

View File

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

View File

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

View File

@@ -172,19 +172,19 @@ of targets and allows testing against multiple different Python environments:
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
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
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::

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
security maintenance (therefore, it doesn't count as standard support) and
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:
========== ========= ======
Date Ubuntu Python
========== ========= ======
April 2021 18.04 LTS 3.6+
---------- --------- ------
April 2023 20.04 LTS 3.8+
---------- --------- ------
April 2025 22.04 LTS 3.10+
========== ========= ======
Release procedures

View File

@@ -12,7 +12,7 @@ Installing Sphinx
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`__,
which are installed when Sphinx is installed.

View File

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

View File

@@ -18,7 +18,6 @@ Both, the url string and the caption string must escape ``%`` as ``%%``.
"""
import re
import sys
from typing import Any, Dict, List, Tuple
from docutils import nodes, utils
@@ -64,12 +63,7 @@ class ExternalLinksChecker(SphinxPostTransform):
title = refnode.astext()
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)
if match and match.groupdict().get('value'):

View File

@@ -15,7 +15,7 @@ from io import StringIO
from types import MethodType, ModuleType
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.util import logging
from sphinx.util.typing import ForwardRef
@@ -298,7 +298,7 @@ def is_singledispatch_method(obj: Any) -> bool:
try:
from functools import singledispatchmethod # type: ignore
return isinstance(obj, singledispatchmethod)
except ImportError: # py36-37
except ImportError: # py37
return False
@@ -569,25 +569,15 @@ def signature(subject: Callable, bound_method: bool = False, type_aliases: Dict
"""
try:
try:
if _should_unwrap(subject):
signature = inspect.signature(subject)
else:
signature = inspect.signature(subject, follow_wrapped=True)
except ValueError:
# follow built-in wrappers up (ex. functools.lru_cache)
if _should_unwrap(subject):
signature = inspect.signature(subject)
parameters = list(signature.parameters.values())
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
signature = inspect.signature(subject, follow_wrapped=True)
except ValueError:
# follow built-in wrappers up (ex. functools.lru_cache)
signature = inspect.signature(subject)
parameters = list(signature.parameters.values())
return_annotation = signature.return_annotation
try:
# Resolve annotations using ``get_type_hints()`` and type_aliases.

View File

@@ -2,6 +2,7 @@
import sys
import typing
import warnings
from struct import Struct
from types import TracebackType
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.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):
from typing import ForwardRef
@@ -158,10 +160,7 @@ def restify(cls: Optional[Type], mode: str = 'fully-qualified-except-typing') ->
else:
return ':py:class:`%s`' % cls.__name__
else:
if sys.version_info >= (3, 7): # py37+
return _restify_py37(cls, mode)
else:
return _restify_py36(cls, mode)
return _restify_py37(cls, mode)
except (AttributeError, TypeError):
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:
warnings.warn('_restify_py36() is deprecated', RemovedInSphinx70Warning)
if mode == 'smart':
modprefix = '~'
else:
@@ -390,10 +391,7 @@ def stringify(annotation: Any, mode: str = 'fully-qualified-except-typing') -> s
elif annotation is Ellipsis:
return '...'
if sys.version_info >= (3, 7): # py37+
return _stringify_py37(annotation, mode)
else:
return _stringify_py36(annotation, mode)
return _stringify_py37(annotation, mode)
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:
"""stringify() for py36."""
warnings.warn('_stringify_py36() is deprecated', RemovedInSphinx70Warning)
module = getattr(annotation, '__module__', None)
modprefix = ''
if module == 'typing' and getattr(annotation, '__forward_arg__', None):

View File

@@ -22,29 +22,23 @@ def nonascii_srcdir(request, rootdir, sphinx_test_tempdir):
# If supported, build in a non-ASCII source dir
test_name = '\u65e5\u672c\u8a9e'
basedir = sphinx_test_tempdir / request.node.originalname
try:
srcdir = basedir / test_name
if not srcdir.exists():
(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
(srcdir / (test_name + '.txt')).write_text(dedent("""
nonascii file name page
=======================
"""), encoding='utf8')
srcdir = basedir / test_name
if not srcdir.exists():
(rootdir / 'test-root').copytree(srcdir)
root_doc = srcdir / 'index.txt'
root_doc.write_text(root_doc.read_text(encoding='utf8') + dedent("""
.. toctree::
# add a doc with a non-ASCII file name to the source dir
(srcdir / (test_name + '.txt')).write_text(dedent("""
nonascii file name page
=======================
"""), encoding='utf8')
root_doc = srcdir / 'index.txt'
root_doc.write_text(root_doc.read_text(encoding='utf8') + dedent("""
.. toctree::
%(test_name)s/%(test_name)s
""" % {'test_name': test_name}), encoding='utf8')
%(test_name)s/%(test_name)s
""" % {'test_name': test_name}), encoding='utf8')
return srcdir

View File

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

View File

@@ -1860,70 +1860,40 @@ def test_autodoc_GenericAlias(app):
options = {"members": None,
"undoc-members": None}
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) == [
'',
'.. 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:data:: L',
' :module: target.genericalias',
'',
' A list of Class',
'',
' alias of :py:class:`~typing.List`\\ '
'[:py:class:`~target.genericalias.Class`]',
'',
'',
'.. py:data:: T',
' :module: target.genericalias',
'',
' A list of int',
'',
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
'',
]
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:data:: L',
' :module: target.genericalias',
'',
' A list of Class',
'',
' alias of :py:class:`~typing.List`\\ '
'[:py:class:`~target.genericalias.Class`]',
'',
'',
'.. py:data:: T',
' :module: target.genericalias',
'',
' A list of int',
'',
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
'',
]
@pytest.mark.sphinx('html', testroot='ext-autodoc')
@@ -2072,37 +2042,21 @@ 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, 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) == [
'',
'.. 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)',
' func(arg: dict, 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: float, kwarg=None)',
' func(arg: int, kwarg=None)',
' func(arg: str, kwarg=None)',
' func(arg: dict, kwarg=None)',
' :module: target.singledispatch',
'',
' A function for general use.',
'',
]
@pytest.mark.skipif(sys.version_info < (3, 8),
@@ -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')
def test_type_union_operator(app):
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.
"""
import sys
import pytest
from .test_ext_autodoc import do_autodoc
@@ -141,27 +139,16 @@ def test_autoattribute_slots_variable_str(app):
@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autoattribute_GenericAlias(app):
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) == [
'',
'.. py:attribute:: Class.T',
' :module: target.genericalias',
'',
' A list of int',
'',
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
'',
]
assert list(actual) == [
'',
'.. py:attribute:: Class.T',
' :module: target.genericalias',
'',
' A list of int',
'',
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
'',
]
@pytest.mark.sphinx('html', testroot='ext-autodoc')

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.
"""
import sys
from typing import List, Union
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')
def test_show_inheritance_for_subclass_of_generic_type(app):
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')
def test_show_inheritance_for_decendants_of_generic_type(app):
options = {'show-inheritance': None}
@@ -299,28 +296,16 @@ def test_autodoc_process_bases(app):
options = {'show-inheritance': None}
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) == [
'',
'.. py:class:: Quux(iterable=(), /)',
' :module: target.classes',
'',
' Bases: :py:class:`int`, :py:class:`str`',
'',
' A subclass of List[Union[int, float]]',
'',
]
assert list(actual) == [
'',
'.. py:class:: Quux(iterable=(), /)',
' :module: target.classes',
'',
' Bases: :py:class:`int`, :py:class:`str`',
'',
' A subclass of List[Union[int, float]]',
'',
]
@pytest.mark.sphinx('html', testroot='ext-autodoc')

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.
"""
import sys
import pytest
from .test_ext_autodoc import do_autodoc
@@ -71,27 +69,16 @@ def test_autodata_type_comment(app):
@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autodata_GenericAlias(app):
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) == [
'',
'.. py:data:: T',
' :module: target.genericalias',
'',
' A list of int',
'',
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
'',
]
assert list(actual) == [
'',
'.. py:data:: T',
' :module: target.genericalias',
'',
' A list of int',
'',
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
'',
]
@pytest.mark.sphinx('html', testroot='ext-autodoc')

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.
"""
import sys
import pytest
from .test_ext_autodoc import do_autodoc
@@ -113,31 +111,18 @@ def test_decorated(app):
def test_singledispatch(app):
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) == [
'',
'.. py:function:: func(arg, kwarg=None)',
' func(arg: float, kwarg=None)',
' func(arg: int, kwarg=None)',
' func(arg: str, kwarg=None)',
' func(arg: dict, kwarg=None)',
' :module: target.singledispatch',
'',
' A function for general use.',
'',
]
assert list(actual) == [
'',
'.. py:function:: func(arg, kwarg=None)',
' func(arg: float, kwarg=None)',
' func(arg: int, kwarg=None)',
' func(arg: str, kwarg=None)',
' func(arg: dict, kwarg=None)',
' :module: target.singledispatch',
'',
' A function for general use.',
'',
]
@pytest.mark.sphinx('html', testroot='ext-autodoc')

View File

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

View File

@@ -1231,7 +1231,6 @@ def test_autodoc_typehints_both(app):
in context)
@pytest.mark.skipif(sys.version_info < (3, 7), reason='python 3.7+ is required.')
@pytest.mark.sphinx('text', testroot='ext-autodoc')
def test_autodoc_type_aliases(app):
# 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',
srcdir='autodoc_typehints_description_and_type_aliases',
confoverrides={'autodoc_typehints': "description",
@@ -1543,27 +1541,16 @@ def test_autodoc_typehints_format_fully_qualified_for_class_alias(app):
confoverrides={'autodoc_typehints_format': "fully-qualified"})
def test_autodoc_typehints_format_fully_qualified_for_generic_alias(app):
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) == [
'',
'.. py:data:: L',
' :module: target.genericalias',
'',
' A list of Class',
'',
' alias of :py:class:`~typing.List`\\ [:py:class:`target.genericalias.Class`]',
'',
]
assert list(actual) == [
'',
'.. py:data:: L',
' :module: target.genericalias',
'',
' A list of Class',
'',
' alias of :py:class:`~typing.List`\\ [:py:class:`target.genericalias.Class`]',
'',
]
@pytest.mark.sphinx('html', testroot='ext-autodoc',

View File

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

View File

@@ -1,6 +1,5 @@
"""Tests for :mod:`sphinx.ext.napoleon.__init__` module."""
import sys
from collections import namedtuple
from unittest import TestCase, mock
@@ -134,18 +133,13 @@ class SkipMemberTest(TestCase):
mock.Mock()))
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
# because there is no way to check the method is a member of the
# namedtuple class. This testcase confirms only it does not
# raise an error on building document (refs: #1455)
self.assertSkip('class', '_asdict',
SampleNamedTuple._asdict, True,
'napoleon_include_private_with_doc')
# Since python 3.7, namedtuple._asdict() has not been documented
# because there is no way to check the method is a member of the
# namedtuple class. This testcase confirms only it does not
# raise an error on building document (refs: #1455)
self.assertSkip('class', '_asdict',
SampleNamedTuple._asdict, True,
'napoleon_include_private_with_doc')
def test_class_private_doc(self):
self.assertSkip('class', '_private_doc',

View File

@@ -163,16 +163,10 @@ def test_signature_annotations():
# TypeVars and generic types with TypeVars
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],'
' y: typing.List[tests.typing_test_data.T_co],'
' z: tests.typing_test_data.T'
') -> typing.List[tests.typing_test_data.T_contra]')
assert stringify_signature(sig) == ('(x: typing.List[tests.typing_test_data.T],'
' y: typing.List[tests.typing_test_data.T_co],'
' z: tests.typing_test_data.T'
') -> typing.List[tests.typing_test_data.T_contra]')
# Union types
sig = inspect.signature(f3)
@@ -678,7 +672,6 @@ def test_isproperty(app):
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')
def test_isgenericalias(app):
from target.genericalias import C, T

View File

@@ -89,17 +89,10 @@ def test_restify_type_hints_containers():
def test_restify_type_hints_Callable():
assert restify(Callable) == ":py:class:`~typing.Callable`"
if sys.version_info >= (3, 7):
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`]")
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`]")
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():
@@ -108,30 +101,20 @@ def test_restify_type_hints_Union():
assert restify(Union[int, str]) == (":py:obj:`~typing.Union`\\ "
"[:py:class:`int`, :py:class:`str`]")
if sys.version_info >= (3, 7):
assert restify(Union[int, Integral]) == (":py:obj:`~typing.Union`\\ "
"[:py:class:`int`, :py:class:`numbers.Integral`]")
assert restify(Union[int, Integral], "smart") == (":py:obj:`~typing.Union`\\ "
"[:py:class:`int`,"
" :py:class:`~numbers.Integral`]")
assert restify(Union[int, Integral]) == (":py:obj:`~typing.Union`\\ "
"[:py:class:`int`, :py:class:`numbers.Integral`]")
assert restify(Union[int, Integral], "smart") == (":py:obj:`~typing.Union`\\ "
"[:py:class:`int`,"
" :py:class:`~numbers.Integral`]")
assert (restify(Union[MyClass1, MyClass2]) ==
(":py:obj:`~typing.Union`\\ "
"[:py:class:`tests.test_util_typing.MyClass1`, "
":py:class:`tests.test_util_typing.<MyClass2>`]"))
assert (restify(Union[MyClass1, MyClass2], "smart") ==
(":py:obj:`~typing.Union`\\ "
"[:py:class:`~tests.test_util_typing.MyClass1`,"
" :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`"
assert (restify(Union[MyClass1, MyClass2]) == (":py:obj:`~typing.Union`\\ "
"[:py:class:`tests.test_util_typing.MyClass1`, "
":py:class:`tests.test_util_typing.<MyClass2>`]"))
assert (restify(Union[MyClass1, MyClass2], "smart") == (":py:obj:`~typing.Union`\\ "
"[:py:class:`~tests.test_util_typing.MyClass1`,"
" :py:class:`~tests.test_util_typing.<MyClass2>`]"))
@pytest.mark.skipif(sys.version_info < (3, 7), reason='python 3.7+ is required.')
def test_restify_type_hints_typevars():
T = TypeVar('T')
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`]"
@pytest.mark.skipif(sys.version_info < (3, 7), reason='python 3.7+ is required.')
def test_restify_type_ForwardRef():
from typing import ForwardRef # type: ignore
assert restify(ForwardRef("myint")) == ":py:class:`myint`"
@@ -346,22 +328,13 @@ def test_stringify_type_hints_Callable():
assert stringify(Callable, "fully-qualified") == "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], "fully-qualified") == "typing.Callable[[str], int]"
assert stringify(Callable[[str], int], "smart") == "~typing.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], "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]"
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]"
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():
@@ -377,25 +350,16 @@ def test_stringify_type_hints_Union():
assert stringify(Union[int, str], "fully-qualified") == "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], "fully-qualified") == "typing.Union[int, numbers.Integral]"
assert stringify(Union[int, Integral], "smart") == "~typing.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], "smart") == "~typing.Union[int, ~numbers.Integral]"
assert (stringify(Union[MyClass1, MyClass2]) ==
"Union[tests.test_util_typing.MyClass1, tests.test_util_typing.<MyClass2>]")
assert (stringify(Union[MyClass1, MyClass2], "fully-qualified") ==
"typing.Union[tests.test_util_typing.MyClass1, tests.test_util_typing.<MyClass2>]")
assert (stringify(Union[MyClass1, MyClass2], "smart") ==
"~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"
assert (stringify(Union[MyClass1, MyClass2]) ==
"Union[tests.test_util_typing.MyClass1, tests.test_util_typing.<MyClass2>]")
assert (stringify(Union[MyClass1, MyClass2], "fully-qualified") ==
"typing.Union[tests.test_util_typing.MyClass1, tests.test_util_typing.<MyClass2>]")
assert (stringify(Union[MyClass1, MyClass2], "smart") ==
"~typing.Union[~tests.test_util_typing.MyClass1, ~tests.test_util_typing.<MyClass2>]")
def test_stringify_type_hints_typevars():
@@ -403,30 +367,17 @@ def test_stringify_type_hints_typevars():
T_co = TypeVar('T_co', covariant=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) == "tests.test_util_typing.T"
assert stringify(T, "smart") == "~tests.test_util_typing.T"
assert stringify(T_co) == "T_co"
assert stringify(T_co, "smart") == "T_co"
assert stringify(T_co) == "tests.test_util_typing.T_co"
assert stringify(T_co, "smart") == "~tests.test_util_typing.T_co"
assert stringify(T_contra) == "T_contra"
assert stringify(T_contra, "smart") == "T_contra"
assert stringify(T_contra) == "tests.test_util_typing.T_contra"
assert stringify(T_contra, "smart") == "~tests.test_util_typing.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, "smart") == "~tests.test_util_typing.T"
assert stringify(T_co) == "tests.test_util_typing.T_co"
assert stringify(T_co, "smart") == "~tests.test_util_typing.T_co"
assert stringify(T_contra) == "tests.test_util_typing.T_contra"
assert stringify(T_contra, "smart") == "~tests.test_util_typing.T_contra"
assert stringify(List[T]) == "List[tests.test_util_typing.T]"
assert stringify(List[T], "smart") == "~typing.List[~tests.test_util_typing.T]"
assert stringify(List[T]) == "List[tests.test_util_typing.T]"
assert stringify(List[T], "smart") == "~typing.List[~tests.test_util_typing.T]"
if sys.version_info >= (3, 10):
assert stringify(MyInt) == "tests.test_util_typing.MyInt"