{"record":{"id":"534c3a057f3722f3","repo":"pandas-dev/pandas","slug":"cannot-evaluate-scalar-only-bool-ops","errorCode":null,"errorMessage":"cannot evaluate scalar only bool ops","messagePattern":"cannot evaluate scalar only bool ops","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"pandas/core/computation/ops.py","lineNumber":487,"sourceCode":"        rhs = self.rhs\n        lhs = self.lhs\n\n        # GH#24883 unwrap dtype if necessary to ensure we have a type object\n        rhs_rt = rhs.return_type\n        rhs_rt = getattr(rhs_rt, \"type\", rhs_rt)\n        lhs_rt = lhs.return_type\n        lhs_rt = getattr(lhs_rt, \"type\", lhs_rt)\n        if (\n            (lhs.is_scalar or rhs.is_scalar)\n            and self.op in _bool_ops_dict\n            and (\n                not (\n                    issubclass(rhs_rt, (bool, np.bool_))\n                    and issubclass(lhs_rt, (bool, np.bool_))\n                )\n            )\n        ):\n            raise NotImplementedError(\"cannot evaluate scalar only bool ops\")\n\n\nUNARY_OPS_SYMS = (\"+\", \"-\", \"~\", \"not\")\n_unary_ops_funcs = (operator.pos, operator.neg, operator.invert, operator.invert)\n_unary_ops_dict = dict(zip(UNARY_OPS_SYMS, _unary_ops_funcs, strict=True))\n\n\nclass UnaryOp(Op):\n    \"\"\"\n    Hold a unary operator and its operands.\n\n    Parameters\n    ----------\n    op : str\n        The token used to represent the operator.\n    operand : Term or Op\n        The Term or Op operand to the operator.\n","sourceCodeStart":469,"sourceCodeEnd":505,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/computation/ops.py#L469-L505","documentation":"Raised by BinOp._disallow_scalar_only_bool_ops in pandas.core.computation.ops when a boolean operator (&, |, and, or) is applied between operands where at least one is a scalar AND not both sides are bool/np.bool_. pandas deliberately refuses to apply Python's bitwise-and/or to non-bool scalars (e.g. integers) because the result is ambiguous (bitwise vs logical). It is raised as NotImplementedError and is intentionally conservative.","triggerScenarios":"pd.eval('@x & @y') with x,y being non-bool scalars (e.g. ints); pd.eval('1 & 2'); pd.eval('(a > 0) & 5') where one side collapses to a scalar. Also df.query('a & 3') where 3 is treated as a scalar.","commonSituations":"Treating pandas eval like Python and expecting 'and'/'&' to work on integer truthiness; mixing boolean column masks with scalar thresholds; migrating code from plain Python `and`/`or` to vectorized eval without converting operands to bool first.","solutions":["Convert operands to bool explicitly before combining: pd.eval('(a > 0) & (b > 0)') instead of 'a & b'.","If combining scalar truth values, use plain Python (x and y) outside of pd.eval, or pass them as bool(x) & bool(y).","For integer bitwise AND, apply the operator directly on the Series outside eval (s1 & s2), or wrap with bool() if you truly want logical semantics."],"exampleFix":"# before\nimport pandas as pd\npd.eval('1 & 2')  # NotImplementedError: cannot evaluate scalar only bool ops\n\n# after (logical)\npd.eval('bool(1) & bool(2)')   # explicit bool cast\n# after (bitwise on integers -> skip eval)\n1 & 2","handlingStrategy":"validation","validationCode":"def coerce_bool(value):\n    return bool(value) if not hasattr(value, '__iter__') else value.astype(bool)\n\n# ensure both sides are bool before combining with & / | in eval\n","typeGuard":"import numpy as np\n\ndef is_bool_scalar(x) -> bool:\n    return isinstance(x, (bool, np.bool_))\n","tryCatchPattern":"try:\n    pd.eval('x & y', local_dict={'x': x, 'y': y})\nexcept NotImplementedError as e:\n    if 'scalar only bool ops' in str(e):\n        # cast to bool and retry, or apply directly\n        result = bool(x) & bool(y)\n    else:\n        raise","preventionTips":["Wrap operands in explicit comparisons: '(a > 0) & (b > 0)' instead of 'a & b'.","Cast scalars to bool before combining: bool(x) & bool(y).","For bitwise integer ops, apply operators directly on Series outside eval."],"tags":["pandas","eval","boolean","scalar"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}