Skip to content

Conversation

@invain01
Copy link
Contributor

@invain01 invain01 commented Nov 4, 2025

Summary

This change enforces Ruff rule B905 (zip-without-explicit-strict) by adding strict=True or strict=False parameters to all zip() function calls in several critical pandas modules. This ensures that input iterables are of equal length, preventing silent truncation and potential data inconsistencies.

According to issue #62434, all zip() calls should ideally specify strict=True since most of the time there's an underlying assumption that the input arguments are of equal length.

Modified Files

1. pandas/core/reshape/merge.py

Purpose: Core merge operation logic for combining DataFrames

Specific Changes (9 zip() calls updated):

Line Original Updated
1251 zip(self.join_names, self.left_on, self.right_on) zip(self.join_names, self.left_on, self.right_on, strict=True)
1284 zip(self.join_names, self.left_on, self.right_on) zip(self.join_names, self.left_on, self.right_on, strict=True)
1593 zip(self.left_on, self.right_on) zip(self.left_on, self.right_on, strict=True)
1656 zip(self.right.index.levels, self.right.index.codes) zip(self.right.index.levels, self.right.index.codes, strict=True)
1678 zip(self.left.index.levels, self.left.index.codes) zip(self.left.index.levels, self.left.index.codes, strict=True)
1695 zip(self.left_join_keys, self.right_join_keys, self.join_names) zip(self.left_join_keys, self.right_join_keys, self.join_names, strict=True)
2087 zip(*mapped) zip(*mapped, strict=True)
2472 zip(left_join_keys, right_join_keys) zip(left_join_keys, right_join_keys, strict=True)
2657 zip(*mapped) zip(*mapped, strict=True)

Rationale: In merge operations, the join keys, levels, and codes must be of equal length. Using strict=True ensures that any data inconsistency will raise an error rather than silently truncating data.

2. pandas/core/reshape/concat.py

Purpose: Concatenation of DataFrame/Series objects

Specific Changes (3 zip() calls updated):

Line Original Updated Rationale
869 zip(zipped, levels) zip(zipped, levels, strict=True) Zipped and levels must have same length in MultiIndex construction
875 zip(hlevel, indexes) zip(hlevel, indexes, strict=False) Could have different lengths when handling non-uniform indexes
925 zip(zipped, levels) zip(zipped, levels, strict=True) Zipped and levels must have same length

3. pandas/tests/plotting/frame/test_frame.py

Purpose: Test cases for DataFrame plotting functionality

Specific Changes (7 zip() calls updated):

Line Original Updated Rationale
186 zip(string.ascii_letters[:10], range(10)) zip(string.ascii_letters[:10], range(10), strict=True) Both slices have fixed length 10
516 zip(normal_lines, stacked_lines) zip(normal_lines, stacked_lines, strict=True) Both line collections should have equal length
923 zip(result_yticklabels, expected_yticklabels) zip(result_yticklabels, expected_yticklabels, strict=True) Expected and result tick labels should match
1134 zip(axes, labels) zip(axes, labels, strict=True) Axes and labels should be paired one-to-one
1261 dict(zip(["A", "B"], ...)) dict(zip(["A", "B"], ..., strict=True)) Dictionary construction expects equal number of keys and values
1682 zip(axes, df.columns) zip(axes, df.columns, strict=True) Each axis corresponds to exactly one column
2384 dict(zip(xticklabels, ax.get_xticks())) dict(zip(xticklabels, ax.get_xticks(), strict=False)) Labels and ticks may differ after scaling
2402 dict(zip(xticklabels, ax.get_xticks())) dict(zip(xticklabels, ax.get_xticks(), strict=False)) Labels and ticks may differ after scaling
2478 zip(axes, expected_labels) zip(axes, expected_labels, strict=True) Axes and labels should pair one-to-one

4. pandas/tests/reshape/merge/test_merge_asof.py

Purpose: Test cases for asof-merge functionality

Specific Changes (3 zip() calls updated):

Line Original Updated
3252 list(zip([0, 5, 10, 15, 20, 25], [0, 1, 2, 3, 4, 5])) list(zip([0, 5, 10, 15, 20, 25], [0, 1, 2, 3, 4, 5], strict=True))
3259 list(zip([0, 3, 9, 12, 15, 18], [0, 1, 2, 3, 4, 5])) list(zip([0, 3, 9, 12, 15, 18], [0, 1, 2, 3, 4, 5], strict=True))
3270 (inside multi-line zip) Added strict=True to the zip() call

Rationale: Test data construction expects exact pairing of time intervals and values to ensure asof-merge semantics are correctly tested.

5. scripts/validate_unwanted_patterns.py

Purpose: Script for validating code patterns

Specific Changes (1 zip() call updated):

Line Original Updated Rationale
269 zip(tokens, tokens[1:], tokens[2:]) zip(tokens, tokens[1:], tokens[2:], strict=False) Three different slice lengths; element-wise iteration can stop at shortest

Rationale: The three lists have different lengths (original vs. slices), so strict=False is appropriate.

Copy link
Member

@mroeschke mroeschke left a comment

Choose a reason for hiding this comment

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

Next time please disclose your AI use and exclude the extraneous AI output

@mroeschke mroeschke added the Code Style Code style, linting, code_checks label Nov 5, 2025
@mroeschke mroeschke added this to the 3.0 milestone Nov 5, 2025
@mroeschke mroeschke merged commit 842a2c6 into pandas-dev:main Nov 5, 2025
47 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Code Style Code style, linting, code_checks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants