Skip to content

Commit e4be30a

Browse files
committed
refactor: Drop Python 3.7 support
- Drop support in pyproject.toml - Remove Python 3.7 dependencies - Remove Python 3.7 related code - Enable Mypy warn unused (remove unused)
1 parent 0bab0c4 commit e4be30a

27 files changed

Lines changed: 114 additions & 309 deletions

config/mypy.ini

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
[mypy]
22
ignore_missing_imports = true
33
exclude = tests/fixtures/
4-
# TODO: set to true once Python 3.7 is dropped
5-
warn_unused_ignores = false
4+
warn_unused_ignores = true
65
show_error_codes = true

config/ruff.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
target-version = "py37"
1+
target-version = "py38"
22
line-length = 132
33
exclude = [
44
"fixtures",

duties.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,13 @@
44

55
import os
66
import sys
7+
from importlib.metadata import version as pkgversion
78
from pathlib import Path
89
from typing import TYPE_CHECKING, Any
910

1011
from duty import duty
1112
from duty.callables import black, blacken_docs, coverage, lazy, mkdocs, mypy, pytest, ruff, safety
1213

13-
if sys.version_info < (3, 8):
14-
from importlib_metadata import version as pkgversion
15-
else:
16-
from importlib.metadata import version as pkgversion
17-
18-
1914
if TYPE_CHECKING:
2015
from duty.context import Context
2116

pyproject.toml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,15 @@ to generate API documentation or find breaking changes in your API."""
1010
authors = [{name = "Timothée Mazzucotelli", email = "pawamoy@pm.me"}]
1111
license = {text = "ISC"}
1212
readme = "README.md"
13-
requires-python = ">=3.7"
14-
keywords = []
13+
requires-python = ">=3.8"
14+
keywords = ["api", "signature", "breaking-changes", "static-analysis", "dynamic-analysis"]
1515
dynamic = ["version"]
1616
classifiers = [
1717
"Development Status :: 4 - Beta",
1818
"Intended Audience :: Developers",
1919
"Programming Language :: Python",
2020
"Programming Language :: Python :: 3",
2121
"Programming Language :: Python :: 3 :: Only",
22-
"Programming Language :: Python :: 3.7",
2322
"Programming Language :: Python :: 3.8",
2423
"Programming Language :: Python :: 3.9",
2524
"Programming Language :: Python :: 3.10",
@@ -32,7 +31,6 @@ classifiers = [
3231
"Typing :: Typed",
3332
]
3433
dependencies = [
35-
"cached-property; python_version < '3.8'",
3634
"colorama>=0.4",
3735
]
3836

scripts/gen_credits.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from __future__ import annotations
44

55
import re
6-
import sys
6+
from importlib.metadata import PackageNotFoundError, metadata
77
from itertools import chain
88
from pathlib import Path
99
from textwrap import dedent
@@ -13,11 +13,6 @@
1313
from jinja2 import StrictUndefined
1414
from jinja2.sandbox import SandboxedEnvironment
1515

16-
if sys.version_info < (3, 8):
17-
from importlib_metadata import PackageNotFoundError, metadata
18-
else:
19-
from importlib.metadata import PackageNotFoundError, metadata
20-
2116
project_dir = Path(".")
2217
pyproject = toml.load(project_dir / "pyproject.toml")
2318
project = pyproject["project"]

src/griffe/agents/inspector.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
from __future__ import annotations
2424

2525
import ast
26-
import sys
2726
from inspect import Parameter as SignatureParameter
2827
from inspect import Signature, cleandoc, getmodule, ismodule
2928
from inspect import signature as getsignature
@@ -53,10 +52,7 @@
5352
from griffe.expressions import Expression, Name
5453

5554

56-
if sys.version_info < (3, 8):
57-
from cached_property import cached_property
58-
else:
59-
from functools import cached_property
55+
from functools import cached_property
6056

6157
empty = Signature.empty
6258

src/griffe/agents/nodes.py

Lines changed: 12 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@
4848
from ast import Mod as NodeMod
4949
from ast import Mult as NodeMult
5050
from ast import Name as NodeName
51+
from ast import NamedExpr as NodeNamedExpr
5152
from ast import Not as NodeNot
5253
from ast import NotEq as NodeNotEq
5354
from ast import NotIn as NodeNotIn
54-
from ast import Num as NodeNum
5555
from ast import Or as NodeOr
5656
from ast import Pow as NodePow
5757
from ast import RShift as NodeRShift
@@ -72,26 +72,13 @@
7272
from ast import comprehension as NodeComprehension
7373
from ast import keyword as NodeKeyword
7474
from contextlib import contextmanager, suppress
75-
from functools import partial
75+
from functools import cached_property, partial
7676
from typing import TYPE_CHECKING, Any, Callable, ClassVar, Iterator, Sequence
7777

7878
from griffe.exceptions import LastNodeError, RootNodeError
7979
from griffe.expressions import Expression, Name
8080
from griffe.logger import LogLevel, get_logger
8181

82-
# TODO: remove condition once Python 3.7 support is dropped
83-
if sys.version_info >= (3, 8):
84-
from ast import NamedExpr as NodeNamedExpr
85-
86-
# TODO: remove once Python 3.7 support is dropped
87-
if sys.version_info < (3, 8):
88-
from ast import Bytes as NodeBytes
89-
from ast import NameConstant as NodeNameConstant
90-
91-
from cached_property import cached_property
92-
else:
93-
from functools import cached_property
94-
9582
# TODO: remove once Python 3.8 support is dropped
9683
if sys.version_info < (3, 9):
9784
from ast import ExtSlice as NodeExtSlice
@@ -112,10 +99,6 @@ class ASTNode:
11299

113100
parent: ASTNode
114101

115-
# TODO: remove once Python 3.7 support is dropped
116-
if sys.version_info < (3, 8):
117-
end_lineno = property(lambda _: None)
118-
119102
@cached_property
120103
def kind(self) -> str:
121104
"""Return the kind of this node.
@@ -544,16 +527,8 @@ def __init__(self, parent: Module) -> None:
544527
NodeBinOp: self._extract_binop,
545528
}
546529

