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.
- {bugdantic-0.5.1 → bugdantic-0.5.2}/PKG-INFO +4 -4
- {bugdantic-0.5.1 → bugdantic-0.5.2}/bugdantic/bugzilla.py +74 -0
- {bugdantic-0.5.1 → bugdantic-0.5.2}/bugdantic.egg-info/PKG-INFO +4 -4
- {bugdantic-0.5.1 → bugdantic-0.5.2}/bugdantic.egg-info/requires.txt +3 -3
- {bugdantic-0.5.1 → bugdantic-0.5.2}/pyproject.toml +4 -4
- {bugdantic-0.5.1 → bugdantic-0.5.2}/test/test_bugzilla.py +18 -0
- {bugdantic-0.5.1 → bugdantic-0.5.2}/LICENSE +0 -0
- {bugdantic-0.5.1 → bugdantic-0.5.2}/README.md +0 -0
- {bugdantic-0.5.1 → bugdantic-0.5.2}/bugdantic/__init__.py +0 -0
- {bugdantic-0.5.1 → bugdantic-0.5.2}/bugdantic/py.typed +0 -0
- {bugdantic-0.5.1 → bugdantic-0.5.2}/bugdantic/userstory.py +0 -0
- {bugdantic-0.5.1 → bugdantic-0.5.2}/bugdantic.egg-info/SOURCES.txt +0 -0
- {bugdantic-0.5.1 → bugdantic-0.5.2}/bugdantic.egg-info/dependency_links.txt +0 -0
- {bugdantic-0.5.1 → bugdantic-0.5.2}/bugdantic.egg-info/top_level.txt +0 -0
- {bugdantic-0.5.1 → bugdantic-0.5.2}/setup.cfg +0 -0
- {bugdantic-0.5.1 → bugdantic-0.5.2}/test/test_userstory.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bugdantic
|
|
3
|
-
Version: 0.5.
|
|
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.
|
|
15
|
-
Requires-Dist: ruff==0.16.
|
|
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.
|
|
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.
|
|
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.
|
|
15
|
-
Requires-Dist: ruff==0.16.
|
|
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.
|
|
18
|
+
Requires-Dist: ty==0.0.78; extra == "test"
|
|
19
19
|
Dynamic: license-file
|
|
@@ -5,7 +5,7 @@ authors = [
|
|
|
5
5
|
{name = "James Graham", email = "james@hoppipolla.co.uk"}
|
|
6
6
|
]
|
|
7
7
|
|
|
8
|
-
version = "0.5.
|
|
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.
|
|
24
|
-
"ruff==0.16.
|
|
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.
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|