Skip to content

Commit 056232a

Browse files
authored
➖ Drop support for Python 3.8 (#1696)
1 parent 028ad29 commit 056232a

21 files changed

+185
-224
lines changed

pdm_build.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import os
2-
from typing import Any, Dict, List
2+
from typing import Any
33

44
from pdm.backend.hooks import Context
55

@@ -9,30 +9,30 @@
99
def pdm_build_initialize(context: Context) -> None:
1010
metadata = context.config.metadata
1111
# Get custom config for the current package, from the env var
12-
config: Dict[str, Any] = context.config.data["tool"]["tiangolo"][
12+
config: dict[str, Any] = context.config.data["tool"]["tiangolo"][
1313
"_internal-slim-build"
1414
]["packages"][TIANGOLO_BUILD_PACKAGE]
15-
project_config: Dict[str, Any] = config["project"]
15+
project_config: dict[str, Any] = config["project"]
1616
# Get main optional dependencies, extras
17-
optional_dependencies: Dict[str, List[str]] = metadata.get(
17+
optional_dependencies: dict[str, list[str]] = metadata.get(
1818
"optional-dependencies", {}
1919
)
2020
# Get custom optional dependencies name to always include in this (non-slim) package
21-
include_optional_dependencies: List[str] = config.get(
21+
include_optional_dependencies: list[str] = config.get(
2222
"include-optional-dependencies", []
2323
)
2424
# Override main [project] configs with custom configs for this package
2525
for key, value in project_config.items():
2626
metadata[key] = value
2727
# Get custom build config for the current package
28-
build_config: Dict[str, Any] = (
28+
build_config: dict[str, Any] = (
2929
config.get("tool", {}).get("pdm", {}).get("build", {})
3030
)
3131
# Override PDM build config with custom build config for this package
3232
for key, value in build_config.items():
3333
context.config.build_config[key] = value
3434
# Get main dependencies
35-
dependencies: List[str] = metadata.get("dependencies", [])
35+
dependencies: list[str] = metadata.get("dependencies", [])
3636
# Add optional dependencies to the default dependencies for this (non-slim) package
3737
for include_optional in include_optional_dependencies:
3838
optional_dependencies_group = optional_dependencies.get(include_optional, [])

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ name = "sqlmodel"
77
dynamic = ["version"]
88
description = "SQLModel, SQL databases in Python, designed for simplicity, compatibility, and robustness."
99
readme = "README.md"
10-
requires-python = ">=3.8"
10+
requires-python = ">=3.9"
1111
authors = [
1212
{ name = "Sebastián Ramírez", email = "[email protected]" },
1313
]
@@ -21,7 +21,6 @@ classifiers = [
2121
"Intended Audience :: Science/Research",
2222
"Intended Audience :: System Administrators",
2323
"Programming Language :: Python :: 3 :: Only",
24-
"Programming Language :: Python :: 3.8",
2524
"Programming Language :: Python :: 3.9",
2625
"Programming Language :: Python :: 3.10",
2726
"Programming Language :: Python :: 3.11",

scripts/generate_select.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import os
22
from itertools import product
33
from pathlib import Path
4-
from typing import List, Tuple
54

65
import black
76
from jinja2 import Template
@@ -21,15 +20,15 @@ class Arg(BaseModel):
2120
annotation: str
2221

2322

24-
arg_groups: List[Arg] = []
23+
arg_groups: list[Arg] = []
2524

26-
signatures: List[Tuple[List[Arg], List[str]]] = []
25+
signatures: list[tuple[list[Arg], list[str]]] = []
2726

2827
for total_args in range(2, number_of_types + 1):
2928
arg_types_tuples = product(["model", "scalar"], repeat=total_args)
3029
for arg_type_tuple in arg_types_tuples:
31-
args: List[Arg] = []
32-
return_types: List[str] = []
30+
args: list[Arg] = []
31+
return_types: list[str] = []
3332
for i, arg_type in enumerate(arg_type_tuple):
3433
if arg_type == "scalar":
3534
t_var = f"_TScalar_{i}"

scripts/mkdocs_hooks.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, List, Union
1+
from typing import Any, Union
22

33
from mkdocs.config.defaults import MkDocsConfig
44
from mkdocs.structure.files import Files
@@ -7,9 +7,9 @@
77

88

99
def generate_renamed_section_items(
10-
items: List[Union[Page, Section, Link]], *, config: MkDocsConfig
11-
) -> List[Union[Page, Section, Link]]:
12-
new_items: List[Union[Page, Section, Link]] = []
10+
items: list[Union[Page, Section, Link]], *, config: MkDocsConfig
11+
) -> list[Union[Page, Section, Link]]:
12+
new_items: list[Union[Page, Section, Link]] = []
1313
for item in items:
1414
if isinstance(item, Section):
1515
new_title = item.title

sqlmodel/_compat.py

Lines changed: 32 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,24 @@
11
import sys
22
import types
3+
from collections.abc import Generator, Mapping, Set
34
from contextlib import contextmanager
45
from contextvars import ContextVar
56
from dataclasses import dataclass
67
from typing import (
78
TYPE_CHECKING,
8-
AbstractSet,
9+
Annotated,
910
Any,
1011
Callable,
11-
Dict,
1212
ForwardRef,
13-
Generator,
14-
Mapping,
1513
Optional,
16-
Set,
17-
Type,
1814
TypeVar,
1915
Union,
2016
)
2117

2218
from pydantic import VERSION as P_VERSION
2319
from pydantic import BaseModel
2420
from pydantic.fields import FieldInfo
25-
from typing_extensions import Annotated, get_args, get_origin
21+
from typing_extensions import get_args, get_origin
2622

2723
# Reassign variable to make it reexported for mypy
2824
PYDANTIC_VERSION = P_VERSION
@@ -36,7 +32,7 @@
3632
UnionType = getattr(types, "UnionType", Union)
3733
NoneType = type(None)
3834
T = TypeVar("T")
39-
InstanceOrType = Union[T, Type[T]]
35+
InstanceOrType = Union[T, type[T]]
4036
_TSQLModel = TypeVar("_TSQLModel", bound="SQLModel")
4137

4238

@@ -49,7 +45,7 @@ class FakeMetadata:
4945
@dataclass
5046
class ObjectWithUpdateWrapper:
5147
obj: Any
52-
update: Dict[str, Any]
48+
update: dict[str, Any]
5349

5450
def __getattribute__(self, __name: str) -> Any:
5551
update = super().__getattribute__("update")
@@ -103,7 +99,7 @@ def set_config_value(
10399
) -> None:
104100
model.model_config[parameter] = value # type: ignore[literal-required]
105101

106-
def get_model_fields(model: InstanceOrType[BaseModel]) -> Dict[str, "FieldInfo"]:
102+
def get_model_fields(model: InstanceOrType[BaseModel]) -> dict[str, "FieldInfo"]:
107103
# TODO: refactor the usage of this function to always pass the class
108104
# not the instance, and then remove this extra check
109105
# this is for compatibility with Pydantic v3
@@ -115,16 +111,16 @@ def get_model_fields(model: InstanceOrType[BaseModel]) -> Dict[str, "FieldInfo"]
115111

116112
def get_fields_set(
117113
object: InstanceOrType["SQLModel"],
118-
) -> Union[Set[str], Callable[[BaseModel], Set[str]]]:
114+
) -> Union[set[str], Callable[[BaseModel], set[str]]]:
119115
return object.model_fields_set
120116

121117
def init_pydantic_private_attrs(new_object: InstanceOrType["SQLModel"]) -> None:
122118
object.__setattr__(new_object, "__pydantic_fields_set__", set())
123119
object.__setattr__(new_object, "__pydantic_extra__", None)
124120
object.__setattr__(new_object, "__pydantic_private__", None)
125121

126-
def get_annotations(class_dict: Dict[str, Any]) -> Dict[str, Any]:
127-
raw_annotations: Dict[str, Any] = class_dict.get("__annotations__", {})
122+
def get_annotations(class_dict: dict[str, Any]) -> dict[str, Any]:
123+
raw_annotations: dict[str, Any] = class_dict.get("__annotations__", {})
128124
if sys.version_info >= (3, 14) and "__annotations__" not in class_dict:
129125
# See https://github.com/pydantic/pydantic/pull/11991
130126
from annotationlib import (
@@ -139,7 +135,7 @@ def get_annotations(class_dict: Dict[str, Any]) -> Dict[str, Any]:
139135
)
140136
return raw_annotations
141137

142-
def is_table_model_class(cls: Type[Any]) -> bool:
138+
def is_table_model_class(cls: type[Any]) -> bool:
143139
config = getattr(cls, "model_config", {})
144140
if config:
145141
return config.get("table", False) or False
@@ -243,15 +239,15 @@ def _calculate_keys(
243239
include: Optional[Mapping[Union[int, str], Any]],
244240
exclude: Optional[Mapping[Union[int, str], Any]],
245241
exclude_unset: bool,
246-
update: Optional[Dict[str, Any]] = None,
247-
) -> Optional[AbstractSet[str]]: # pragma: no cover
242+
update: Optional[dict[str, Any]] = None,
243+
) -> Optional[Set[str]]: # pragma: no cover
248244
return None
249245

250246
def sqlmodel_table_construct(
251247
*,
252248
self_instance: _TSQLModel,
253-
values: Dict[str, Any],
254-
_fields_set: Union[Set[str], None] = None,
249+
values: dict[str, Any],
250+
_fields_set: Union[set[str], None] = None,
255251
) -> _TSQLModel:
256252
# Copy from Pydantic's BaseModel.construct()
257253
# Ref: https://github.com/pydantic/pydantic/blob/v2.5.2/pydantic/main.py#L198
@@ -264,8 +260,8 @@ def sqlmodel_table_construct(
264260
old_dict = self_instance.__dict__.copy()
265261
# End SQLModel override
266262

267-
fields_values: Dict[str, Any] = {}
268-
defaults: Dict[
263+
fields_values: dict[str, Any] = {}
264+
defaults: dict[
269265
str, Any
270266
] = {} # keeping this separate from `fields_values` helps us compute `_fields_set`
271267
for name, field in cls.model_fields.items():
@@ -279,7 +275,7 @@ def sqlmodel_table_construct(
279275
_fields_set = set(fields_values.keys())
280276
fields_values.update(defaults)
281277

282-
_extra: Union[Dict[str, Any], None] = None
278+
_extra: Union[dict[str, Any], None] = None
283279
if cls.model_config.get("extra") == "allow":
284280
_extra = {}
285281
for k, v in values.items():
@@ -315,13 +311,13 @@ def sqlmodel_table_construct(
315311
return self_instance
316312

317313
def sqlmodel_validate(
318-
cls: Type[_TSQLModel],
314+
cls: type[_TSQLModel],
319315
obj: Any,
320316
*,
321317
strict: Union[bool, None] = None,
322318
from_attributes: Union[bool, None] = None,
323-
context: Union[Dict[str, Any], None] = None,
324-
update: Union[Dict[str, Any], None] = None,
319+
context: Union[dict[str, Any], None] = None,
320+
update: Union[dict[str, Any], None] = None,
325321
) -> _TSQLModel:
326322
if not is_table_model_class(cls):
327323
new_obj: _TSQLModel = cls.__new__(cls)
@@ -366,7 +362,7 @@ def sqlmodel_validate(
366362
setattr(new_obj, key, value)
367363
return new_obj
368364

369-
def sqlmodel_init(*, self: "SQLModel", data: Dict[str, Any]) -> None:
365+
def sqlmodel_init(*, self: "SQLModel", data: dict[str, Any]) -> None:
370366
old_dict = self.__dict__.copy()
371367
if not is_table_model_class(self.__class__):
372368
self.__pydantic_validator__.validate_python(
@@ -424,24 +420,24 @@ def set_config_value(
424420
) -> None:
425421
setattr(model.__config__, parameter, value) # type: ignore
426422

427-
def get_model_fields(model: InstanceOrType[BaseModel]) -> Dict[str, "FieldInfo"]:
423+
def get_model_fields(model: InstanceOrType[BaseModel]) -> dict[str, "FieldInfo"]:
428424
return model.__fields__ # type: ignore
429425

430426
def get_fields_set(
431427
object: InstanceOrType["SQLModel"],
432-
) -> Union[Set[str], Callable[[BaseModel], Set[str]]]:
428+
) -> Union[set[str], Callable[[BaseModel], set[str]]]:
433429
return object.__fields_set__
434430

435431
def init_pydantic_private_attrs(new_object: InstanceOrType["SQLModel"]) -> None:
436432
object.__setattr__(new_object, "__fields_set__", set())
437433

438-
def get_annotations(class_dict: Dict[str, Any]) -> Dict[str, Any]:
434+
def get_annotations(class_dict: dict[str, Any]) -> dict[str, Any]:
439435
return resolve_annotations( # type: ignore[no-any-return]
440436
class_dict.get("__annotations__", {}),
441437
class_dict.get("__module__", None),
442438
)
443439

444-
def is_table_model_class(cls: Type[Any]) -> bool:
440+
def is_table_model_class(cls: type[Any]) -> bool:
445441
config = getattr(cls, "__config__", None)
446442
if config:
447443
return getattr(config, "table", False)
@@ -492,8 +488,8 @@ def _calculate_keys(
492488
include: Optional[Mapping[Union[int, str], Any]],
493489
exclude: Optional[Mapping[Union[int, str], Any]],
494490
exclude_unset: bool,
495-
update: Optional[Dict[str, Any]] = None,
496-
) -> Optional[AbstractSet[str]]:
491+
update: Optional[dict[str, Any]] = None,
492+
) -> Optional[Set[str]]:
497493
if include is None and exclude is None and not exclude_unset:
498494
# Original in Pydantic:
499495
# return None
@@ -504,7 +500,7 @@ def _calculate_keys(
504500
self.__fields__.keys() # noqa
505501
) # | self.__sqlmodel_relationships__.keys()
506502

507-
keys: AbstractSet[str]
503+
keys: Set[str]
508504
if exclude_unset:
509505
keys = self.__fields_set__.copy() # noqa
510506
else:
@@ -528,13 +524,13 @@ def _calculate_keys(
528524
return keys
529525

530526
def sqlmodel_validate(
531-
cls: Type[_TSQLModel],
527+
cls: type[_TSQLModel],
532528
obj: Any,
533529
*,
534530
strict: Union[bool, None] = None,
535531
from_attributes: Union[bool, None] = None,
536-
context: Union[Dict[str, Any], None] = None,
537-
update: Union[Dict[str, Any], None] = None,
532+
context: Union[dict[str, Any], None] = None,
533+
update: Union[dict[str, Any], None] = None,
538534
) -> _TSQLModel:
539535
# This was SQLModel's original from_orm() for Pydantic v1
540536
# Duplicated from Pydantic
@@ -573,7 +569,7 @@ def sqlmodel_validate(
573569
m._init_private_attributes() # type: ignore[attr-defined] # noqa
574570
return m
575571

576-
def sqlmodel_init(*, self: "SQLModel", data: Dict[str, Any]) -> None:
572+
def sqlmodel_init(*, self: "SQLModel", data: dict[str, Any]) -> None:
577573
values, fields_set, validation_error = validate_model(self.__class__, data)
578574
# Only raise errors if not a SQLModel model
579575
if (

0 commit comments

Comments
 (0)