Skip to content

refactor(to_pandas): single resource classes delegate to_pandas() to their list class - #2761

Merged
haakonvt merged 13 commits into
masterfrom
refactor-list-class-delegation
Aug 21, 2026
Merged

refactor(to_pandas): single resource classes delegate to_pandas() to their list class#2761
haakonvt merged 13 commits into
masterfrom
refactor-list-class-delegation

Conversation

@haakonvt

@haakonvt haakonvt commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Split from #2724

Removes duplicated to_pandas logic between resource classes and their list counterparts (e.g. Group/GroupList, Node/NodeList etc.) by having single resources delegate to _LIST_CLASS([self]).to_pandas(...) and squeeze the result, instead of maintaining a second copy of the conversion logic.

Adds _LIST_CLASS/_RESOURCE back-reference enforcement as a new test in test_meta.py: every CogniteResourceList._RESOURCE must point to a resource class whose _LIST_CLASS points right back, so future additions can't silently drift out of sync. Also adds test_standalone_to_pandas_allowlist, documenting the deliberate exceptions that don't follow this pattern.

Pure refactor, no behavior change. Paves the way for the pandas v2/v3 fix.

Tip to reviewer

Almost all of the changes is part of just one commit, cd3b63f, (57 files changed, 482 insertions(+)). The PR can be reviewed commit-by-commit

@haakonvt
haakonvt requested review from a team as code owners August 10, 2026 17:01

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the to_pandas implementation across various CogniteResource subclasses by delegating the conversion logic to their corresponding list classes, reducing duplication. This is supported by introducing a _LIST_CLASS attribute on resource classes and adding meta-tests to enforce this relationship. Feedback on the changes suggests replacing a runtime assert statement in instances.py with an explicit if check and raising a RuntimeError to ensure defensive programming and runtime safety when Python is run with optimization flags.

Comment thread cognite/client/data_classes/data_modeling/instances.py
@haakonvt
haakonvt force-pushed the refactor-list-class-delegation branch 2 times, most recently from 1046ab0 to eb5edf5 Compare August 10, 2026 17:28
@codecov

codecov Bot commented Aug 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.50649% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.02%. Comparing base (0fbe857) to head (b3cee43).

Files with missing lines Patch % Lines
cognite/client/_api/data_modeling/instances.py 75.00% 2 Missing ⚠️
cognite/client/utils/_pandas_helpers.py 86.66% 2 Missing ⚠️
cognite/client/data_classes/_base.py 93.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2761      +/-   ##
==========================================
- Coverage   93.04%   93.02%   -0.02%     
==========================================
  Files         514      514              
  Lines       52924    52959      +35     
==========================================
+ Hits        49241    49266      +25     
- Misses       3683     3693      +10     
Files with missing lines Coverage Δ
...ognite/client/_sync_api/data_modeling/instances.py 99.04% <ø> (ø)
...ite/client/data_classes/data_modeling/instances.py 91.51% <100.00%> (-0.04%) ⬇️
cognite/client/data_classes/iam.py 96.87% <ø> (-0.10%) ⬇️
...ration/test_api/test_data_modeling/test_records.py 91.42% <100.00%> (-6.65%) ⬇️
tests/tests_unit/test_meta.py 93.25% <100.00%> (+3.60%) ⬆️
cognite/client/data_classes/_base.py 93.61% <93.33%> (-0.16%) ⬇️
cognite/client/_api/data_modeling/instances.py 86.93% <75.00%> (-0.28%) ⬇️
cognite/client/utils/_pandas_helpers.py 91.06% <86.66%> (-0.41%) ⬇️

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@haakonvt
haakonvt force-pushed the refactor-list-class-delegation branch from eb5edf5 to b2b958a Compare August 10, 2026 19:40

@audunska audunska left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice stuff. Out of curiosity, would it have been an option to do it the other way? I.e., have a default to_pandas on CogniteResource, but override it in CogniteResourceList to iterate over the implementation in _RESOURCE.

df = super().to_pandas(
expand_metadata=False, ignore=ignore, camel_case=camel_case, convert_timestamps=convert_timestamps
assert self._LIST_CLASS is not None
df = cast("type[DataModelingInstancesList]", self._LIST_CLASS)([self]).to_pandas(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to override this and not just defer to the base CogniteResource implementation? Will it not use the DataModelingInstancesList implementation if we do that?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do want to delegate to DataModelingInstancesList, but we cannot use the generic CogniteResource.to_pandas path directly as the base method always forwards args like expand_metadata and metadata_prefix, while DataModelingInstancesList.to_pandas uses e.g. expand_properties/remove_property_prefix.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whatever you say 😅

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of garbage in this repo tbh 😅 The one-base-class-fits-all pattern for example...

@haakonvt

haakonvt commented Aug 21, 2026

Copy link
Copy Markdown
Contributor Author

(...) Out of curiosity, would it have been an option to do it the other way? I.e., have a default to_pandas on CogniteResource, but override it in CogniteResourceList to iterate over the implementation in _RESOURCE.

Just for efficiency reasons, repeated calling a function for millions of items in a list isn't exactly cheap in Python 😅

...or, a much better reason is that a pandas dataframe concatenation from individual dataframes would be a really bad idea (just making all those individual ones)

audunska
audunska previously approved these changes Aug 21, 2026
df = super().to_pandas(
expand_metadata=False, ignore=ignore, camel_case=camel_case, convert_timestamps=convert_timestamps
assert self._LIST_CLASS is not None
df = cast("type[DataModelingInstancesList]", self._LIST_CLASS)([self]).to_pandas(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whatever you say 😅

@haakonvt

Copy link
Copy Markdown
Contributor Author

🦄

@haakonvt
haakonvt enabled auto-merge August 21, 2026 08:48
@haakonvt haakonvt self-assigned this Aug 21, 2026
@haakonvt haakonvt added risk-review-ongoing Risk review is in progress waiting-for-team Waiting for the submitter or reviewer of the PR to take an action labels Aug 21, 2026
@haakonvt
haakonvt added this pull request to the merge queue Aug 21, 2026
@haakonvt
haakonvt removed this pull request from the merge queue due to a manual request Aug 21, 2026
@haakonvt

Copy link
Copy Markdown
Contributor Author

🦄

@haakonvt
haakonvt enabled auto-merge August 21, 2026 08:58
@haakonvt
haakonvt added this pull request to the merge queue Aug 21, 2026
Merged via the queue into master with commit 38cbb51 Aug 21, 2026
21 checks passed
@haakonvt
haakonvt deleted the refactor-list-class-delegation branch August 21, 2026 09:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk-review-ongoing Risk review is in progress waiting-for-team Waiting for the submitter or reviewer of the PR to take an action

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants