{"record":{"id":"298a4db0d687916a","repo":"pandas-dev/pandas","slug":"cannot-use-an-invert-condition-when-passing-to-num","errorCode":null,"errorMessage":"cannot use an invert condition when passing to numexpr","messagePattern":"cannot use an invert condition when passing to numexpr","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"pandas/core/computation/pytables.py","lineNumber":383,"sourceCode":"class JointFilterBinOp(FilterBinOp):\n    def format(self):\n        raise NotImplementedError(\"unable to collapse Joint Filters\")\n\n    # error: Signature of \"evaluate\" incompatible with supertype \"BinOp\"\n    def evaluate(self) -> Self:  # type: ignore[override]\n        return self\n\n\nclass ConditionBinOp(BinOp):\n    def __repr__(self) -> str:\n        return pprint_thing(f\"[Condition : [{self.condition}]]\")\n\n    def invert(self):\n        \"\"\"invert the condition\"\"\"\n        # if self.condition is not None:\n        #    self.condition = \"~(%s)\" % self.condition\n        # return self\n        raise NotImplementedError(\n            \"cannot use an invert condition when passing to numexpr\"\n        )\n\n    def format(self):\n        \"\"\"return the actual ne format\"\"\"\n        return self.condition\n\n    # error: Signature of \"evaluate\" incompatible with supertype \"BinOp\"\n    def evaluate(self) -> Self | None:  # type: ignore[override]\n        if not self.is_valid:\n            raise ValueError(f\"query term is not valid [{self}]\")\n\n        # convert values if we are in the table\n        if not self.is_in_table:\n            return None\n\n        rhs = self.conform(self.rhs)\n        values = [self.convert_value(v) for v in rhs]","sourceCodeStart":365,"sourceCodeEnd":401,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/computation/pytables.py#L365-L401","documentation":"Raised in ConditionBinOp.invert. ConditionBinOp produces a numexpr condition string (e.g. '(A > 5)'); numexpr/PyTables condition inversion via Python '~' is not wired up, so attempting to invert a condition — typically through a '~(...)' wrapper in the where clause routed through the numexpr engine — raises NotImplementedError. The commented-out code shows the historical attempt to wrap the condition in '~(...)'.","triggerScenarios":"store.select('df', where='~(A > 5)') when the condition is compiled for numexpr. Also from explicit .invert() calls on a ConditionBinOp during query pruning, or using 'not' inside a where clause that resolves to a numexpr condition.","commonSituations":"Negating a where clause expecting SQL-style NOT. Porting df[~(df.A > 5)] to HDFStore select. Mixing '~' with numexpr-routed conditions.","solutions":["Rewrite the negation as a positive condition: store.select('df', where='A <= 5') instead of '~(A > 5)'.","Use De Morgan's laws to push the negation onto comparisons: '~(A > 5 & B < 3)' -> '(A <= 5 | B >= 3)'.","Read the data and filter in pandas if rewriting is impractical."],"exampleFix":"// before\nstore.select('df', where='~(A > 5)')\n\n// after\nstore.select('df', where='A <= 5')","handlingStrategy":"validation","validationCode":"import re\n\ndef where_has_invert(where: str) -> bool:\n    return bool(re.search(r'~\\s*\\(', where))\n\nassert not where_has_invert(where_clause), 'invert (~) conditions are not supported via numexpr in HDFStore'","typeGuard":"def is_positive_predicate(op: str) -> bool:\n    return op in ('>', '<', '>=', '<=', '==', '!=', 'in', 'not in')","tryCatchPattern":"try:\n    store.select('df', where='~(A > 5)')\nexcept NotImplementedError as e:\n    if 'invert condition' in str(e):\n        store.select('df', where='A <= 5')\n    else:\n        raise","preventionTips":["Rewrite negations as positive predicates using De Morgan's laws.","Avoid '~' wrappers in where clauses routed through numexpr.","Precompute the negated comparison in plain Python."],"tags":["pandas","hdfstore","pytables","numexpr","inversion","where"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}