Skip to content

Commit

Permalink
Drop Python 3.7
Browse files Browse the repository at this point in the history
  • Loading branch information
AA-Turner committed Sep 27, 2022
1 parent 7649eb1 commit 4660b62
Show file tree
Hide file tree
Showing 27 changed files with 167 additions and 291 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/main.yml
Expand Up @@ -13,8 +13,6 @@ jobs:
fail-fast: false
matrix:
include:
- python: "3.7"
docutils: du15
- python: "3.8"
docutils: du16
- python: "3.9"
Expand Down
1 change: 1 addition & 0 deletions CHANGES
Expand Up @@ -5,6 +5,7 @@ Dependencies
------------

* #10468: Drop Python 3.6 support
* #10470: Drop Python 3.7 support. Patch by Adam Turner

Incompatible changes
--------------------
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.7+. It builds upon the
Sphinx is written in `Python`__ and supports Python 3.8+. 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: 2 additions & 5 deletions pyproject.toml
Expand Up @@ -13,7 +13,7 @@ urls.Download = "https://pypi.org/project/Sphinx/"
urls.Homepage = "https://www.sphinx-doc.org/"
urls."Issue tracker" = "https://github.com/sphinx-doc/sphinx/issues"
license.text = "BSD"
requires-python = ">=3.7"
requires-python = ">=3.8"

