Skip to content

Commit

Permalink
Drop python 3.6 support
Browse files Browse the repository at this point in the history
  • Loading branch information
tk0miya committed May 22, 2022
1 parent fffba7b commit adc57be
Show file tree
Hide file tree
Showing 24 changed files with 203 additions and 416 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/builddoc.yml
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Expand Up @@ -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
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/main.yml
Expand Up @@ -10,8 +10,6 @@ jobs:
fail-fast: false
matrix:
include:
- python: "3.6"
docutils: du14
- python: "3.7"
docutils: du15
- python: "3.8"
Expand Down
2 changes: 2 additions & 0 deletions CHANGES
Expand Up @@ -4,6 +4,8 @@ Release 6.0.0 (in development)
Dependencies
------------

* Drop python 3.6 support

Incompatible changes
--------------------

Expand Down
8 changes: 4 additions & 4 deletions doc/internals/contributing.rst
Expand Up @@ -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::

Expand Down
6 changes: 3 additions & 3 deletions doc/internals/release-process.rst
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion doc/usage/installation.rst
Expand Up @@ -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.

Expand Down
7 changes: 3 additions & 4 deletions setup.py
Expand Up @@ -7,8 +7,8 @@
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 = [
Expand Down Expand Up @@ -84,7 +84,6 @@
'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',
Expand Down Expand Up @@ -126,7 +125,7 @@
'build_sphinx = sphinx.setup_command:BuildDoc',
],
},
python_requires=">=3.6",
python_requires=">=3.7",
install_requires=install_requires,
extras_require=extras_require,
)
8 changes: 1 addition & 7 deletions sphinx/ext/extlinks.py
Expand Up @@ -18,7 +18,6 @@
"""

import re
import sys
from typing import Any, Dict, List, Tuple

from docutils import nodes, utils
Expand Down Expand Up @@ -64,12 +63,7 @@ def check_uri(self, refnode: nodes.reference) -> None:
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'):
Expand Down
28 changes: 9 additions & 19 deletions sphinx/util/inspect.py
Expand Up @@ -15,7 +15,7 @@
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
Expand Down Expand Up @@ -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


Expand Down Expand Up @@ -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.
Expand Down
18 changes: 9 additions & 9 deletions sphinx/util/typing.py
Expand Up @@ -2,14 +2,16 @@

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

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
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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):
Expand Down
40 changes: 17 additions & 23 deletions tests/test_build.py
Expand Up @@ -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')

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')
srcdir = basedir / test_name
if not srcdir.exists():
(rootdir / 'test-root').copytree(srcdir)

# 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')

return srcdir


Expand Down
8 changes: 1 addition & 7 deletions tests/test_errors.py
@@ -1,5 +1,3 @@
import sys

from sphinx.errors import ExtensionError


Expand All @@ -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'))"

0 comments on commit adc57be

Please sign in to comment.