Skip to content

Commit 72fd85d

Browse files
jacalataclaude
andcommitted
fix: use return instead of raise StopIteration in QuerySet.__iter__
Per PEP 479, StopIteration raised inside a generator is converted to RuntimeError. QuerySet.__iter__ is a generator and was raising StopIteration to handle 400006 (invalid page number) errors, causing RuntimeError for callers iterating endpoints that don't support pagination past the last page. Fixes #1786 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 5d9a3c5 commit 72fd85d

2 files changed

Lines changed: 28 additions & 2 deletions

File tree

tableauserverclient/server/query.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,9 @@ def __iter__(self: Self) -> Iterator[T]:
8484
if e.code == "400006":
8585
# If the endpoint does not support pagination, it will end
8686
# up overrunning the total number of pages. Catch the
87-
# error and break out of the loop.
88-
raise StopIteration
87+
# error and return to cleanly end the generator.
88+
# (raise StopIteration would cause RuntimeError per PEP 479)
89+
return
8990
if len(self._result_cache) == 0:
9091
return
9192
yield from self._result_cache

test/test_pager.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,28 @@ def test_queryset_no_matches(server: TSC.Server) -> None:
136136
all_groups = server.groups.all()
137137
groups = list(all_groups)
138138
assert len(groups) == 0
139+
140+
141+
def test_queryset_400006_returns_cleanly(server: TSC.Server) -> None:
142+
"""Regression test for PEP 479: 400006 on page 2 must not raise RuntimeError."""
143+
page1_xml = b"""<?xml version='1.0' encoding='UTF-8'?>
144+
<tsResponse xmlns='http://tableau.com/api'>
145+
<pagination pageNumber='1' pageSize='1' totalAvailable='2'/>
146+
<projects><project id='abc' name='Test' contentPermissions='ManagedByOwner'/></projects>
147+
</tsResponse>"""
148+
error_xml = b"""<?xml version='1.0' encoding='UTF-8'?>
149+
<tsResponse xmlns='http://tableau.com/api'>
150+
<error code='400006'><summary>Bad Request</summary><detail>Invalid page number</detail></error>
151+
</tsResponse>"""
152+
153+
with requests_mock.mock() as m:
154+
m.get(
155+
requests_mock.ANY,
156+
[
157+
{"content": page1_xml, "status_code": 200},
158+
{"content": error_xml, "status_code": 400},
159+
],
160+
)
161+
# Before the fix this raised RuntimeError: generator raised StopIteration
162+
results = list(server.projects.all())
163+
assert len(results) == 1

0 commit comments

Comments
 (0)