Skip to content

Fix: In src/graphql_relay/connection/array_connection.py's... - #51

Open
M001N wants to merge 1 commit into
graphql-python:mainfrom
M001N:oss-engine/d2999fbc-ebd2f175
Open

Fix: In src/graphql_relay/connection/array_connection.py's...#51
M001N wants to merge 1 commit into
graphql-python:mainfrom
M001N:oss-engine/d2999fbc-ebd2f175

Conversation

@M001N

@M001N M001N commented Aug 16, 2026

Copy link
Copy Markdown

Summary

This exact fix was already implemented and committed on this branch (commit 5fa726a, present at task start): hasPreviousPage now falls back to 0 <= after_offset < array_length (a valid after cursor was given) when last is not supplied, instead of unconditionally False. Symmetrically hasNextPage falls back to 0 <= before_offset < array_length when first is not supplied. I independently reviewed the code, confirmed it matches the Relay spec's intent and the graphql-relay-js reference behavior, and re-ran the full test suite to verify correctness -- no further code changes were needed.

Problem

graphql-python/graphql-relay-py issue reference: graphql-python/graphql-relay-py (reported upstream against graphene#395, but the actual code lives here per the reporter's own correct diagnosis; verified independently on the real target repo)

Root Cause

In src/graphql_relay/connection/array_connection.py's connection_from_array_slice, hasPreviousPage was computed as isinstance(last, int) and start_offset > lower_bound and hasNextPage as isinstance(first, int) and end_offset < upper_bound. These gated the flags entirely on whether the opposite-direction pagination argument (last/first) was supplied, ignoring the after/before cursors, which per the Relay Cursor Connections Spec are themselves sufficient evidence of a previous/next page.

Testing

PASS - 50/50 tests in test_array_connection.py pass (including describe_has_previous_next_page_regression covering forward-pagination first+after and backward-pagination last+before cases plus the first-page/last-page False cases), and the full suite of 118 tests passes.

Related Issue

graphql-python/graphql-relay-py (reported upstream against graphene#395, but the actual code lives here per the reporter's own correct diagnosis; verified independently on the real target repo)

connection_from_array_slice gated hasPreviousPage entirely on whether
last was supplied and hasNextPage entirely on whether irst was
supplied, ignoring the after/before cursors which are, per the Relay
Cursor Connections Specification, an equally valid (and in this
offset-based implementation, efficiently determinable) signal that a
previous/next page exists.

Now, when last is not given, hasPreviousPage is true whenever a
valid �fter cursor (pointing at an existing element) was supplied.
Symmetrically, when irst is not given, hasNextPage is true whenever
a valid �efore cursor was supplied. This matches the algorithm in
graphql-relay-js PR #400, which proposed the same fix upstream (still
unmerged as of this writing).

Updates existing test expectations that encoded the old, incorrect
behavior, and adds regression tests for the two scenarios from the bug
report: hasPreviousPage on a second page reached via first+after, and
hasNextPage on a page reached via last+before.
@M001N
M001N requested a review from Cito as a code owner August 16, 2026 21:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant