Skip to content

Commit 9445c0b

Browse files
committed
fix(types): path is required within incremental results
Replicates graphql/graphql-js@d1d66a3
1 parent d9c5e1d commit 9445c0b

File tree

3 files changed

+43
-41
lines changed

3 files changed

+43
-41
lines changed

src/graphql/execution/incremental_publisher.py

+32-30
Original file line numberDiff line numberDiff line change
@@ -364,51 +364,52 @@ class ExperimentalIncrementalExecutionResults(NamedTuple):
364364
class FormattedIncrementalDeferResult(TypedDict, total=False):
365365
"""Formatted incremental deferred execution result"""
366366

367-
data: dict[str, Any] | None
368-
errors: list[GraphQLFormattedError]
367+
data: dict[str, Any]
369368
path: list[str | int]
369+
errors: list[GraphQLFormattedError]
370370
extensions: dict[str, Any]
371371

372372

373373
class IncrementalDeferResult:
374374
"""Incremental deferred execution result"""
375375

376-
data: dict[str, Any] | None
376+
data: dict[str, Any]
377+
path: list[str | int]
377378
errors: list[GraphQLError] | None
378-
path: list[str | int] | None
379379
extensions: dict[str, Any] | None
380380

381381
__slots__ = "data", "errors", "extensions", "path"
382382

383383
def __init__(
384384
self,
385-
data: dict[str, Any] | None = None,
385+
data: dict[str, Any],
386+
path: list[str | int],
386387
errors: list[GraphQLError] | None = None,
387-
path: list[str | int] | None = None,
388388
extensions: dict[str, Any] | None = None,
389389
) -> None:
390390
self.data = data
391-
self.errors = errors
392391
self.path = path
392+
self.errors = errors
393393
self.extensions = extensions
394394

395395
def __repr__(self) -> str:
396396
name = self.__class__.__name__
397-
args: list[str] = [f"data={self.data!r}, errors={self.errors!r}"]
398-
if self.path:
399-
args.append(f"path={self.path!r}")
397+
args: list[str] = [f"data={self.data!r}, path={self.path!r}"]
398+
if self.errors:
399+
args.append(f"errors={self.errors!r}")
400400
if self.extensions:
401401
args.append(f"extensions={self.extensions}")
402402
return f"{name}({', '.join(args)})"
403403

404404
@property
405405
def formatted(self) -> FormattedIncrementalDeferResult:
406406
"""Get execution result formatted according to the specification."""
407-
formatted: FormattedIncrementalDeferResult = {"data": self.data}
407+
formatted: FormattedIncrementalDeferResult = {
408+
"data": self.data,
409+
"path": self.path,
410+
}
408411
if self.errors is not None:
409412
formatted["errors"] = [error.formatted for error in self.errors]
410-
if self.path is not None:
411-
formatted["path"] = self.path
412413
if self.extensions is not None:
413414
formatted["extensions"] = self.extensions
414415
return formatted
@@ -442,51 +443,52 @@ def __ne__(self, other: object) -> bool:
442443
class FormattedIncrementalStreamResult(TypedDict, total=False):
443444
"""Formatted incremental stream execution result"""
444445

445-
items: list[Any] | None
446-
errors: list[GraphQLFormattedError]
446+
items: list[Any]
447447
path: list[str | int]
448+
errors: list[GraphQLFormattedError]
448449
extensions: dict[str, Any]
449450

450451

451452
class IncrementalStreamResult:
452453
"""Incremental streamed execution result"""
453454

454-
items: list[Any] | None
455+
items: list[Any]
456+
path: list[str | int]
455457
errors: list[GraphQLError] | None
456-
path: list[str | int] | None
457458
extensions: dict[str, Any] | None
458459

459460
__slots__ = "errors", "extensions", "items", "label", "path"
460461

461462
def __init__(
462463
self,
463-
items: list[Any] | None = None,
464+
items: list[Any],
465+
path: list[str | int],
464466
errors: list[GraphQLError] | None = None,
465-
path: list[str | int] | None = None,
466467
extensions: dict[str, Any] | None = None,
467468
) -> None:
468469
self.items = items
469-
self.errors = errors
470470
self.path = path
471+
self.errors = errors
471472
self.extensions = extensions
472473

473474
def __repr__(self) -> str:
474475
name = self.__class__.__name__
475-
args: list[str] = [f"items={self.items!r}, errors={self.errors!r}"]
476-
if self.path:
477-
args.append(f"path={self.path!r}")
476+
args: list[str] = [f"items={self.items!r}, path={self.path!r}"]
477+
if self.errors:
478+
args.append(f"errors={self.errors!r}")
478479
if self.extensions:
479480
args.append(f"extensions={self.extensions}")
480481
return f"{name}({', '.join(args)})"
481482

