[SPARK-59513][PYTHON] Compare Row lengths in assertDataFrameEqual by laserninja · Pull Request #58789 · apache/spark · GitHub
Skip to content

[SPARK-59513][PYTHON] Compare Row lengths in assertDataFrameEqual - #58789

Open
laserninja wants to merge 1 commit into
apache:masterfrom
laserninja:fix/row-comparison-arity
Open

laserninja wants to merge 1 commit into
apache:masterfrom
laserninja:fix/row-comparison-arity

Conversation

@laserninja

@laserninja laserninja commented Sep 14, 2026

Copy link
Copy Markdown

What changes were proposed in this pull request?

Jira: SPARK-59513

Check Row lengths before recursively comparing field values. Add tests for either side having extra fields, empty Rows, nested Rows, arrays, maps, and both row-order settings.

Why are the changes needed?

The Row comparator uses zip without a length check, so trailing fields are ignored. List-of-Row inputs are supported and do not undergo a DataFrame schema comparison, allowing unequal results to pass assertions.

from pyspark.sql import Row
from pyspark.testing import assertDataFrameEqual
assertDataFrameEqual([Row(x=1)], [Row(x=1, y=2)])
# Returns without raising

Does this PR introduce any user-facing change?

Yes. assertDataFrameEqual raises DIFFERENT_ROWS when corresponding Rows contain different numbers of fields, including nested Rows.

How was this patch tested?

The new regression tests failed before the fix and passed afterward on Python 3.10.11 with NumPy 2.2.6. The focused run passed 2 tests, including parameterized subtests:

PYTHONPATH=python TERM=dumb python -m unittest pyspark.sql.tests.test_utils.RowComparisonTests -q
PYTHON_EXECUTABLE=python ./dev/lint-python --compile --custom-pyspark-error --ruff

Run the commands with the Python virtual environment activated; the local run shared an environment from a sibling checkout. The tests call public Python APIs directly and require no SparkSession. Python compilation, custom-error checks, Ruff lint, and Ruff formatting passed. JVM-backed suites were not run because these fixes are confined to Python-side logic.

Was this patch authored or co-authored using generative AI tooling?

Generated-by: OpenAI Codex (GPT-6).

@HyukjinKwon HyukjinKwon 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.

  • compare_vals: adding len(val1) == len(val2) to the Row branch is the right fix and
    mirrors the existing list and dict branches. The Row branch is reachable because
    Row is a tuple subclass, not a list, so the list branch above does not intercept
    it. And since list/dict values recurse back into compare_vals, the length check also
    protects Rows nested inside lists and maps -- which the new tests exercise.
  • Tests: good coverage -- both argument orders, plain/nested-Row/array/map wrapping, and
    both checkRowOrder values. unittest.TestCase is the right base here (no SparkSession
    is needed for list-of-Row inputs). Imports and line lengths are clean.

One process nit: this is a user-facing behavior change to a public API (assertDataFrameEqual
now raises DIFFERENT_ROWS on an arity mismatch), so it should carry a SPARK-xxxxx JIRA in
the title rather than a bare [PYTHON] tag. You already note the Jira is pending -- worth
creating it and updating the title before merge.

Nothing blocking in the code.

@laserninja
laserninja force-pushed the fix/row-comparison-arity branch from 305566e to 9a6f5d9 Compare September 15, 2026 01:16
@laserninja laserninja changed the title [PYTHON] Compare Row lengths in assertDataFrameEqual [SPARK-59513][PYTHON] Compare Row lengths in assertDataFrameEqual Sep 15, 2026
@laserninja

Copy link
Copy Markdown
Author

@laserninja
laserninja marked this pull request as ready for review September 15, 2026 02:32
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.

2 participants