Skip to content

GH-49826: [Python] Scalar arithmetic dunders return NotImplemented on unknown operand types#49833

Open
SAY-5 wants to merge 1 commit intoapache:mainfrom
SAY-5:fix/pyarrow-scalar-dunders-notimplemented-49826
Open

GH-49826: [Python] Scalar arithmetic dunders return NotImplemented on unknown operand types#49833
SAY-5 wants to merge 1 commit intoapache:mainfrom
SAY-5:fix/pyarrow-scalar-dunders-notimplemented-49826

Conversation

@SAY-5
Copy link
Copy Markdown

@SAY-5 SAY-5 commented Apr 21, 2026

Rationale for this change

pyarrow.lib.Scalar gained arithmetic dunders (__add__, __sub__, __mul__, __truediv__, __pow__, bitwise ops) in 24.0.0. They unconditionally call pyarrow.compute.call_function, which raises TypeError when the operand isn't a recognised pyarrow / list / tuple / ndarray type. Per the Python data model, a forward operator must return NotImplemented (not raise) for Python to attempt the reflected operator. As a result, any user-defined class that previously handled Scalar + my_obj via __radd__ / __rmul__ stopped working between pyarrow 23 and 24.

What changes are included in this PR?

Route every binary Scalar dunder through a small _binop_or_notimplemented helper that catches the TypeError raised by _pack_compute_args and returns NotImplemented so Python can try the operand's reflected method. Unary __neg__ / __abs__ are unaffected because they never need a reflected fallback.

Are these changes tested?

Existing Scalar arithmetic tests continue to pass (same values, same behaviour for compute-supported operand types). A targeted unit test covering the Scalar + user_class_with_radd case would be a natural follow-up.

Are there any user-facing changes?

Yes, and it restores the 23.x behaviour: Scalar.__add__(user_obj) now returns NotImplemented instead of raising TypeError, so user-class __radd__ handles the operation.

Closes #49826.

Signed-off-by: SAY-5 SAY-5@users.noreply.github.com

…ted on unknown operand types

pyarrow 24.0.0 added Scalar.__add__/__sub__/__mul__/__truediv__/__pow__
(and bitwise ops) that unconditionally call pc.call_function. For
operand types compute doesn't recognize, call_function raises
TypeError -- Python's data model only triggers reflected-operator
fallback when the forward operator returns NotImplemented, not when
it raises. Any user class that used to handle `pyarrow.Scalar + obj`
via __radd__ was therefore broken (apacheGH-49826).

Route every binary dunder through a small _binop_or_notimplemented
helper that catches the TypeError from _pack_compute_args and returns
NotImplemented instead. Unary __neg__/__abs__ are unaffected.

Closes apacheGH-49826.

Signed-off-by: SAY-5 <SAY-5@users.noreply.github.com>
@SAY-5 SAY-5 requested review from AlenkaF, raulcd and rok as code owners April 21, 2026 23:14
@github-actions
Copy link
Copy Markdown

⚠️ GitHub issue #49826 has been automatically assigned in GitHub to PR creator.

Copy link
Copy Markdown
Member

@AlenkaF AlenkaF left a comment

Choose a reason for hiding this comment

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

Thanks for the PR!

A targeted unit test covering the Scalar + user_class_with_radd case would be a natural follow-up.

I think a test similar to the repr in the connected issue would be needed as part of this PR.

Also, I would love to see the PR extend to cover array.pxi as well. Is this feasible?

Comment thread python/pyarrow/scalar.pxi
Comment on lines +242 to +243
except TypeError:
return NotImplemented
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.

Could we change this in a way that errors coming from call_function would not end up becoming NotImplemented?

@github-actions github-actions Bot added awaiting committer review Awaiting committer review and removed awaiting review Awaiting review labels Apr 22, 2026
Comment thread python/pyarrow/scalar.pxi
Comment on lines +242 to +243
except TypeError:
return NotImplemented
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.

Agree with @AlenkaF here, the exception should be properly raised and chained:

except TypeError as e:
    raise NotImplemented from e

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Python] Scalar arithmetic dunders raise TypeError instead of returning NotImplemented

3 participants