Skip to content

Commit d787c3f

Browse files
authored
Merge branch 'main' into dependabot/pip/mypy-1.18.1
2 parents f30beb2 + 2d3b25d commit d787c3f

File tree

10 files changed

+141
-29
lines changed

10 files changed

+141
-29
lines changed

.github/workflows/deploy-docs.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ jobs:
4444
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4545
COMMIT_SHA: ${{ github.event.workflow_run.head_sha }}
4646
RUN_ID: ${{ github.run_id }}
47-
47+
STATE: "pending"
4848
- name: Clean site
4949
run: |
5050
rm -rf ./site
@@ -68,11 +68,19 @@ jobs:
6868
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
6969
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
7070
command: pages deploy ./site --project-name=${{ env.PROJECT_NAME }} --branch=${{ env.BRANCH }}
71+
- name: Deploy Docs Status Error
72+
if: failure()
73+
run: python ./scripts/deploy_docs_status.py
74+
env:
75+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
76+
COMMIT_SHA: ${{ github.event.workflow_run.head_sha }}
77+
RUN_ID: ${{ github.run_id }}
78+
STATE: "error"
7179
- name: Comment Deploy
7280
run: python ./scripts/deploy_docs_status.py
7381
env:
7482
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
7583
DEPLOY_URL: ${{ steps.deploy.outputs.deployment-url }}
7684
COMMIT_SHA: ${{ github.event.workflow_run.head_sha }}
7785
RUN_ID: ${{ github.run_id }}
78-
IS_DONE: "true"
86+
STATE: "success"

.github/workflows/issue-manager.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
env:
2828
GITHUB_CONTEXT: ${{ toJson(github) }}
2929
run: echo "$GITHUB_CONTEXT"
30-
- uses: tiangolo/issue-manager@0.5.1
30+
- uses: tiangolo/issue-manager@0.6.0
3131
with:
3232
token: ${{ secrets.GITHUB_TOKEN }}
3333
config: >

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ repos:
1414
- id: end-of-file-fixer
1515
- id: trailing-whitespace
1616
- repo: https://github.com/astral-sh/ruff-pre-commit
17-
rev: v0.13.1
17+
rev: v0.13.3
1818
hooks:
1919
- id: ruff
2020
args:

docs/release-notes.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,22 @@
22

33
## Latest Changes
44

