Skip to content

Commit ce4ec99

Browse files
authored
Make Summary.summary_notifications a tuple (#1185)
Make `Summary.summary_notifications` a `tuple` instead of a `list` and type it with `Sequence` to signify that it should be treated as immutable.
1 parent 34d1789 commit ce4ec99

File tree

3 files changed

+24
-19
lines changed

3 files changed

+24
-19
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ See also https://github.com/neo4j/neo4j-python-driver/wiki for a full changelog.
9595
- Calling `driver.close()` again is now a no-op.
9696
- No longer implicitly closing drivers and sessions in `__del__()` (finalizer/destructor).
9797
Make sure to call `.close()` on them explicitly or use them in a `with` statement.
98+
- Make `Summary.summary_notifications` a `tuple` instead of a `list` and type it with `Sequence` to signify that it
99+
should be treated as immutable.
98100

99101

100102
## Version 5.28

src/neo4j/_work/summary.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131

3232

3333
if t.TYPE_CHECKING:
34+
from collections.abc import Sequence
35+
3436
import typing_extensions as te
3537

3638
from .._addressing import Address
@@ -93,7 +95,7 @@ class ResultSummary:
9395
_notifications_set: bool = False
9496

9597
# cache for property `summary_notifications`
96-
_summary_notifications: list[SummaryNotification]
98+
_summary_notifications: tuple[SummaryNotification, ...]
9799

98100
# cache for property `summary_notifications`
99101
_gql_status_objects: tuple[GqlStatusObject, ...]
@@ -202,9 +204,8 @@ def _set_notifications(self) -> None:
202204

203205
self.notifications = None
204206

205-
# TODO: 6.0 - return a tuple for immutability (annotate with Sequence)
206207
@property
207-
def summary_notifications(self) -> list[SummaryNotification]:
208+
def summary_notifications(self) -> Sequence[SummaryNotification]:
208209
"""
209210
The same as ``notifications`` but in a parsed, structured form.
210211
@@ -220,11 +221,11 @@ def summary_notifications(self) -> list[SummaryNotification]:
220221

221222
raw_notifications = self.notifications
222223
if not isinstance(raw_notifications, list):
223-
self._summary_notifications = []
224+
self._summary_notifications = ()
224225
return self._summary_notifications
225-
self._summary_notifications = [
226+
self._summary_notifications = tuple(
226227
SummaryNotification._from_metadata(n) for n in raw_notifications
227-
]
228+
)
228229
return self._summary_notifications
229230

230231
@property

tests/unit/common/work/test_summary.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222

2323
if t.TYPE_CHECKING:
24+
from collections.abc import Sequence
25+
2426
import typing_extensions as te
2527

2628
_T = t.TypeVar("_T")
@@ -759,11 +761,11 @@ def test_summary_summary_notifications(
759761
kwargs["metadata"]["notifications"] = summary_in
760762

761763
summary = ResultSummary(*args, **kwargs)
762-
summary_out: list[SummaryNotification] = summary.summary_notifications
764+
summary_out: Sequence[SummaryNotification] = summary.summary_notifications
763765

764-
assert isinstance(summary_out, list)
766+
assert isinstance(summary_out, tuple)
765767
if summary_in is None:
766-
assert summary_out == []
768+
assert summary_out == ()
767769
return
768770

769771
assert summary_in is not None
@@ -1469,12 +1471,12 @@ def test_no_notification_from_status(raw_status, summary_args_kwargs) -> None:
14691471

14701472
summary = ResultSummary(*args, **kwargs)
14711473
notifications: list[dict] | None = summary.notifications
1472-
summary_notifications: list[SummaryNotification] = (
1474+
summary_notifications: Sequence[SummaryNotification] = (
14731475
summary.summary_notifications
14741476
)
14751477

14761478
assert notifications is None
1477-
assert summary_notifications == []
1479+
assert summary_notifications == ()
14781480

14791481

14801482
@pytest.mark.parametrize(
@@ -1745,7 +1747,7 @@ def test_no_notification_from_wrong_type_status(
17451747
summary_notifications = summary.summary_notifications
17461748

17471749
assert notifications is None
1748-
assert summary_notifications == []
1750+
assert summary_notifications == ()
17491751

17501752

17511753
def _get_from_dict(
@@ -1939,7 +1941,7 @@ def test_no_notification_from_status_without_neo4j_code(
19391941
summary_notifications = summary.summary_notifications
19401942

19411943
assert notifications is None
1942-
assert summary_notifications == []
1944+
assert summary_notifications == ()
19431945

19441946

19451947
@pytest.mark.parametrize(
@@ -1977,9 +1979,9 @@ def test_notification_from_incomplete_status(
19771979

19781980
assert notifications == [raw_notification]
19791981

1980-
assert summary_notifications == [
1981-
SummaryNotification._from_metadata(raw_notification)
1982-
]
1982+
assert summary_notifications == (
1983+
SummaryNotification._from_metadata(raw_notification),
1984+
)
19831985

19841986

19851987
@pytest.mark.parametrize(
@@ -2027,9 +2029,9 @@ def test_notification_from_unexpected_status(
20272029

20282030
assert notifications == [raw_notification]
20292031

2030-
assert summary_notifications == [
2031-
SummaryNotification._from_metadata(raw_notification)
2032-
]
2032+
assert summary_notifications == (
2033+
SummaryNotification._from_metadata(raw_notification),
2034+
)
20332035

20342036

20352037
def _test_status():

0 commit comments

Comments
 (0)