|
1 |
| -from typing import Any |
| 1 | +from typing import cast, Any, Awaitable |
2 | 2 |
|
3 | 3 | from pytest import mark
|
4 | 4 |
|
5 | 5 | from graphql.execution import execute, execute_sync, ExecutionResult
|
6 | 6 | from graphql.language import parse
|
| 7 | +from graphql.pyutils import is_awaitable |
7 | 8 | from graphql.utilities import build_schema
|
8 | 9 |
|
9 | 10 |
|
@@ -45,6 +46,24 @@ def list_field():
|
45 | 46 | None,
|
46 | 47 | )
|
47 | 48 |
|
| 49 | + def accepts_a_custom_iterable_as_a_list_value(): |
| 50 | + class ListField: |
| 51 | + def __iter__(self): |
| 52 | + self.last = "hello" |
| 53 | + return self |
| 54 | + |
| 55 | + def __next__(self): |
| 56 | + last = self.last |
| 57 | + if last == "stop": |
| 58 | + raise StopIteration |
| 59 | + self.last = "world" if last == "hello" else "stop" |
| 60 | + return last |
| 61 | + |
| 62 | + assert _complete(ListField()) == ( |
| 63 | + {"listField": ["hello", "world"]}, |
| 64 | + None, |
| 65 | + ) |
| 66 | + |
48 | 67 | def accepts_function_arguments_as_a_list_value():
|
49 | 68 | def get_args(*args):
|
50 | 69 | return args # actually just a tuple, nothing special in Python
|
@@ -195,3 +214,46 @@ async def results_in_errors():
|
195 | 214 | None,
|
196 | 215 | errors,
|
197 | 216 | )
|
| 217 | + |
| 218 | + |
| 219 | +def describe_experimental_execute_accepts_async_iterables_as_list_value(): |
| 220 | + async def _complete(list_field): |
| 221 | + result = execute( |
| 222 | + build_schema("type Query { listField: [String] }"), |
| 223 | + parse("{ listField }"), |
| 224 | + Data(list_field), |
| 225 | + ) |
| 226 | + assert is_awaitable(result) |
| 227 | + result = cast(Awaitable, result) |
| 228 | + return await result |
| 229 | + |
| 230 | + @mark.asyncio |
| 231 | + async def accepts_an_async_generator_as_a_list_value(): |
| 232 | + async def list_field(): |
| 233 | + yield "one" |
| 234 | + yield 2 |
| 235 | + yield True |
| 236 | + |
| 237 | + assert await _complete(list_field()) == ( |
| 238 | + {"listField": ["one", "2", "true"]}, |
| 239 | + None, |
| 240 | + ) |
| 241 | + |
| 242 | + @mark.asyncio |
| 243 | + async def accepts_a_custom_async_iterable_as_a_list_value(): |
| 244 | + class ListField: |
| 245 | + def __aiter__(self): |
| 246 | + self.last = "hello" |
| 247 | + return self |
| 248 | + |
| 249 | + async def __anext__(self): |
| 250 | + last = self.last |
| 251 | + if last == "stop": |
| 252 | + raise StopAsyncIteration |
| 253 | + self.last = "world" if last == "hello" else "stop" |
| 254 | + return last |
| 255 | + |
| 256 | + assert await _complete(ListField()) == ( |
| 257 | + {"listField": ["hello", "world"]}, |
| 258 | + None, |
| 259 | + ) |
0 commit comments