Skip to content

Commit fe2f942

Browse files
authored
Fix Pydantic deprecation warnings (#764)
1 parent 74f0c89 commit fe2f942

File tree

5 files changed

+28
-18
lines changed

5 files changed

+28
-18
lines changed

jbi/models.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,14 @@
1111
from typing import DefaultDict, Literal, Mapping, Optional
1212
from urllib.parse import ParseResult, urlparse
1313

14-
from pydantic import BaseModel, ConfigDict, Extra, Field, RootModel, field_validator
14+
from pydantic import (
15+
BaseModel,
16+
ConfigDict,
17+
Field,
18+
RootModel,
19+
TypeAdapter,
20+
field_validator,
21+
)
1522
from typing_extensions import TypedDict
1623

1724
from jbi import Operation, steps
@@ -295,6 +302,9 @@ class BugzillaComment(BaseModel):
295302
creator: str
296303

297304

305+
BugzillaComments = TypeAdapter(list[BugzillaComment])
306+
307+
298308
class BugzillaApiResponse(BaseModel):
299309
"""Bugzilla Response Object"""
300310

@@ -335,7 +345,7 @@ class Context(BaseModel):
335345

336346
def update(self, **kwargs):
337347
"""Return a copy with updated fields."""
338-
return self.copy(update=kwargs)
348+
return self.model_copy(update=kwargs, deep=True)
339349

340350

341351
class JiraContext(Context):
@@ -349,7 +359,7 @@ class JiraContext(Context):
349359
BugId = TypedDict("BugId", {"id": Optional[int]})
350360

351361

352-
class RunnerContext(Context, extra=Extra.forbid):
362+
class RunnerContext(Context, extra="forbid"):
353363
"""Logging context from runner"""
354364

355365
rid: str
@@ -359,7 +369,7 @@ class RunnerContext(Context, extra=Extra.forbid):
359369
bug: BugId | BugzillaBug
360370

361371

362-
class ActionContext(Context, extra=Extra.forbid):
372+
class ActionContext(Context, extra="forbid"):
363373
"""Logging context from actions"""
364374

365375
action: Action

jbi/services/bugzilla.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from functools import lru_cache
77

88
import requests
9-
from pydantic import parse_obj_as
109
from statsd.defaults.env import statsd
1110

1211
from jbi import Operation, environment
@@ -15,6 +14,7 @@
1514
BugzillaApiResponse,
1615
BugzillaBug,
1716
BugzillaComment,
17+
BugzillaComments,
1818
BugzillaWebhooksResponse,
1919
)
2020

