Skip to content

Commit 4b02038

Browse files
author
Luke Shaw
committed
Improving constructor handling
1 parent 0d8e583 commit 4b02038

1 file changed

Lines changed: 50 additions & 3 deletions

File tree

src/blosc2/lazyexpr.py

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,51 @@ def visit_Call(self, node):
630630
return set(visitor.operands)
631631

632632

633+
def conserve_functions(
634+
expression: str,
635+
operands_old: dict[str : blosc2.ndarray | blosc2.LazyExpr],
636+
operands_new: dict[str : blosc2.ndarray | blosc2.LazyExpr],
637+
) -> tuple(str, dict[str : blosc2.ndarray.NDArray | blosc2.LazyExpr]):
638+
operand_to_key = {id(v): k for k, v in operands_new.items()}
639+
640+
class OperandVisitor(ast.NodeVisitor):
641+
def __init__(self):
642+
self.operandset = set()
643+
self.operands = {}
644+
self.opcounter = 0
645+
self.function_names = set()
646+
647+
def visit_Name(self, node):
648+
if node.id == "np":
649+
# Skip NumPy namespace (e.g. np.int8, which will be treated separately)
650+
return
651+
if node.id in self.function_names:
652+
# Skip function names
653+
return
654+
elif (node.id not in dtype_symbols) and (node.id not in self.operandset):
655+
k = operand_to_key[id(operands_old[node.id])]
656+
newkey = f"o{self.opcounter}"
657+
self.operands[newkey] = operands_new[k]
658+
node.id = newkey
659+
self.operandset.add(node.id)
660+
self.opcounter += 1
661+
else:
662+
pass
663+
self.generic_visit(node)
664+
665+
def visit_Call(self, node):
666+
if isinstance(
667+
node.func, ast.Name
668+
): # visits Call first, then Name, so don't increment operandcounter yet
669+
self.function_names.add(node.func.id)
670+
self.generic_visit(node)
671+
672+
tree = ast.parse(expression)
673+
visitor = OperandVisitor()
674+
visitor.visit(tree)
675+
return ast.unparse(tree), visitor.operands
676+
677+
633678
class TransformNumpyCalls(ast.NodeTransformer):
634679
def __init__(self):
635680
self.replacements = {}
@@ -2679,9 +2724,11 @@ def _new_expr(cls, expression, operands, guess, out=None, where=None, ne_args=No
26792724
_shape = new_expr.shape
26802725
if isinstance(new_expr, blosc2.LazyExpr):
26812726
# DO NOT restore the original expression and operands
2682-
# new_expr.expression = new_expr.expression} #don't have to do anything
2683-
new_expr.expression_tosave = _expression
2684-
# new_expr.operands = new_expr.operands #don't have to do anything
2727+
# Instead rebase operands and restore only constructors
2728+
expression_, operands_ = conserve_functions(expression, operands, new_expr.operands)
2729+
new_expr.expression = f"({expression_})" # force parenthesis
2730+
new_expr.expression_tosave = expression
2731+
new_expr.operands = operands_
26852732
new_expr.operands_tosave = operands
26862733
else:
26872734
# An immediate evaluation happened (e.g. all operands are numpy arrays)

0 commit comments

Comments
 (0)