bugdantic 0.5.1__tar.gz → 0.5.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bugdantic
3
- Version: 0.5.1
3
+ Version: 0.5.2
4
4
  Summary: Bugzilla client based on pydantic
5
5
  Author-email: James Graham <james@hoppipolla.co.uk>
6
6
  License-Expression: MPL-2.0
@@ -11,9 +11,9 @@ License-File: LICENSE
11
11
  Requires-Dist: httpx[http2]>=0.28.1
12
12
  Requires-Dist: pydantic>=2.11.3
13
13
  Provides-Extra: test
14
- Requires-Dist: mypy==2.3.0; extra == "test"
15
- Requires-Dist: ruff==0.16.2; extra == "test"
14
+ Requires-Dist: mypy==2.3.1; extra == "test"
15
+ Requires-Dist: ruff==0.16.6; extra == "test"
16
16
  Requires-Dist: pytest==9.1.1; extra == "test"
17
17
  Requires-Dist: pytest-ruff==0.5; extra == "test"
18
- Requires-Dist: ty==0.0.71; extra == "test"
18
+ Requires-Dist: ty==0.0.78; extra == "test"
19
19
  Dynamic: license-file
@@ -97,6 +97,7 @@ class BugComment(BaseModel):
97
97
  is_private: Optional[bool] = None
98
98
  is_markdown: Optional[bool] = None
99
99
  tags: Optional[list[str]] = None
100
+ reactions: Optional[dict[str, int]] = None
100
101
 
101
102
  model_config = ConfigDict(extra="allow")
102
103
 
@@ -433,6 +434,22 @@ class CommentCreateResponse(BaseModel):
433
434
  id: int
434
435
 
435
436
 
437
+ CommentType = TypeVar("CommentType", bound=BaseModel)
438
+
439
+
440
+ class CommentsResponseGeneric(BaseModel, Generic[CommentType]):
441
+ comments: Mapping[str, CommentType]
442
+
443
+
444
+ def comments_response_model(
445
+ comment_type: type[CommentType],
446
+ ) -> type[CommentsResponseGeneric[CommentType]]:
447
+ return cast(
448
+ type[CommentsResponseGeneric[CommentType]],
449
+ CommentsResponseGeneric.__class_getitem__(comment_type),
450
+ )
451
+
452
+
436
453
  class ErrorResponse(BaseModel):
437
454
  code: int
438
455
  message: str
@@ -655,6 +672,63 @@ class Bugzilla:
655
672
  )
656
673
  return results
657
674
 
675
+ def _comments(
676
+ self,
677
+ comment_ids: Sequence[int],
678
+ comment_type: type[CommentType],
679
+ include_fields: Optional[list[str]] = None,
680
+ exclude_fields: Optional[list[str]] = None,
681
+ page_size: int = 100,
682
+ ) -> list[CommentType]:
683
+ """Get comments specified by their ids.
684
+
685
+ The API accepts a list of comment ids with a single id in the path,
686
+ and the remainder are passed as repeated comment_ids parameters."""
687
+ results: list[CommentType] = []
688
+ for comment_ids_chunk in [
689
+ comment_ids[n : n + page_size]
690
+ for n in range(0, len(comment_ids), page_size)
691
+ ]:
692
+ response = self.check_error(
693
+ self.request(
694
+ "GET",
695
+ f"bug/comment/{comment_ids_chunk[0]}",
696
+ include_fields=include_fields,
697
+ exclude_fields=exclude_fields,
698
+ params={
699
+ "comment_ids": [str(item) for item in comment_ids_chunk[1:]]
700
+ },
701
+ )
702
+ )
703
+ result = comments_response_model(comment_type).model_validate(response)
704
+ results.extend(result.comments.values())
705
+ return results
706
+
707
+ def comments(
708
+ self,
709
+ comment_ids: Sequence[int],
710
+ include_fields: Optional[list[str]] = None,
711
+ exclude_fields: Optional[list[str]] = None,
712
+ page_size: int = 100,
713
+ ) -> list[BugComment]:
714
+ """Get comments specified by their ids"""
715
+ return self._comments(
716
+ comment_ids, BugComment, include_fields, exclude_fields, page_size
717
+ )
718
+
719
+ def comments_as(
720
+ self,
721
+ comment_ids: Sequence[int],
722
+ comment_type: type[CommentType],
723
+ exclude_fields: Optional[list[str]] = None,
724
+ page_size: int = 100,
725
+ ) -> list[CommentType]:
726
+ """Get comments specified by their ids"""
727
+ include_fields = model_field_names(comment_type)
728
+ return self._comments(
729
+ comment_ids, comment_type, include_fields, exclude_fields, page_size
730
+ )
731
+
658
732
  def bug_history(
659
733
  self, bug_id: int, new_since: Optional[datetime] = None
660
734
  ) -> BugHistory:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bugdantic