@@ -73,7 +73,7 @@ def get_bug(self, bugid) -> BugzillaBug:
7373
# https://bugzilla.readthedocs.io/en/latest/api/core/v1/bug.html#rest-single-bug
7474
url = f"{self.base_url}/rest/bug/{bugid}"
7575
bug_info = self._call("GET", url)
76-
parsed = BugzillaApiResponse.parse_obj(bug_info)
76+
parsed = BugzillaApiResponse.model_validate(bug_info)
7777
if not parsed.bugs:
7878
raise BugzillaClientError(
7979
f"Unexpected response content from 'GET {url}' (no 'bugs' field)"
@@ -85,7 +85,7 @@ def get_bug(self, bugid) -> BugzillaBug:
8585
matching_comments = [c for c in comment_list if c.id == bug.comment.id]
8686
# If no matching entry is found, set `bug.comment` to `None`.
8787
found = matching_comments[0] if matching_comments else None
88-
bug = bug.copy(update={"comment": found})
88+
bug = bug.model_copy(update={"comment": found}, deep=True)
8989
return bug
9090

9191
@instrumented_method
@@ -99,15 +99,15 @@ def get_comments(self, bugid) -> list[BugzillaComment]:
9999
raise BugzillaClientError(
100100
f"Unexpected response content from 'GET {url}' (no 'bugs' field)"
101101
)
102-
return parse_obj_as(list[BugzillaComment], comments)
102+
return BugzillaComments.validate_python(comments)
103103

104104
@instrumented_method
105105
def update_bug(self, bugid, **fields) -> BugzillaBug:
106106
"""Update the specified fields of the specified bug."""
107107
# https://bugzilla.readthedocs.io/en/latest/api/core/v1/bug.html#rest-update-bug
108108
url = f"{self.base_url}/rest/bug/{bugid}"
109109
updated_info = self._call("PUT", url, json=fields)
110-
parsed = BugzillaApiResponse.parse_obj(updated_info)
110+
parsed = BugzillaApiResponse.model_validate(updated_info)
111111
if not parsed.bugs:
112112
raise BugzillaClientError(
113113
f"Unexpected response content from 'PUT {url}' (no 'bugs' field)"
@@ -119,7 +119,7 @@ def list_webhooks(self):
119119
"""List the currently configured webhooks, including their status."""
120120
url = f"{self.base_url}/rest/webhooks/list"
121121
webhooks_info = self._call("GET", url)
122-
parsed = BugzillaWebhooksResponse.parse_obj(webhooks_info)
122+
parsed = BugzillaWebhooksResponse.model_validate(webhooks_info)
123123
if parsed.webhooks is None:
124124
raise BugzillaClientError(
125125
f"Unexpected response content from 'GET {url}' (no 'webhooks' field)"

tests/unit/test_app.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ def test_errors_are_reported_to_sentry(
7272
with patch("jbi.router.execute_action", side_effect=ValueError):
7373
with pytest.raises(ValueError):
7474
anon_client.post(
75-
"/bugzilla_webhook", data=webhook_create_example.json()
75+
"/bugzilla_webhook", data=webhook_create_example.model_dump_json()
7676
)
7777

7878
assert mocked.called, "Sentry captured the exception"
@@ -92,7 +92,7 @@ def test_request_id_is_passed_down_to_logger_contexts(
9292
with TestClient(app) as anon_client:
9393
anon_client.post(
9494
"/bugzilla_webhook",
95-
data=webhook_create_example.json(),
95+
data=webhook_create_example.model_dump_json(),
9696
headers={
9797
"X-Request-Id": "foo-bar",
9898
},

tests/unit/test_models.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ def test_default_invalid_step():
3737

3838
def test_duplicated_whiteboard_tag_fails(action_factory):
3939
with pytest.raises(ValueError) as exc_info:
40-
Actions.parse_obj(
41-
[
40+
Actions(
41+
root=[
4242
action_factory(whiteboard_tag="x"),
4343
action_factory(whiteboard_tag="y"),
4444
action_factory(whiteboard_tag="x"),
@@ -49,8 +49,8 @@ def test_duplicated_whiteboard_tag_fails(action_factory):
4949

5050
def test_override_step_configuration_for_single_action_type():
5151
default_steps = ActionSteps()
52-
params = ActionParams.parse_obj(
53-
{"jira_project_key": "JBI", "steps": {"new": ["create_issue"]}}
52+
params = ActionParams(
53+
jira_project_key="JBI", steps=ActionSteps(new=["create_issue"])
5454
)
5555
assert params.steps.new == ["create_issue"]
5656
assert params.steps.new != default_steps.new

tests/unit/test_router.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def test_webhook_is_200_if_action_succeeds(
108108

109109
with TestClient(app) as anon_client:
110110
response = anon_client.post(
111-
"/bugzilla_webhook", data=webhook_create_example.json()
111+
"/bugzilla_webhook", data=webhook_create_example.model_dump_json()
112112
)
113113
assert response
114114
assert response.status_code == 200
@@ -124,7 +124,7 @@ def test_webhook_is_200_if_action_raises_IgnoreInvalidRequestError(
124124

125125
with TestClient(app) as anon_client:
126126
response = anon_client.post(
127-
"/bugzilla_webhook", data=webhook_create_example.json()
127+
"/bugzilla_webhook", data=webhook_create_example.model_dump_json()
128128
)
129129
assert response
130130
assert response.status_code == 200

0 commit comments

Comments
 (0)