Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Support tuple unpacking of DataOps - #2243

Merged
jeromedockes merged 3 commits into
skrub-data:mainfrom
e-strauss:tuple-unpacking
Sep 11, 2026
Merged

Support tuple unpacking of DataOps#2243
jeromedockes merged 3 commits into
skrub-data:mainfrom
e-strauss:tuple-unpacking

Conversation

@e-strauss

@e-strauss e-strauss commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

a, b, c = data_op now creates a node per target instead of raising an error, so a deferred function returning several values can be unpacked as usual.

Python calls iter() on the right-hand side from an UNPACK_SEQUENCE instruction whose argument is the number of targets, so DataOp.__iter__ reads that count off the calling frame's bytecode and creates an AsTuple node (which converts the result to a tuple and checks its length) plus one GetItem per target. A wrong number of targets is reported eagerly when a preview value is available, and at evaluation time otherwise.

Only UNPACK_SEQUENCE is recognised, so anything else (for loops, list(data_op), f(*data_op), a, *rest = data_op) keeps raising the previous TypeError, as does any case where the bytecode cannot be inspected. Indexing into the result stays available as a portable alternative.

Example:

test = skrub.var("test", [1, 2])

@skrub.deferred
def process_test_data(test):
   left = test[0]
   right = test[1]
   return left, right

# works now without raising
left, right = process_test_data(test)

@e-strauss
e-strauss marked this pull request as ready for review August 5, 2026 13:42
Copilot AI lite review requested due to automatic review settings August 5, 2026 13:42

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR adds support for tuple unpacking of DataOp objects (e.g. a, b, c = data_op) by inspecting the caller’s bytecode to detect UNPACK_SEQUENCE, building an AsTuple node plus one GetItem node per target, and preserving the previous “no eager iteration” behavior for other iteration forms.

Changes:

  • Implement bytecode-based unpack arity detection and DataOp.__iter__ support for UNPACK_SEQUENCE.
  • Add an AsTuple node + unpack() constructor to support unpacking any iterable and to validate expected length.
  • Add tests + documentation/changelog updates describing supported/unsupported unpacking cases and error behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
skrub/_data_ops/_data_ops.py Implements _unpack_arity(), updates DataOp.__iter__, and introduces AsTuple/unpack() to enable assignment unpacking.
skrub/_data_ops/tests/test_data_ops.py Adds coverage for basic, iterable, and nested unpacking behavior.
skrub/_data_ops/tests/test_errors.py Adds coverage for unsupported starred unpacking, bytecode-inspection failure fallbacks, and wrong-target-count errors.
doc/modules/data_ops/basics/control_flow.rst Updates docs to show supported unpacking and documents bytecode-based limitations + fallback indexing.
CHANGES.rst Adds a release-note entry announcing tuple unpacking support.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread skrub/_data_ops/_data_ops.py
Comment thread skrub/_data_ops/_data_ops.py Outdated
Comment thread CHANGES.rst Outdated
Comment thread skrub/_data_ops/tests/test_data_ops.py Outdated
`a, b, c = data_op` now creates a node per target instead of raising an error, so a deferred function returning several values can be unpacked as usual.

Python calls `iter()` on the right-hand side from an `UNPACK_SEQUENCE` instruction whose argument is the number of targets, so `DataOp.__iter__` reads that count off the calling frame's bytecode and creates an `AsTuple` node (which converts the result to a tuple and checks its length) plus one `GetItem` per target. A wrong number of targets is reported eagerly when a preview value is available, and at evaluation time otherwise.

Only `UNPACK_SEQUENCE` is recognised, so anything else (`for` loops, `list(data_op)`, `f(*data_op)`, `a, *rest = data_op`) keeps raising the previous TypeError, as does any case where the bytecode cannot be inspected. Indexing into the result stays available as a portable alternative.
@jeromedockes

Copy link
Copy Markdown
Member

thanks a lot for opening this PR, @e-strauss !!

for context, the original discussion where @e-strauss proposed this approach happened on the skrub discord:

https://discord.com/channels/1220094555282477159/1532375520405229649

@jeromedockes jeromedockes left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

looks great apart from some nitpicks! this is an issue that had come up a couple of times so it is a really neat improvement, thanks a lot @e-strauss ! :)

Comment thread skrub/_data_ops/_data_ops.py Outdated
Comment thread skrub/_data_ops/_data_ops.py
Comment thread skrub/_data_ops/_data_ops.py Outdated
Comment thread skrub/_data_ops/_data_ops.py Outdated
Comment thread CHANGES.rst Outdated
@jeromedockes jeromedockes added enhancement New feature or request data_ops Something related to the skrub DataOps labels Aug 7, 2026
@rcap107 rcap107 modified the milestones: Release 0.10.1, Release 0.11 Aug 25, 2026
@rcap107

rcap107 commented Sep 7, 2026

Copy link
Copy Markdown
Member

Hi @e-strauss, thanks a lot for the time you spent on this PR!

We're planning another release soon-ish (not before a couple of weeks) and it'd be great if this PR could be part of it. Do you think you'll have time to work on this? If not, no problem at all and no pressure: it'll just go in the next release some more time down the line.

@e-strauss

Copy link
Copy Markdown
Contributor Author

Hi @rcap107 , I will get to back it this week :)

@rcap107

rcap107 commented Sep 7, 2026

Copy link
Copy Markdown
Member

Hi @rcap107 , I will get to back it this week :)

Amazing, thanks a lot!

@rcap107

rcap107 commented Sep 9, 2026

Copy link
Copy Markdown
Member

Just a heads up that the docs have been moved from doc/ to skrub/_docs

@jeromedockes jeromedockes left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

cool, this is a very nice addition! thank you very much @e-strauss :)

@jeromedockes
jeromedockes merged commit 309e647 into skrub-data:main Sep 11, 2026
29 checks passed
@e-strauss

Copy link
Copy Markdown
Contributor Author

cool, this is a very nice addition! thank you very much @e-strauss :)

thanks for the assistance :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

data_ops Something related to the skrub DataOps enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants