@@ -317,11 +317,8 @@ def visit_UnaryOp(self, node: ast.UnaryOp) -> "Expr":
317317 operand = self .visit (node .operand )
318318 return UnaryExpr (Operation .NOT , operand )
319319 elif isinstance (node .op , ast .USub ):
320- # For negative numbers, treat as literal
321- if isinstance (node .operand , ast .Constant ):
322- return lit (- node .operand .value )
323- else :
324- raise ValueError ("Unary minus only supported for constant values" )
320+ operand = self .visit (node .operand )
321+ return operand * lit (- 1 )
325322 else :
326323 raise ValueError (f"Unsupported unary operator: { type (node .op ).__name__ } " )
327324
@@ -372,7 +369,9 @@ def visit_Attribute(self, node: ast.Attribute) -> "Expr":
372369 if isinstance (left_expr , ColumnExpr ):
373370 return col (f"{ left_expr ._name } .{ node .attr } " )
374371
375- raise ValueError (f"Unsupported attribute access: { node .attr } " )
372+ raise ValueError (
373+ f"Unsupported attribute access: { node .attr } . Node details: { ast .dump (node )} "
374+ )
376375
377376 def visit_Call (self , node : ast .Call ) -> "Expr" :
378377 """Handle function calls for operations like is_null, is_not_null, is_nan."""
@@ -385,7 +384,8 @@ def visit_Call(self, node: ast.Call) -> "Expr":
385384 raise ValueError ("is_null() expects exactly one argument" )
386385 operand = self .visit (node .args [0 ])
387386 return UnaryExpr (Operation .IS_NULL , operand )
388- # Adding this conditional to keep it consistent with the existing implementation.
387+ # Adding this conditional to keep it consistent with the current implementation,
388+ # of carrying Pyarrow's semantic of `is_valid`
389389 elif func_name == "is_valid" or func_name == "is_not_null" :
390390 if len (node .args ) != 1 :
391391 raise ValueError (f"{ func_name } () expects exactly one argument" )
0 commit comments