4242
4343import blosc2
4444
45+ from .b2objects import _encode_b2object_payload , _make_b2object_carrier , _write_b2object_payload
4546from .dsl_kernel import DSLKernel , DSLSyntaxError , _DSLValidator , specialize_miniexpr_inputs
4647
4748if blosc2 ._HAS_NUMBA :
@@ -570,7 +571,7 @@ def convert_inputs(inputs):
570571 return []
571572 inputs_ = []
572573 for obj in inputs :
573- if not isinstance (obj , ( np .ndarray , blosc2 .Operand ) ) and not np .isscalar (obj ):
574+ if not isinstance (obj , np .ndarray | blosc2 .Operand ) and not np .isscalar (obj ):
574575 try :
575576 obj = blosc2 .SimpleProxy (obj )
576577 except Exception :
@@ -2855,7 +2856,7 @@ def result_type(
28552856 # Follow NumPy rules for scalar-array operations
28562857 # Create small arrays with the same dtypes and let NumPy's type promotion determine the result type
28572858 arrs = [
2858- (np .array (value ).dtype if isinstance (value , ( str , bytes ) ) else value )
2859+ (np .array (value ).dtype if isinstance (value , str | bytes ) else value )
28592860 if (np .isscalar (value ) or not hasattr (value , "dtype" ))
28602861 else np .array ([0 ], dtype = _convert_dtype (value .dtype ))
28612862 for value in arrays_and_dtypes
@@ -2902,7 +2903,7 @@ def __init__(self, new_op): # noqa: C901
29022903 # Check that operands are proper Operands, LazyArray or scalars; if not, convert to NDArray objects
29032904 value1 = (
29042905 blosc2 .SimpleProxy (value1 )
2905- if not (isinstance (value1 , ( blosc2 .Operand , np .ndarray ) ) or np .isscalar (value1 ))
2906+ if not (isinstance (value1 , blosc2 .Operand | np .ndarray ) or np .isscalar (value1 ))
29062907 else value1
29072908 )
29082909 # Reset values represented as np.int64 etc. to be set as Python natives
@@ -2926,7 +2927,7 @@ def __init__(self, new_op): # noqa: C901
29262927 return
29272928 value2 = (
29282929 blosc2 .SimpleProxy (value2 )
2929- if not (isinstance (value2 , ( blosc2 .Operand , np .ndarray ) ) or np .isscalar (value2 ))
2930+ if not (isinstance (value2 , blosc2 .Operand | np .ndarray ) or np .isscalar (value2 ))
29302931 else value2
29312932 )
29322933 # Reset values represented as np.int64 etc. to be set as Python natives
@@ -3711,44 +3712,27 @@ def save(self, urlpath=None, **kwargs):
37113712 if urlpath is None :
37123713 raise ValueError ("To save a LazyArray you must provide an urlpath" )
37133714
3714- expression = self .expression_tosave if hasattr (self , "expression_tosave" ) else self .expression
3715- operands_ = self .operands_tosave if hasattr (self , "operands_tosave" ) else self .operands
3716- # Validate expression
3717- validate_expr (expression )
3718-
3719- meta = kwargs .get ("meta" , {})
3720- meta ["LazyArray" ] = LazyArrayEnum .Expr .value
37213715 kwargs ["urlpath" ] = urlpath
3722- kwargs ["meta" ] = meta
37233716 kwargs ["mode" ] = "w" # always overwrite the file in urlpath
3717+ self ._to_b2object_carrier (** kwargs )
37243718
3725- # Create an empty array; useful for providing the shape and dtype of the outcome
3726- array = blosc2 .empty (shape = self .shape , dtype = self .dtype , ** kwargs )
3727-
3728- # Save the expression and operands in the metadata
3729- operands = {}
3730- for key , value in operands_ .items ():
3731- if isinstance (value , blosc2 .C2Array ):
3732- operands [key ] = {
3733- "path" : str (value .path ),
3734- "urlbase" : value .urlbase ,
3735- }
3736- continue
3737- if isinstance (value , blosc2 .Proxy ):
3738- # Take the required info from the Proxy._cache container
3739- value = value ._cache
3740- if not hasattr (value , "schunk" ):
3741- raise ValueError (
3742- "To save a LazyArray, all operands must be blosc2.NDArray or blosc2.C2Array objects"
3743- )
3744- if value .schunk .urlpath is None :
3745- raise ValueError ("To save a LazyArray, all operands must be stored on disk/network" )
3746- operands [key ] = value .schunk .urlpath
3747- array .schunk .vlmeta ["_LazyArray" ] = {
3748- "expression" : expression ,
3749- "UDF" : None ,
3750- "operands" : operands ,
3751- }
3719+ def to_cframe (self ) -> bytes :
3720+ return self ._to_b2object_carrier ().to_cframe ()
3721+
3722+ def _to_b2object_carrier (self , ** kwargs ):
3723+ payload = _encode_b2object_payload (self )
3724+ if payload is None :
3725+ raise TypeError ("Unsupported persisted Blosc2 object" )
3726+ array = _make_b2object_carrier (
3727+ "lazyexpr" ,
3728+ self .shape ,
3729+ self .dtype ,
3730+ chunks = self .chunks ,
3731+ blocks = self .blocks ,
3732+ ** kwargs ,
3733+ )
3734+ _write_b2object_payload (array , payload )
3735+ return array
37523736
37533737 @classmethod
37543738 def _new_expr (cls , expression , operands , guess , out = None , where = None , ne_args = None ):
@@ -3764,7 +3748,7 @@ def _new_expr(cls, expression, operands, guess, out=None, where=None, ne_args=No
37643748 _operands = operands | local_vars
37653749 # Check that operands are proper Operands, LazyArray or scalars; if not, convert to NDArray objects
37663750 for op , val in _operands .items ():
3767- if not (isinstance (val , ( blosc2 .Operand , np .ndarray ) ) or np .isscalar (val )):
3751+ if not (isinstance (val , blosc2 .Operand | np .ndarray ) or np .isscalar (val )):
37683752 _operands [op ] = blosc2 .SimpleProxy (val )
37693753 # for scalars just return value (internally converts to () if necessary)
37703754 opshapes = {k : v if not hasattr (v , "shape" ) else v .shape for k , v in _operands .items ()}
0 commit comments