5+
### Fixes
6+
7+
* 🐛 Fix attribute handling in `model_dump` for compatibility with the latest Pydantic versions. PR [#1595](https://github.com/fastapi/sqlmodel/pull/1595) by [@spazm](https://github.com/spazm).
8+
9+
### Docs
10+
11+
* 📝 Fix typo in `docs/tutorial/fastapi/simple-hero-api.md`. PR [#1583](https://github.com/fastapi/sqlmodel/pull/1583) by [@kofi-kusi](https://github.com/kofi-kusi).
12+
513
### Internal
614

15+
* ✅ Add test that runs select with 3 or 4 arguments. PR [#1590](https://github.com/fastapi/sqlmodel/pull/1590) by [@svlandeg](https://github.com/svlandeg).
16+
* ⬆ Bump mkdocs-macros-plugin from 1.3.9 to 1.4.0. PR [#1581](https://github.com/fastapi/sqlmodel/pull/1581) by [@dependabot[bot]](https://github.com/apps/dependabot).
17+
* ⬆ Bump mkdocs-material from 9.6.20 to 9.6.21. PR [#1588](https://github.com/fastapi/sqlmodel/pull/1588) by [@dependabot[bot]](https://github.com/apps/dependabot).
18+
*[pre-commit.ci] pre-commit autoupdate. PR [#1584](https://github.com/fastapi/sqlmodel/pull/1584) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
19+
* ⬆ Bump tiangolo/issue-manager from 0.5.1 to 0.6.0. PR [#1589](https://github.com/fastapi/sqlmodel/pull/1589) by [@dependabot[bot]](https://github.com/apps/dependabot).
20+
* 👷 Update docs previews comment, single comment, add failure status. PR [#1586](https://github.com/fastapi/sqlmodel/pull/1586) by [@tiangolo](https://github.com/tiangolo).
721
* ⬆ Bump markdown-include-variants from 0.0.4 to 0.0.5. PR [#1582](https://github.com/fastapi/sqlmodel/pull/1582) by [@dependabot[bot]](https://github.com/apps/dependabot).
822
* ⬆ Bump typing-extensions from 4.13.2 to 4.15.0 for Python 3.9+. PR [#1580](https://github.com/fastapi/sqlmodel/pull/1580) by [@svlandeg](https://github.com/svlandeg).
923
*[pre-commit.ci] pre-commit autoupdate. PR [#1571](https://github.com/fastapi/sqlmodel/pull/1571) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).

docs/tutorial/fastapi/simple-hero-api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ And then create an `app` object that is an instance of that `FastAPI` class:
6060

6161
## Create Database and Tables on `startup`
6262

63-
We want to make sure that once the app starts running, the function `create_tables` is called. To create the database and tables.
63+
We want to make sure that once the app starts running, the function `create_db_and_tables` is called. To create the database and tables.
6464

6565
This should be called only once at startup, not before every request, so we put it in the function to handle the `"startup"` event:
6666

requirements-docs.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
-e .
22
-r requirements-docs-tests.txt
3-
mkdocs-material==9.6.20
3+
mkdocs-material==9.6.21
44
mdx-include >=1.4.1,<2.0.0
55
mkdocs-redirects>=1.2.1,<1.3.0
66
pyyaml >=5.3.1,<7.0.0
@@ -14,5 +14,5 @@ cairosvg==2.8.2
1414
griffe-typingdoc==0.2.9
1515
# For griffe, it formats with black
1616
typer == 0.19.2
17-
mkdocs-macros-plugin==1.3.9
17+
mkdocs-macros-plugin==1.4.0
1818
markdown-include-variants==0.0.5

scripts/deploy_docs_status.py

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import logging
22
import re
3+
from typing import Literal
34

4-
from github import Github
5+
from github import Auth, Github
56
from pydantic import BaseModel, SecretStr
67
from pydantic_settings import BaseSettings
78

@@ -14,7 +15,7 @@ class Settings(BaseSettings):
1415
deploy_url: str | None = None
1516
commit_sha: str
1617
run_id: int
17-
is_done: bool = False
18+
state: Literal["pending", "success", "error"] = "pending"
1819

1920

2021
class LinkData(BaseModel):
@@ -27,7 +28,7 @@ def main() -> None:
2728
settings = Settings()
2829

2930
logging.info(f"Using config: {settings.model_dump_json()}")
30-
g = Github(settings.github_token.get_secret_value())
31+
g = Github(auth=Auth.Token(settings.github_token.get_secret_value()))
3132
repo = g.get_repo(settings.github_repository)
3233
use_pr = next(
3334
(pr for pr in repo.get_pulls() if pr.head.sha == settings.commit_sha), None
@@ -38,24 +39,35 @@ def main() -> None:
3839
commits = list(use_pr.get_commits())
3940
current_commit = [c for c in commits if c.sha == settings.commit_sha][0]
4041
run_url = f"https://github.com/{settings.github_repository}/actions/runs/{settings.run_id}"
41-
if settings.is_done and not settings.deploy_url:
42+
if settings.state == "pending":
4243
current_commit.create_status(
43-
state="success",
44-
description="No Docs Changes",
44+
state="pending",
45+
description="Deploying Docs",
4546
context="deploy-docs",
4647
target_url=run_url,
4748
)
48-
logging.info("No docs changes found")
49+
logging.info("No deploy URL available yet")
4950
return
51+
if settings.state == "error":
52+
current_commit.create_status(
53+
state="error",
54+
description="Error Deploying Docs",
55+
context="deploy-docs",
56+
target_url=run_url,
57+
)
58+
logging.info("Error deploying docs")
59+
return
60+
assert settings.state == "success"
5061
if not settings.deploy_url:
5162
current_commit.create_status(
52-
state="pending",
53-
description="Deploying Docs",
63+
state="success",
64+
description="No Docs Changes",
5465
context="deploy-docs",
5566
target_url=run_url,
5667
)
57-
logging.info("No deploy URL available yet")
68+
logging.info("No docs changes found")
5869
return
70+
assert settings.deploy_url
5971
current_commit.create_status(
6072
state="success",
6173
description="Docs Deployed",
@@ -84,7 +96,9 @@ def main() -> None:
8496
links.append(link)
8597
links.sort(key=lambda x: x.preview_link)
8698

87-
message = f"📝 Docs preview for commit {settings.commit_sha} at: {deploy_url}"
99+
header = "## 📝 Docs preview"
100+
message = header
101+
message += f"\n\nLast commit {settings.commit_sha} at: {deploy_url}"
88102

89103
if links:
90104
message += "\n\n### Modified Pages\n\n"
@@ -94,7 +108,17 @@ def main() -> None:
94108
message += "\n"
95109

96110
print(message)
97-
use_pr.as_issue().create_comment(message)
111+
issue = use_pr.as_issue()
112+
comments = list(issue.get_comments())
113+
for comment in comments:
114+
if (
115+
comment.body.startswith(header)
116+
and comment.user.login == "github-actions[bot]"
117+
):
118+
comment.edit(message)
119+
break
120+
else:
121+
issue.create_comment(message)
98122

99123
logging.info("Finished")
100124

scripts/lint.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ set -e
44
set -x
55

66
mypy sqlmodel
7+
mypy tests/test_select_typing.py
78
ruff check sqlmodel tests docs_src scripts
89
ruff format sqlmodel tests docs_src scripts --check

sqlmodel/main.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ def __dataclass_transform__(
111111
return lambda a: a
112112

113113

114-
class FieldInfo(PydanticFieldInfo):
114+
class FieldInfo(PydanticFieldInfo): # type: ignore[misc]
115+
# mypy - ignore that PydanticFieldInfo is @final
115116
def __init__(self, default: Any = Undefined, **kwargs: Any) -> None:
116117
primary_key = kwargs.pop("primary_key", False)
117118
nullable = kwargs.pop("nullable", Undefined)
@@ -865,27 +866,27 @@ def model_dump(
865866
mode: Union[Literal["json", "python"], str] = "python",
866867
include: Union[IncEx, None] = None,
867868
exclude: Union[IncEx, None] = None,
868-
context: Union[Any, None] = None,
869+
context: Union[Any, None] = None, # v2.7
869870
by_alias: Union[bool, None] = None,
870871
exclude_unset: bool = False,
871872
exclude_defaults: bool = False,
872873
exclude_none: bool = False,
874+
exclude_computed_fields: bool = False, # v2.12
873875
round_trip: bool = False,
874876
warnings: Union[bool, Literal["none", "warn", "error"]] = True,
875-
fallback: Union[Callable[[Any], Any], None] = None,
876-
serialize_as_any: bool = False,
877+
fallback: Union[Callable[[Any], Any], None] = None, # v2.11
878+
serialize_as_any: bool = False, # v2.7
877879
) -> Dict[str, Any]:
878880
if PYDANTIC_MINOR_VERSION < (2, 11):
879881
by_alias = by_alias or False
882+
extra_kwargs: Dict[str, Any] = {}
880883
if PYDANTIC_MINOR_VERSION >= (2, 7):
881-
extra_kwargs: Dict[str, Any] = {
882-
"context": context,
883-
"serialize_as_any": serialize_as_any,
884-
}
884+
extra_kwargs["context"] = context
885+
extra_kwargs["serialize_as_any"] = serialize_as_any
885886
if PYDANTIC_MINOR_VERSION >= (2, 11):
886887
extra_kwargs["fallback"] = fallback
887-
else:
888-
extra_kwargs = {}
888+
if PYDANTIC_MINOR_VERSION >= (2, 12):
889+
extra_kwargs["exclude_computed_fields"] = exclude_computed_fields
889890
if IS_PYDANTIC_V2:
890891
return super().model_dump(
891892
mode=mode,

tests/test_select_typing.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from typing import Optional
2+
3+
from sqlmodel import Field, Session, SQLModel, create_engine, select
4+
from sqlmodel.pool import StaticPool
5+
6+
7+
def test_fields() -> None:
8+
class Hero(SQLModel, table=True):
9+
id: Optional[int] = Field(default=None, primary_key=True)
10+
name: str
11+
secret_name: str
12+
age: Optional[int] = None
13+
food: Optional[str] = None
14+
15+
engine = create_engine(
16+
"sqlite://", connect_args={"check_same_thread": False}, poolclass=StaticPool
17+
)
18+
19+
SQLModel.metadata.create_all(engine)
20+
21+
with Session(engine) as session:
22+
session.add(Hero(name="Deadpond", secret_name="Dive Wilson"))
23+
session.add(
24+
Hero(name="Spider-Boy", secret_name="Pedro Parqueador", food="pizza")
25+
)
26+
session.add(Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48))
27+
28+
session.commit()
29+
30+
# check typing of select with 3 fields
31+
with Session(engine) as session:
32+
statement_3 = select(Hero.id, Hero.name, Hero.secret_name)
33+
results_3 = session.exec(statement_3)
34+
for hero_3 in results_3:
35+
assert len(hero_3) == 3
36+
name_3: str = hero_3[1]
37+
assert type(name_3) is str
38+
assert type(hero_3[0]) is int
39+
assert type(hero_3[2]) is str
40+
41+
# check typing of select with 4 fields
42+
with Session(engine) as session:
43+
statement_4 = select(Hero.id, Hero.name, Hero.secret_name, Hero.age)
44+
results_4 = session.exec(statement_4)
45+
for hero_4 in results_4:
46+
assert len(hero_4) == 4
47+
name_4: str = hero_4[1]
48+
assert type(name_4) is str
49+
assert type(hero_4[0]) is int
50+
assert type(hero_4[2]) is str
51+
assert type(hero_4[3]) in [int, type(None)]
52+
53+
# check typing of select with 5 fields: currently runs but doesn't pass mypy
54+
# with Session(engine) as session:
55+
# statement_5 = select(Hero.id, Hero.name, Hero.secret_name, Hero.age, Hero.food)
56+
# results_5 = session.exec(statement_5)
57+
# for hero_5 in results_5:
58+
# assert len(hero_5) == 5
59+
# name_5: str = hero_5[1]
60+
# assert type(name_5) is str
61+
# assert type(hero_5[0]) is int
62+
# assert type(hero_5[2]) is str
63+
# assert type(hero_5[3]) in [int, type(None)]
64+
# assert type(hero_5[4]) in [str, type(None)]

0 commit comments

Comments
 (0)