pandas-dev/pandas · error · NotImplementedError
UnaryOp only support invert type ops
Error message
UnaryOp only support invert type ops
What it means
Raised in the PyTables UnaryOp.prune when self.op is not '~'. The HDFStore where-clause evaluator only supports the bitwise-invert unary operator '~' (and ast.Not is mapped to '~' in visit_UnaryOp). Other unary forms such as unary minus '-' are handled earlier (USub returns a constant) and 'not' is mapped, so reaching this branch implies an unsupported unary operator slipped through, e.g. a constructed UnaryOp('+', ...) or 'not' that bypassed the mapping.
Solutions
- Rewrite the predicate to use '~' for negation: store.select('df', where='~(A > 0)').
- For unary minus, precompute the negated column and store it as a data_column: df['neg_A'] = -df['A'].
- Avoid non-invert unary operators in HDFStore where clauses; filter in pandas instead.
Example fix
// before
store.select('df', where='-A > 1')
// after
df['neg_A'] = -df['A']
store.put('df', df, format='table', data_columns=['neg_A'])
store.select('df', where='neg_A > 1') Defensive patterns
Strategy: validation
Validate before calling
import re
def where_has_non_invert_unary(where: str) -> bool:
# detect unary minus directly on an identifier (not folded to constant)
return bool(re.search(r'(?<![\w\d)])-[A-Za-z_]', where))
assert not where_has_non_invert_unary(where_clause) Type guard
def is_invert_op(op: str) -> bool:
return op == '~' Try / catch
try:
store.select('df', where='-A > 1')
except NotImplementedError as e:
if 'UnaryOp only support invert' in str(e):
df = store.get('df')
df[-df['A'] > 1]
else:
raise Prevention
- Use only '~' as a unary operator in HDFStore where clauses.
- Precompute negated columns and store them as data_columns.
- Filter in pandas for unary-minus predicates.
When it happens
Trigger: store.select('df', where='-A > 1') where '-' is not folded into a constant by visit_UnaryOp (e.g. operand is non-numeric). Programmatic construction of a pytables UnaryOp with an operator other than '~'. Internal calls passing 'not' or '+' into prune.
Common situations: Using unary minus on a non-numeric column inside a where clause. Custom subclasses of the PyTables visitor that emit UnaryOp nodes with non-invert ops. AST rewriting that loses the USub folding.
Related errors
- Unary addition not supported
- arithmetic operations are not supported inside an HDFStore…
- Cannot compare of type to column
- cannot subscript with
- cannot use an invert condition when passing to numexpr
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/6b4d1a0dafbc4c64.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/computation/pytables.py:429
else:
return None
else:
self.condition = self.generate(values[0])
return self
class JointConditionBinOp(ConditionBinOp):
# error: Signature of "evaluate" incompatible with supertype "BinOp"
def evaluate(self) -> Self: # type: ignore[override]
self.condition = f"({self.lhs.condition} {self.op} {self.rhs.condition})"
return self
class UnaryOp(ops.UnaryOp):
def prune(self, klass):
if self.op != "~":
raise NotImplementedError("UnaryOp only support invert type ops")
operand = self.operand
operand = operand.prune(klass)
if operand is not None and (
(issubclass(klass, ConditionBinOp) and operand.condition is not None)
or (
not issubclass(klass, ConditionBinOp)
and issubclass(klass, FilterBinOp)
and operand.filter is not None
)
):
return operand.invert()
return None
class PyTablesExprVisitor(BaseExprVisitor):
const_type: ClassVar[type[ops.Term]] = ConstantView on GitHub (pinned to 3b7651241d)