547-
# TODO: remove once Python 3.7 support is dropped
548-
if sys.version_info < (3, 8):
549-
self._node_map[NodeNameConstant] = self._extract_nameconstant # type: ignore[assignment]
550-
self._node_map[NodeStr] = self._extract_str # type: ignore[assignment]
551-
552530
def _extract_constant(self, node: NodeConstant) -> list[str]:
553-
try:
554-
return [node.value]
555-
except AttributeError:
556-
return [node.s] # TODO: remove once Python 3.7 is dropped
531+
return [node.value]
557532

558533
def _extract_name(self, node: NodeName) -> list[Name]:
559534
return [Name(node.id, partial(self.parent.resolve, node.id))]
@@ -572,15 +547,6 @@ def _extract_binop(self, node: NodeBinOp) -> list[str | Name]:
572547
right = self._extract(node.right)
573548
return left + right
574549

575-
# TODO: remove once Python 3.7 support is dropped
576-
if sys.version_info < (3, 8):
577-
578-
def _extract_nameconstant(self, node: NodeNameConstant) -> list[Name]:
579-
return [node.value]
580-
581-
def _extract_str(self, node: NodeStr) -> list[str]:
582-
return [node.s]
583-
584550
def _extract(self, node: AST) -> list[str | Name]:
585551
return self._node_map[type(node)](node)
586552

@@ -621,7 +587,7 @@ def safe_get__all__(
621587
except Exception as error: # noqa: BLE001
622588
message = f"Failed to extract `__all__` value: {get_value(node.value)}"
623589
with suppress(Exception):
624-
message += f" at {parent.relative_filepath}:{node.lineno}" # type: ignore[union-attr]
590+
message += f" at {parent.relative_filepath}:{node.lineno}"
625591
if isinstance(error, KeyError):
626592
message += f": unsupported node {error}"
627593
else:
@@ -672,13 +638,6 @@ def __init__(self, parent: Module | Class, *, parse_strings: bool | None = None)
672638
if sys.version_info < (3, 9):
673639
self._node_map[NodeIndex] = self._build_index
674640

675-
# TODO: remove once Python 3.7 support is dropped
676-
if sys.version_info < (3, 8):
677-
self._node_map[NodeBytes] = self._build_bytes
678-
self._node_map[NodeNameConstant] = self._build_nameconstant
679-
self._node_map[NodeNum] = self._build_num
680-
self._node_map[NodeStr] = self._build_str
681-
682641
@contextmanager
683642
def literal_strings(self) -> Iterator[None]:
684643
self._literal_strings = True
@@ -798,22 +757,6 @@ def _build_usub(self, node: NodeUSub) -> str: # noqa: ARG002
798757
def _build_index(self, node: NodeIndex) -> str | Name | Expression:
799758
return self._build(node.value)
800759

801-
# TODO: remove once Python 3.7 support is dropped
802-
if sys.version_info < (3, 8):
803-
804-
def _build_bytes(self, node: NodeBytes) -> str:
805-
return repr(node.s)
806-
807-
def _build_nameconstant(self, node: NodeNameConstant) -> str:
808-
return repr(node.value)
809-
810-
def _build_num(self, node: NodeNum) -> str:
811-
return repr(node.n)
812-
813-
def _build_str(self, node: NodeStr) -> str | Name:
814-
node.value = node.s # type: ignore[attr-defined] # fake node as constant
815-
return self._node_map[NodeConstant](node) # type: ignore[return-value]
816-
817760
def _build(self, node: AST) -> str | Name | Expression:
818761
return self._node_map[type(node)](node)
819762

@@ -922,16 +865,10 @@ def get_docstring(
922865
else:
923866
return None, None, None
924867
if isinstance(doc, NodeConstant) and isinstance(doc.value, str):
925-
return doc.value, doc.lineno, doc.end_lineno # type: ignore[attr-defined]
868+
return doc.value, doc.lineno, doc.end_lineno
926869
if isinstance(doc, NodeStr):
927-
# TODO: remove once Python 3.7 support is dropped
928-
# on Python 3.7, lineno seems to be the ending line of the string
929-
# rather than the starting one, so we substract the number of newlines
930870
lineno = doc.lineno
931-
if sys.version_info < (3, 8):
932-
lineno -= doc.s.count("\n")
933-
934-
return doc.s, lineno, doc.end_lineno # type: ignore[attr-defined]
871+
return doc.s, lineno, doc.end_lineno
935872
return None, None, None
936873

937874

@@ -1001,22 +938,13 @@ def __init__(self) -> None:
1001938
NodeYield: self._extract_yield,
1002939
}
1003940

1004-
# TODO: remove condition once Python 3.7 support is dropped
1005-
if sys.version_info >= (3, 8):
1006-
self._node_map[NodeNamedExpr] = self._extract_named_expr
941+
self._node_map[NodeNamedExpr] = self._extract_named_expr
1007942

1008943
# TODO: remove once Python 3.8 support is dropped
1009944
if sys.version_info < (3, 9):
1010945
self._node_map[NodeExtSlice] = self._extract_extslice
1011946
self._node_map[NodeIndex] = self._extract_index
1012947

1013-
# TODO: remove once Python 3.7 support is dropped
1014-
if sys.version_info < (3, 8):
1015-
self._node_map[NodeBytes] = self._extract_bytes
1016-
self._node_map[NodeNameConstant] = self._extract_nameconstant
1017-
self._node_map[NodeNum] = self._extract_num
1018-
self._node_map[NodeStr] = self._extract_str
1019-
1020948
def _extract_add(self, node: NodeAdd) -> str: # noqa: ARG002
1021949
return "+"
1022950

@@ -1237,13 +1165,10 @@ def _extract_yield(self, node: NodeYield) -> str:
12371165
return repr(None)
12381166
return self._extract(node.value)
12391167

1240-
# TODO: remove condition once Python 3.7 support is dropped
1241-
if sys.version_info >= (3, 8):
1242-
1243-
def _extract_named_expr(self, node: NodeNamedExpr) -> str:
1244-
return f"({self._extract(node.target)} := {self._extract(node.value)})"
1168+
def _extract_named_expr(self, node: NodeNamedExpr) -> str:
1169+
return f"({self._extract(node.target)} := {self._extract(node.value)})"
12451170

1246-
# TODO: remove once Python 3.8 support is dropped
1171+
# TODO: remove once Python 3.8 support is
12471172
if sys.version_info < (3, 9):
12481173

12491174
def _extract_extslice(self, node: NodeExtSlice) -> str:
@@ -1252,21 +1177,6 @@ def _extract_extslice(self, node: NodeExtSlice) -> str:
12521177
def _extract_index(self, node: NodeIndex) -> str:
12531178
return self._extract(node.value)
12541179

1255-
# TODO: remove once Python 3.7 support is dropped
1256-
if sys.version_info < (3, 8):
1257-
1258-
def _extract_bytes(self, node: NodeBytes) -> str:
1259-
return repr(node.s)
1260-
1261-
def _extract_nameconstant(self, node: NodeNameConstant) -> str:
1262-
return repr(node.value)
1263-
1264-
def _extract_num(self, node: NodeNum) -> str:
1265-
return repr(node.n)
1266-
1267-
def _extract_str(self, node: NodeStr) -> str:
1268-
return repr(node.s)
1269-
12701180
def _extract(self, node: AST) -> str:
12711181
return self._node_map[type(node)](node)
12721182

@@ -1394,8 +1304,8 @@ def get_parameter_default(node: AST | None, filepath: Path, lines_collection: Li
13941304
default = safe_get_value(node)
13951305
if default is not None:
13961306
return default
1397-
if node.lineno == node.end_lineno: # type: ignore[attr-defined]
1398-
return lines_collection[filepath][node.lineno - 1][node.col_offset : node.end_col_offset] # type: ignore[attr-defined]
1307+
if node.lineno == node.end_lineno:
1308+
return lines_collection[filepath][node.lineno - 1][node.col_offset : node.end_col_offset]
13991309
# TODO: handle multiple line defaults
14001310
return None
14011311

0 commit comments

Comments
 (0)