482483
@property
483484
def formatted(self) -> FormattedIncrementalStreamResult:
484485
"""Get execution result formatted according to the specification."""
485-
formatted: FormattedIncrementalStreamResult = {"items": self.items}
486-
if self.errors is not None:
486+
formatted: FormattedIncrementalStreamResult = {
487+
"items": self.items,
488+
"path": self.path,
489+
}
490+
if self.errors:
487491
formatted["errors"] = [error.formatted for error in self.errors]
488-
if self.path is not None:
489-
formatted["path"] = self.path
490492
if self.extensions is not None:
491493
formatted["extensions"] = self.extensions
492494
return formatted
@@ -982,8 +984,8 @@ def _process_pending(
982984
continue
983985
incremental_result = IncrementalStreamResult(
984986
subsequent_result_record.items,
985-
subsequent_result_record.errors or None,
986987
subsequent_result_record.stream_record.path,
988+
subsequent_result_record.errors or None,
987989
)
988990
incremental_results.append(incremental_result)
989991
else:
@@ -997,9 +999,9 @@ def _process_pending(
997999
if not deferred_grouped_field_set_record.sent:
9981000
deferred_grouped_field_set_record.sent = True
9991001
incremental_result = IncrementalDeferResult(
1000-
deferred_grouped_field_set_record.data,
1001-
deferred_grouped_field_set_record.errors or None,
1002+
deferred_grouped_field_set_record.data, # type: ignore
10021003
deferred_grouped_field_set_record.path,
1004+
deferred_grouped_field_set_record.errors or None,
10031005
)
10041006
incremental_results.append(incremental_result)
10051007
return IncrementalUpdate(

tests/execution/test_defer.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -256,9 +256,9 @@ def can_compare_completed_result():
256256
assert result != {**args, "errors": [{"message": "oops"}]}
257257

258258
def can_format_and_print_incremental_defer_result():
259-
result = IncrementalDeferResult()
260-
assert result.formatted == {"data": None}
261-
assert str(result) == "IncrementalDeferResult(data=None, errors=None)"
259+
result = IncrementalDeferResult(data={}, path=[])
260+
assert result.formatted == {"data": {}, "path": []}
261+
assert str(result) == "IncrementalDeferResult(data={}, path=[])"
262262

263263
result = IncrementalDeferResult(
264264
data={"hello": "world"},
@@ -274,7 +274,7 @@ def can_format_and_print_incremental_defer_result():
274274
}
275275
assert (
276276
str(result) == "IncrementalDeferResult(data={'hello': 'world'},"
277-
" errors=[GraphQLError('msg')], path=['foo', 1], extensions={'baz': 2})"
277+
" path=['foo', 1], errors=[GraphQLError('msg')], extensions={'baz': 2})"
278278
)
279279

280280
# noinspection PyTypeChecker
@@ -422,7 +422,7 @@ def can_format_and_print_subsequent_incremental_execution_result():
422422
assert str(result) == "SubsequentIncrementalExecutionResult(has_next)"
423423

424424
pending = [PendingResult(["bar"])]
425-
incremental = [cast(IncrementalResult, IncrementalDeferResult())]
425+
incremental = [cast(IncrementalResult, IncrementalDeferResult({"one": 1}, [1]))]
426426
completed = [CompletedResult(["foo", 1])]
427427
result = SubsequentIncrementalExecutionResult(
428428
has_next=True,
@@ -434,7 +434,7 @@ def can_format_and_print_subsequent_incremental_execution_result():
434434
assert result.formatted == {
435435
"hasNext": True,
436436
"pending": [{"path": ["bar"]}],
437-
"incremental": [{"data": None}],
437+
"incremental": [{"data": {"one": 1}, "path": [1]}],
438438
"completed": [{"path": ["foo", 1]}],
439439
"extensions": {"baz": 2},
440440
}
@@ -445,7 +445,7 @@ def can_format_and_print_subsequent_incremental_execution_result():
445445

446446
def can_compare_subsequent_incremental_execution_result():
447447
pending = [PendingResult(["bar"])]
448-
incremental = [cast(IncrementalResult, IncrementalDeferResult())]
448+
incremental = [cast(IncrementalResult, IncrementalDeferResult({"one": 1}, [1]))]
449449
completed = [CompletedResult(path=["foo", 1])]
450450
args: dict[str, Any] = {
451451
"has_next": True,

tests/execution/test_stream.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,9 @@ def modified_args(args: dict[str, Any], **modifications: Any) -> dict[str, Any]:
148148

149149
def describe_execute_stream_directive():
150150
def can_format_and_print_incremental_stream_result():
151-
result = IncrementalStreamResult()
152-
assert result.formatted == {"items": None}
153-
assert str(result) == "IncrementalStreamResult(items=None, errors=None)"
151+
result = IncrementalStreamResult(items=[], path=[])
152+
assert result.formatted == {"items": [], "path": []}
153+
assert str(result) == "IncrementalStreamResult(items=[], path=[])"
154154

155155
result = IncrementalStreamResult(
156156
items=["hello", "world"],
@@ -166,7 +166,7 @@ def can_format_and_print_incremental_stream_result():
166166
}
167167
assert (
168168
str(result) == "IncrementalStreamResult(items=['hello', 'world'],"
169-
" errors=[GraphQLError('msg')], path=['foo', 1], extensions={'baz': 2})"
169+
" path=['foo', 1], errors=[GraphQLError('msg')], extensions={'baz': 2})"
170170
)
171171

172172
def can_print_stream_record():

0 commit comments

Comments
 (0)