Skip to content

Commit dac1228

Browse files
committed
chore: Remove Python 3.8 and 3.9 support
Signed-off-by: Dmitry Dygalo <dmitry@dygalo.dev>
1 parent 83db553 commit dac1228

26 files changed

Lines changed: 177 additions & 244 deletions

.github/workflows/build.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525

2626
- uses: actions/setup-python@v6.2.0
2727
with:
28-
python-version: 3.9
28+
python-version: "3.14"
2929

3030
- uses: j178/prek-action@v2.0.4
3131
with:
@@ -41,7 +41,7 @@ jobs:
4141

4242
- uses: actions/setup-python@v6.2.0
4343
with:
44-
python-version: 3.9
44+
python-version: "3.14"
4545

4646
- uses: j178/prek-action@v2.0.4
4747
with:
@@ -51,7 +51,7 @@ jobs:
5151
strategy:
5252
matrix:
5353
os: [ubuntu-24.04]
54-
python: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
54+
python: ["3.10", "3.11", "3.12", "3.13", "3.14"]
5555

5656
name: ${{ matrix.os }}/tests_${{ matrix.python }}
5757
runs-on: ${{ matrix.os }}

.github/workflows/release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ jobs:
1111
runs-on: ubuntu-24.04
1212
steps:
1313
- uses: actions/checkout@v6.0.2
14-
- name: Set up Python 3.9
14+
- name: Set up Python
1515
uses: actions/setup-python@v6.2.0
1616
with:
17-
python-version: 3.9
17+
python-version: "3.14"
1818

1919
- run: pip install hatch
2020

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010

1111
- Much faster generation - up to ~180x on large and negative-mode cases.
1212

13+
### Removed
14+
15+
- Python 3.8 and 3.9 support.
16+
1317
## [0.12.0] - 2026-02-04
1418

1519
### Added

benchmarks/_schemas.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import json
22
import pathlib
3-
from typing import Dict, Optional
43

54
import graphql
65
from hypothesis import strategies as st
@@ -38,12 +37,12 @@
3837
PLACEHOLDER_STRATEGY = st.just("placeholder").map(nodes.String)
3938

4039

41-
def _load_corpus() -> Dict[str, str]:
40+
def _load_corpus() -> dict[str, str]:
4241
with open(_CORPUS_PATH) as fd:
4342
return json.load(fd)
4443

4544

46-
def custom_scalars_for(schema: str) -> Optional[Dict[str, st.SearchStrategy]]:
45+
def custom_scalars_for(schema: str) -> dict[str, st.SearchStrategy] | None:
4746
parsed = graphql.build_schema(schema)
4847
custom = {
4948
name: PLACEHOLDER_STRATEGY
@@ -53,7 +52,7 @@ def custom_scalars_for(schema: str) -> Optional[Dict[str, st.SearchStrategy]]:
5352
return custom or None
5453

5554

56-
def load_schemas() -> Dict[str, str]:
55+
def load_schemas() -> dict[str, str]:
5756
corpus = _load_corpus()
5857
schemas = {"recursive": RECURSIVE_SCHEMA}
5958
for label, name in _CORPUS_SELECTION.items():

mypy.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[mypy]
2-
python_version = 3.9
2+
python_version = 3.10
33
show_error_context = true
44
verbosity = 0
55
ignore_missing_imports = true

pyproject.toml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ classifiers = [
1515
"License :: OSI Approved :: MIT License",
1616
"Operating System :: OS Independent",
1717
"Programming Language :: Python :: 3 :: Only",
18-
"Programming Language :: Python :: 3.8",
19-
"Programming Language :: Python :: 3.9",
2018
"Programming Language :: Python :: 3.10",
2119
"Programming Language :: Python :: 3.11",
2220
"Programming Language :: Python :: 3.12",
@@ -30,7 +28,7 @@ maintainers = [{ name = "Dmitry Dygalo", email = "dmitry@dygalo.dev" }]
3028
readme = "README.md"
3129
license = "MIT"
3230
include = ["src/hypothesis_graphql/py.typed"]
33-
requires-python = ">=3.8"
31+
requires-python = ">=3.10"
3432
dependencies = ["hypothesis>=6.84.3,<7.0", "graphql-core>=3.1.0,<3.3.0"]
3533

3634
[project.optional-dependencies]
@@ -64,7 +62,7 @@ exclude_lines = ["pragma: no cover", "raise NotImplementedError", "if TYPE_CHECK
6462

6563
[tool.ruff]
6664
line-length = 120
67-
target-version = "py38"
65+
target-version = "py310"
6866

6967
[tool.ruff.lint]
7068
select = [

src/hypothesis_graphql/_strategies/aliases.py

Lines changed: 0 additions & 45 deletions
This file was deleted.

src/hypothesis_graphql/_strategies/ast.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
import graphql
24

35
from ..types import SelectionNodes

src/hypothesis_graphql/_strategies/builder.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,42 @@
1-
from typing import Dict, List, Optional, Sequence, Tuple
1+
from __future__ import annotations
2+
3+
from collections.abc import Sequence
24

35
import graphql
46
from graphql import is_equal_type
57

68
from .strategy import make_type_name
79

810
# (field_name, on_type, children, arguments)
9-
SelectionNode = Tuple[str, Optional[str], "List[SelectionNode]", List[graphql.ArgumentNode]]
11+
SelectionNode = tuple[str, str | None, "list[SelectionNode]", list[graphql.ArgumentNode]]
1012

1113

1214
def _field_node(
13-
name: str, children: Sequence[graphql.SelectionNode], args: List[graphql.ArgumentNode]
15+
name: str, children: Sequence[graphql.SelectionNode], args: list[graphql.ArgumentNode]
1416
) -> graphql.FieldNode:
1517
selection_set = graphql.SelectionSetNode(selections=tuple(children)) if children else None
1618
return graphql.FieldNode(name=graphql.NameNode(value=name), arguments=tuple(args), selection_set=selection_set)
1719

1820

1921
def build_selection_set(
20-
nodes: "List[SelectionNode]", type_map: Optional[Dict[str, graphql.GraphQLNamedType]] = None
22+
nodes: list[SelectionNode], type_map: dict[str, graphql.GraphQLNamedType] | None = None
2123
) -> graphql.SelectionSetNode:
22-
selections: List[graphql.SelectionNode] = []
24+
selections: list[graphql.SelectionNode] = []
2325
for name, on, children, args in nodes:
2426
if on is not None:
2527
continue
2628
child = list(build_selection_set(children, type_map).selections) if children else []
2729
selections.append(_field_node(name, child, args))
2830

29-
seen: Dict[str, graphql.GraphQLType] = {}
30-
by_type: Dict[str, List[SelectionNode]] = {}
31+
seen: dict[str, graphql.GraphQLType] = {}
32+
by_type: dict[str, list[SelectionNode]] = {}
3133
for node in nodes:
3234
if node[1] is not None:
3335
by_type.setdefault(node[1], []).append(node)
3436
for on_type in sorted(by_type):
3537
assert type_map is not None
3638
fragment_type = type_map[on_type]
37-
frag_fields: List[graphql.SelectionNode] = []
39+
frag_fields: list[graphql.SelectionNode] = []
3840
for name, _on_type, children, args in by_type[on_type]:
3941
field_type = fragment_type.fields[name].type
4042
child = list(build_selection_set(children, type_map).selections) if children else []

src/hypothesis_graphql/_strategies/containers.py

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)