Skip to content

fix: PageIterator does not correctly capture the @odata.deltaLink - #1117

Open
Diederik Greveling (DPGrev) wants to merge 5 commits into
microsoftgraph:mainfrom
DPGrev:fix/page-iterator-delta-link
Open

fix: PageIterator does not correctly capture the @odata.deltaLink#1117
Diederik Greveling (DPGrev) wants to merge 5 commits into
microsoftgraph:mainfrom
DPGrev:fix/page-iterator-delta-link

Conversation

@DPGrev

Copy link
Copy Markdown

Summary

PageIterator.delta_link was effectively always empty for real usage, for two separate reasons:

  • PageResult had no field or deserializer for @odata.deltaLink, so it was silently dropped when a page response was parsed.
  • PageIterator.__init__ read the delta link via getattr(response, '@odata.deltaLink', ''), which is never a valid attribute name on a Kiota Parsable model, so it always fell through to ''.
  • Even once fixed, the delta link was only ever inspected on the initial response passed to the constructor and never updated as later pages were fetched via next() — but in a real multi-page delta sync, the delta link normally only appears on the final page.

This PR:

  • Adds an odata_delta_link field (and its @odata.deltaLink (de)serialization) to PageResult.
  • Fixes PageIterator to read the delta link correctly and to keep it updated as next() advances through pages.
  • Adds an additional_data fallback when extracting the delta link, matching how the .NET SDK's PageIterator checks AdditionalData before its strongly-typed OdataDeltaLink property — this covers a custom constructor_callable model that doesn't declare the field explicitly.

Test plan

  • pytest tests/tasks/test_page_iterator.py tests/tasks/test_page_result.py — added two regression tests: a multi-page delta sync where the delta link only appears on the final page, and a page model that only carries the delta link in additional_data.
  • Full suite: pytest tests — 76 passed.
  • pylint src/msgraph_core/tasks/page_iterator.py src/msgraph_core/models/page_result.py — 10.00/10.

PageResult had no field/deserializer for @odata.deltaLink, so it was
silently dropped when parsing a page response. PageIterator also read
the delta link from a Parsable model via getattr(response,
'@odata.deltaLink', ''), which can never match a real attribute name
and always returned an empty string, and it only inspected the very
first response, never updating delta_link as later pages (where the
delta link normally appears) were fetched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Matches the .NET SDK's PageIterator, which checks AdditionalData
before the strongly-typed OdataDeltaLink property. A custom
constructor_callable model that doesn't declare odata_delta_link would
otherwise silently lose the delta link, same failure mode as before.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@DPGrev
Diederik Greveling (DPGrev) requested a review from a team as a code owner September 3, 2026 13:47
Keeps the field addition purely additive for positional construction
(PageResult(next_link, value)), avoiding a breaking change for any
downstream caller not using keyword arguments, per the repo's
contribution guideline against interface-breaking trivial PRs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Use PEP 604 union syntax for the type hint and extract the repeated
'@odata.deltaLink' literal into a constant.
Removes boilerplate for the additional_data fallback test without
losing coverage of that code path.
@sonarqubecloud

sonarqubecloud Bot commented Sep 3, 2026

Copy link
Copy Markdown

@DPGrev

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

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