# Classifiers list: https://pypi.org/classifiers/
classifiers = [
Expand All @@ -30,7 +30,6 @@ classifiers = [
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
Expand Down Expand Up @@ -89,13 +88,11 @@ lint = [
"mypy>=0.981",
"sphinx-lint",
"docutils-stubs",
"types-typed-ast",
"types-requests",
]
test = [
"pytest>=4.6",
"html5lib",
"typed_ast; python_version < '3.8'",
"cython",
]

Expand Down Expand Up @@ -144,7 +141,7 @@ disallow_incomplete_defs = true
follow_imports = "skip"
ignore_missing_imports = true
no_implicit_optional = true
python_version = "3.7"
python_version = "3.8"
show_column_numbers = true
show_error_codes = true
show_error_context = true
Expand Down
2 changes: 1 addition & 1 deletion sphinx/directives/other.py
Expand Up @@ -77,7 +77,7 @@ def run(self) -> List[Node]:
return ret

def parse_content(self, toctree: addnodes.toctree) -> List[Node]:
generated_docnames = frozenset(self.env.domains['std'].initial_data['labels'].keys())
generated_docnames = frozenset(self.env.domains['std']._virtual_doc_names)
suffixes = self.config.source_suffix

# glob target documents
Expand Down
17 changes: 2 additions & 15 deletions sphinx/domains/python.py
@@ -1,9 +1,9 @@
"""The Python domain."""

import ast
import builtins
import inspect
import re
import sys
import typing
from inspect import Parameter
from typing import Any, Dict, Iterable, Iterator, List, NamedTuple, Optional, Tuple, Type, cast
Expand All @@ -21,7 +21,6 @@
from sphinx.domains import Domain, Index, IndexEntry, ObjType
from sphinx.environment import BuildEnvironment
from sphinx.locale import _, __
from sphinx.pycode.ast import ast
from sphinx.pycode.ast import parse as ast_parse
from sphinx.roles import XRefRole
from sphinx.util import logging
Expand Down Expand Up @@ -138,7 +137,7 @@ def unparse(node: ast.AST) -> List[Node]:
return [addnodes.desc_sig_space(),
addnodes.desc_sig_punctuation('', '|'),
addnodes.desc_sig_space()]
elif isinstance(node, ast.Constant): # type: ignore
elif isinstance(node, ast.Constant):
if node.value is Ellipsis:
return [addnodes.desc_sig_punctuation('', "...")]
elif isinstance(node.value, bool):
Expand Down Expand Up @@ -204,18 +203,6 @@ def unparse(node: ast.AST) -> List[Node]:

return result
else:
if sys.version_info[:2] <= (3, 7):
if isinstance(node, ast.Bytes):
return [addnodes.desc_sig_literal_string('', repr(node.s))]
elif isinstance(node, ast.Ellipsis):
return [addnodes.desc_sig_punctuation('', "...")]
elif isinstance(node, ast.NameConstant):
return [nodes.Text(node.value)]
elif isinstance(node, ast.Num):
return [addnodes.desc_sig_literal_string('', repr(node.n))]
elif isinstance(node, ast.Str):
return [addnodes.desc_sig_literal_string('', repr(node.s))]

raise SyntaxError # unsupported syntax

try:
Expand Down
18 changes: 9 additions & 9 deletions sphinx/domains/std.py
@@ -1,10 +1,9 @@
"""The standard domain."""

import re
import sys
from copy import copy
from typing import (TYPE_CHECKING, Any, Callable, Dict, Iterable, Iterator, List, Optional,
Tuple, Type, Union, cast)
from typing import (TYPE_CHECKING, Any, Callable, Dict, Final, Iterable, Iterator, List,
Optional, Tuple, Type, Union, cast)

from docutils import nodes
from docutils.nodes import Element, Node, system_message
Expand All @@ -29,11 +28,6 @@

logger = logging.getLogger(__name__)

if sys.version_info[:2] >= (3, 8):
from typing import Final
else:
Final = Any

# RE for option descriptions
option_desc_re = re.compile(r'((?:/|--|-|\+)?[^\s=]+)(=?\s*.*)')
# RE for grammar tokens
Expand Down Expand Up @@ -589,7 +583,7 @@ class StandardDomain(Domain):
'doc': XRefRole(warn_dangling=True, innernodeclass=nodes.inline),
}

initial_data: Final = {
initial_data: Final = { # type: ignore[misc]
'progoptions': {}, # (program, name) -> docname, labelid
'objects': {}, # (type, name) -> docname, labelid
'labels': { # labelname -> docname, labelid, sectionname
Expand All @@ -604,6 +598,12 @@ class StandardDomain(Domain):
},
}

_virtual_doc_names: Dict[str, Tuple[str, str]] = { # labelname -> docname, sectionname
'genindex': ('genindex', _('Index')),
'modindex': ('py-modindex', _('Module Index')),
'search': ('search', _('Search Page')),
}

dangling_warnings = {
'term': 'term not in glossary: %(target)r',
'numref': 'undefined label: %(target)r',
Expand Down
4 changes: 2 additions & 2 deletions sphinx/environment/adapters/toctree.py
Expand Up @@ -54,7 +54,7 @@ def resolve(self, docname: str, builder: "Builder", toctree: addnodes.toctree,
"""
if toctree.get('hidden', False) and not includehidden:
return None
generated_docnames: Dict[str, Tuple[str, str, str]] = self.env.domains['std'].initial_data['labels'].copy() # NoQA: E501
generated_docnames: Dict[str, Tuple[str, str]] = self.env.domains['std']._virtual_doc_names.copy() # NoQA: E501

# For reading the following two helper function, it is useful to keep
# in mind the node structure of a toctree (using HTML-like node names
Expand Down Expand Up @@ -141,7 +141,7 @@ def _entries_from_toctree(toctreenode: addnodes.toctree, parents: List[str],
# don't show subitems
toc = nodes.bullet_list('', item)
elif ref in generated_docnames:
docname, _, sectionname = generated_docnames[ref]
docname, sectionname = generated_docnames[ref]
if not title:
title = sectionname
reference = nodes.reference('', title, internal=True,
Expand Down
2 changes: 1 addition & 1 deletion sphinx/environment/collectors/toctree.py
Expand Up @@ -236,7 +236,7 @@ def _walk_toctree(toctreenode: addnodes.toctree, depth: int) -> None:

def assign_figure_numbers(self, env: BuildEnvironment) -> List[str]:
"""Assign a figure number to each figure under a numbered toctree."""
generated_docnames = frozenset(env.domains['std'].initial_data['labels'].keys())
generated_docnames = frozenset(env.domains['std']._virtual_doc_names)

rewrite_needed = []

Expand Down
10 changes: 3 additions & 7 deletions sphinx/ext/autodoc/preserve_defaults.py
Expand Up @@ -6,8 +6,6 @@

import ast
import inspect
import sys
from inspect import Parameter
from typing import Any, Dict, List, Optional

from sphinx.application import Sphinx
Expand Down Expand Up @@ -48,8 +46,6 @@ def get_function_def(obj: Any) -> Optional[ast.FunctionDef]:

def get_default_value(lines: List[str], position: ast.AST) -> Optional[str]:
try:
if sys.version_info[:2] <= (3, 7): # only for py38+
return None
if position.lineno == position.end_lineno:
line = lines[position.lineno - 1]
return line[position.col_offset:position.end_col_offset]
Expand Down Expand Up @@ -89,18 +85,18 @@ def update_defvalue(app: Sphinx, obj: Any, bound_method: bool) -> None:
default = defaults.pop(0)
value = get_default_value(lines, default)
if value is None:
value = ast_unparse(default) # type: ignore
value = ast_unparse(default)
parameters[i] = param.replace(default=DefaultValue(value))
else:
default = kw_defaults.pop(0)
value = get_default_value(lines, default)
if value is None:
value = ast_unparse(default) # type: ignore
value = ast_unparse(default)
parameters[i] = param.replace(default=DefaultValue(value))

if bound_method and inspect.ismethod(obj):
# classmethods
cls = inspect.Parameter('cls', Parameter.POSITIONAL_OR_KEYWORD)
cls = inspect.Parameter('cls', inspect.Parameter.POSITIONAL_OR_KEYWORD)
parameters.insert(0, cls)

sig = sig.replace(parameters=parameters)
Expand Down
11 changes: 5 additions & 6 deletions sphinx/ext/autodoc/type_comment.py
@@ -1,12 +1,12 @@
"""Update annotations info of living objects using type_comments."""

import ast
from inspect import Parameter, Signature, getsource
from typing import Any, Dict, List, cast

import sphinx
from sphinx.application import Sphinx
from sphinx.locale import __
from sphinx.pycode.ast import ast
from sphinx.pycode.ast import parse as ast_parse
from sphinx.pycode.ast import unparse as ast_unparse
from sphinx.util import inspect, logging
Expand Down Expand Up @@ -34,10 +34,9 @@ def signature_from_ast(node: ast.FunctionDef, bound_method: bool,
:param bound_method: Specify *node* is a bound method or not
"""
params = []
if hasattr(node.args, "posonlyargs"): # for py38+
for arg in node.args.posonlyargs: # type: ignore
param = Parameter(arg.arg, Parameter.POSITIONAL_ONLY, annotation=arg.type_comment)
params.append(param)
for arg in node.args.posonlyargs:
param = Parameter(arg.arg, Parameter.POSITIONAL_ONLY, annotation=arg.type_comment)
params.append(param)

for arg in node.args.args:
param = Parameter(arg.arg, Parameter.POSITIONAL_OR_KEYWORD,
Expand Down Expand Up @@ -80,7 +79,7 @@ def get_type_comment(obj: Any, bound_method: bool = False) -> Signature:
"""Get type_comment'ed FunctionDef object from living object.
This tries to parse original code for living object and returns
Signature for given *obj*. It requires py38+ or typed_ast module.
Signature for given *obj*.
"""
try:
source = getsource(obj)
Expand Down

0 comments on commit 4660b62

Please sign in to comment.