pandas-dev/pandas · error · NotImplementedError
cannot evaluate scalar only bool ops
Error message
cannot evaluate scalar only bool ops
What it means
Raised in BinOp._disallow_scalar_only_bool_ops when at least one operand is scalar, the operator is a boolean op (&, |, and, or), and the operand types are not both bool/np.bool_. The eval engine refuses to silently coerce scalar non-bool values through Python truthiness inside a vectorized boolean expression, because the result would be ambiguous (element-wise vs scalar truth).
Solutions
- Convert scalar operands to bool explicitly before the eval: pd.eval('bool(1) & bool(2)') is still rejected — instead pass booleans: flag = True; df.query('@flag & (A > 0)').
- Use comparison operators to produce boolean scalars: df.query('(A > 0) & (B > 0)') instead of df.query('A & 1').
- Move scalar boolean logic out of the query string and combine in Python afterward.
- If the scalar is meant as a mask, broadcast it: pd.eval('(A > 0) & True') works because True is bool.
Example fix
// before
pd.eval("1 & 2")
df.query("A & 1")
// after
pd.eval("True & False")
df.query("A & (B > 0)") Defensive patterns
Strategy: validation
Validate before calling
from pandas.core.computation.ops import _bool_ops_dict
from pandas.core.dtypes.common import is_scalar, is_bool_dtype
import numpy as np
def bool_op_safe(lhs, rhs, op: str) -> bool:
if op not in _bool_ops_dict:
return True
if not (is_scalar(lhs) or is_scalar(rhs)):
return True
lt = type(lhs); rt = type(rhs)
return issubclass(lt, (bool, np.bool_)) and issubclass(rt, (bool, np.bool_))
assert bool_op_safe(1, 2, '&') is False # would raise Type guard
import numpy as np
from typing import Any
def operands_bool_safe(lhs: Any, rhs: Any, op: str) -> bool:
if op not in ('&', '|', 'and', 'or'):
return True
return isinstance(lhs, (bool, np.bool_)) and isinstance(rhs, (bool, np.bool_)) Try / catch
try:
pd.eval('1 & 2')
except NotImplementedError as e:
if 'scalar only bool ops' in str(e):
pd.eval('True & False')
else:
raise Prevention
- Convert scalar operands to bool before boolean ops in eval.
- Use comparison operators to produce boolean scalars.
- Avoid scalar integer operands with & / | / and / or inside eval strings.
When it happens
Trigger: pd.eval('1 & 2'), pd.eval('5 and 3'), df.query('A & 1') where one side is a scalar int. Any boolean operator applied between a scalar non-bool (int, float, str) and another term inside eval/query.
Common situations: Treating eval like Python and expecting short-circuit truthiness on scalars. Mixing bitwise & with integer masks inside query. Migrating from plain Python boolean expressions to df.query() without converting flags to bool.
Related errors
- Function " " does not support keyword arguments
- Invalid function call
- keyword error in function call
- N-dimensional objects, where N > 2, are not supported with…
- " " is not a supported function
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/534c3a057f3722f3.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/computation/ops.py:487
rhs = self.rhs
lhs = self.lhs
# GH#24883 unwrap dtype if necessary to ensure we have a type object
rhs_rt = rhs.return_type
rhs_rt = getattr(rhs_rt, "type", rhs_rt)
lhs_rt = lhs.return_type
lhs_rt = getattr(lhs_rt, "type", lhs_rt)
if (
(lhs.is_scalar or rhs.is_scalar)
and self.op in _bool_ops_dict
and (
not (
issubclass(rhs_rt, (bool, np.bool_))
and issubclass(lhs_rt, (bool, np.bool_))
)
)
):
raise NotImplementedError("cannot evaluate scalar only bool ops")
UNARY_OPS_SYMS = ("+", "-", "~", "not")
_unary_ops_funcs = (operator.pos, operator.neg, operator.invert, operator.invert)
_unary_ops_dict = dict(zip(UNARY_OPS_SYMS, _unary_ops_funcs, strict=True))
class UnaryOp(Op):
"""
Hold a unary operator and its operands.
Parameters
----------
op : str
The token used to represent the operator.
operand : Term or Op
The Term or Op operand to the operator.
View on GitHub (pinned to 3b7651241d)