{"record":{"id":"5d2e719948179002","repo":"pandas-dev/pandas","slug":"unary-addition-not-supported","errorCode":null,"errorMessage":"Unary addition not supported","messagePattern":"Unary addition not supported","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"pandas/core/computation/pytables.py","lineNumber":466,"sourceCode":"    term_type: ClassVar[type[Term]] = Term\n\n    def __init__(self, env, engine, parser, **kwargs) -> None:\n        super().__init__(env, engine, parser)\n        for bin_op in self.binary_ops:\n            bin_node = self.binary_op_nodes_map[bin_op]\n            setattr(\n                self,\n                f\"visit_{bin_node}\",\n                lambda node, bin_op=bin_op: partial(BinOp, bin_op, **kwargs),\n            )\n\n    def visit_UnaryOp(self, node, **kwargs) -> ops.Term | UnaryOp | None:\n        if isinstance(node.op, (ast.Not, ast.Invert)):\n            return UnaryOp(\"~\", self.visit(node.operand))\n        elif isinstance(node.op, ast.USub):\n            return self.const_type(-self.visit(node.operand).value, self.env)\n        elif isinstance(node.op, ast.UAdd):\n            raise NotImplementedError(\"Unary addition not supported\")\n        # TODO: return None might never be reached\n        return None\n\n    def visit_Index(self, node, **kwargs):\n        return self.visit(node.value).value\n\n    def visit_Assign(self, node, **kwargs):\n        cmpr = ast.Compare(\n            ops=[ast.Eq()], left=node.targets[0], comparators=[node.value]\n        )\n        return self.visit(cmpr)\n\n    def visit_Subscript(self, node, **kwargs) -> ops.Term:\n        # only allow simple subscripts\n\n        value = self.visit(node.value)\n        slobj = self.visit(node.slice)\n        try:","sourceCodeStart":448,"sourceCodeEnd":484,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/computation/pytables.py#L448-L484","documentation":"Raised by PyTablesExprVisitor.visit_UnaryOp in pandas.core.computation.pytables when the AST node is ast.UAdd (a unary '+' prefix like '+x'). The visitor handles ast.Not/ast.Invert as '~' and ast.USub by negating a constant, but explicit unary plus is not supported in HDFStore where clauses and raises NotImplementedError.","triggerScenarios":"store.select('df', where='+a > 0'); pd.read_hdf(path, where='+index == 5'). Anywhere a leading '+' appears before an identifier in a pytables where expression.","commonSituations":"Copy-pasting expressions from numeric code that uses unary '+' for emphasis/clarity; programmatic generation of where strings that prepend '+' to numeric tokens.","solutions":["Remove the unary '+' from the expression: where='a > 0' instead of where='+a > 0'.","If the '+' was meant to coerce type, precompute the column with the desired dtype and store it.","Simplify the where clause to plain identifiers and comparison operators."],"exampleFix":"# before\nstore.select('df', where='+amount > 0')  # NotImplementedError: Unary addition not supported\n\n# after\nstore.select('df', where='amount > 0')","handlingStrategy":"validation","validationCode":"import re\n\ndef strip_unary_plus(where: str) -> str:\n    return re.sub(r'(?<![A-Za-z0-9_)\\]\\s])\\s*\\+(?=[A-Za-z_(])', '', where)\n\nwhere = strip_unary_plus(where)","typeGuard":"def has_unary_plus(where: str) -> bool:\n    import re\n    return bool(re.search(r'(?<![A-Za-z0-9_)\\]\\s])\\s*\\+(?=[A-Za-z_(])', where))\n","tryCatchPattern":"try:\n    store.select('df', where=where)\nexcept NotImplementedError as e:\n    if 'Unary addition not supported' in str(e):\n        where = strip_unary_plus(where)\n        store.select('df', where=where)\n    else:\n        raise","preventionTips":["Never prefix identifiers with '+' in where clauses.","Sanitize programmatically generated where strings to drop unary '+'.","Keep where expressions to plain identifiers and comparison operators."],"tags":["pandas","hdf5","pytables","where","unary"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}