3
- Version: 0.5.1
3
+ Version: 0.5.2
4
4
  Summary: Bugzilla client based on pydantic
5
5
  Author-email: James Graham <james@hoppipolla.co.uk>
6
6
  License-Expression: MPL-2.0
@@ -11,9 +11,9 @@ License-File: LICENSE
11
11
  Requires-Dist: httpx[http2]>=0.28.1
12
12
  Requires-Dist: pydantic>=2.11.3
13
13
  Provides-Extra: test
14
- Requires-Dist: mypy==2.3.0; extra == "test"
15
- Requires-Dist: ruff==0.16.2; extra == "test"
14
+ Requires-Dist: mypy==2.3.1; extra == "test"
15
+ Requires-Dist: ruff==0.16.6; extra == "test"
16
16
  Requires-Dist: pytest==9.1.1; extra == "test"
17
17
  Requires-Dist: pytest-ruff==0.5; extra == "test"
18
- Requires-Dist: ty==0.0.71; extra == "test"
18
+ Requires-Dist: ty==0.0.78; extra == "test"
19
19
  Dynamic: license-file
@@ -2,8 +2,8 @@ httpx[http2]>=0.28.1
2
2
  pydantic>=2.11.3
3
3
 
4
4
  [test]
5
- mypy==2.3.0
6
- ruff==0.16.2
5
+ mypy==2.3.1
6
+ ruff==0.16.6
7
7
  pytest==9.1.1
8
8
  pytest-ruff==0.5
9
- ty==0.0.71
9
+ ty==0.0.78
@@ -5,7 +5,7 @@ authors = [
5
5
  {name = "James Graham", email = "james@hoppipolla.co.uk"}
6
6
  ]
7
7
 
8
- version = "0.5.1"
8
+ version = "0.5.2"
9
9
  requires-python = ">=3.11"
10
10
  license = "MPL-2.0"
11
11
  classifiers = [
@@ -20,11 +20,11 @@ dependencies = [
20
20
 
21
21
  [project.optional-dependencies]
22
22
  test = [
23
- "mypy==2.3.0",
24
- "ruff==0.16.2",
23
+ "mypy==2.3.1",
24
+ "ruff==0.16.6",
25
25
  "pytest==9.1.1",
26
26
  "pytest-ruff==0.5",
27
- "ty==0.0.71",
27
+ "ty==0.0.78",
28
28
  ]
29
29
 
30
30
  [tool.mypy]
@@ -124,3 +124,21 @@ def test_bug_as_exclude(bugzilla):
124
124
  assert result.id == 975444
125
125
  assert result.attachments
126
126
  assert all("data" not in item for item in result.attachments)
127
+
128
+
129
+ def test_comment(bugzilla):
130
+ result = bugzilla.comments([18109498, 18109500])
131
+ assert all(isinstance(item, BugComment) for item in result)
132
+ assert len(result) == 2
133
+ assert {item.id for item in result} == {18109498, 18109500}
134
+
135
+
136
+ def test_comment_as(bugzilla):
137
+ class CommentReactions(BaseModel):
138
+ id: int
139
+ reactions: dict[str, int]
140
+
141
+ result = bugzilla.comments_as([18109498, 18109500], CommentReactions)
142
+ assert all(isinstance(item, CommentReactions) for item in result)
143
+ assert {item.id for item in result} == {18109498, 18109500}
144
+ assert all(isinstance(item.reactions, dict) for item in result)
File without changes
File without changes
File without changes
File without changes