Skip to content
This repository was archived by the owner on Mar 6, 2026. It is now read-only.

Commit 0561a34

Browse files
author
Chris Rossi
authored
fix: query.map() and query.map_async() hanging with empty result set. (#230)
Fixes #227.
1 parent bd219fb commit 0561a34

3 files changed

Lines changed: 36 additions & 1 deletion

File tree

google/cloud/ndb/query.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2031,7 +2031,11 @@ def map_async(self, callback, **kwargs):
20312031
mapped = future
20322032
futures.append(mapped)
20332033

2034-
mapped_results = yield futures
2034+
if futures:
2035+
mapped_results = yield futures
2036+
else:
2037+
mapped_results = []
2038+
20352039
raise tasklets.Return(mapped_results)
20362040

20372041
@_query_options

tests/system/test_query.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,6 +1323,18 @@ def get_other_foo(thing):
13231323
assert query.map(get_other_foo) == foos
13241324

13251325

1326+
@pytest.mark.usefixtures("client_context")
1327+
def test_map_empty_result_set(dispose_of):
1328+
class SomeKind(ndb.Model):
1329+
foo = ndb.StringProperty()
1330+
1331+
def somefunc(x):
1332+
raise Exception("Shouldn't be called.")
1333+
1334+
query = SomeKind.query()
1335+
assert query.map(somefunc) == []
1336+
1337+
13261338
@pytest.mark.usefixtures("client_context")
13271339
def test_gql(ds_entity):
13281340
for i in range(5):

tests/unit/test_query.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1877,6 +1877,25 @@ def callback(result):
18771877
query = query_module.Query()
18781878
assert query.map(callback) == (1, 2, 3, 4, 5)
18791879

1880+
@staticmethod
1881+
@pytest.mark.usefixtures("in_context")
1882+
@mock.patch("google.cloud.ndb._datastore_query")
1883+
def test_map_empty_result_set(_datastore_query):
1884+
class DummyQueryIterator:
1885+
def __init__(self, items):
1886+
self.items = list(items)
1887+
1888+
def has_next_async(self):
1889+
return utils.future_result(bool(self.items))
1890+
1891+
_datastore_query.iterate.return_value = DummyQueryIterator(())
1892+
1893+
def callback(result): # pragma: NO COVER
1894+
raise Exception("Shouldn't get called.")
1895+
1896+
query = query_module.Query()
1897+
assert query.map(callback) == []
1898+
18801899
@staticmethod
18811900
@pytest.mark.usefixtures("in_context")
18821901
@mock.patch("google.cloud.ndb._datastore_query")

0 commit comments

Comments
 (0)