Skip to content

Commit 3424b68

Browse files
committed
Revert adding global field serializer - causes more issues than it fixes - instead validate 'IntSlice' specifically which was my root problem
1 parent 9a681e1 commit 3424b68

1 file changed

Lines changed: 15 additions & 43 deletions

File tree

caiman/source_extraction/cnmf/params.py

Lines changed: 15 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from pydantic import (
1414
ConfigDict, TypeAdapter, BeforeValidator, AfterValidator, InstanceOf,
1515
PlainValidator, PlainSerializer, ValidationError, ValidationInfo,
16-
WithJsonSchema, Field, field_validator, field_serializer, computed_field, model_validator)
16+
WithJsonSchema, Field, field_validator, computed_field, model_validator)
1717
from pydantic.dataclasses import dataclass
1818
from pydantic.fields import FieldInfo
1919
from pydantic.json_schema import SkipJsonSchema, PydanticJsonSchemaWarning
@@ -74,12 +74,19 @@ def eval_bytes(obj: Any) -> Any:
7474
return obj
7575

7676

77-
Slice = Annotated[
78-
Union[ # these are the same base types (slice) but with different validators
79-
InstanceOf[slice], # accept existing slices as is
80-
# anything convertible to a len-3 tuple, with 'NoneType' conversion, can be a slice
81-
Annotated[slice, ValidateAs(tuple[SafeAny, SafeAny, SafeAny], lambda tup: slice(*tup))]],
82-
BeforeValidator(eval_bytes),
77+
def preprocess_intslice(obj: Any) -> Any:
78+
obj = eval_bytes(obj)
79+
if isinstance(obj, slice):
80+
obj = (obj.start, obj.stop, obj.step)
81+
return obj
82+
83+
84+
IntSlice = Annotated[
85+
slice,
86+
# anything convertible to a len-3 tuple of int or None, with 'NoneType' conversion, can be interpreted as a slice
87+
ValidateAs(tuple[SafeOptional[int], SafeOptional[int], SafeOptional[int]], lambda tup: slice(*tup)),
88+
BeforeValidator(preprocess_intslice),
89+
# serialize as a tuple
8390
PlainSerializer(lambda sl: (sl.start, sl.stop, sl.step)),
8491
WithJsonSchema(TypeAdapter(tuple[Any, Any, Any]).json_schema())
8592
]
@@ -206,41 +213,6 @@ def validation_wrapper(cls, value: Any, handler, info: ValidationInfo) -> Any:
206213

207214
return value
208215

209-
210-
@classmethod
211-
def _ser_numpy_scalar_helper(cls, value: Any, seen: frozenset[int] = frozenset()) -> Any:
212-
"""Recursive helper for ser_numpy_number"""
213-
if id(value) in seen: # avoid cycles, keep track of objects in path from here to root
214-
return value
215-
else:
216-
seen = seen.union({id(value)})
217-
218-
if isinstance(value, tuple):
219-
return tuple(cls._ser_numpy_scalar_helper(v, seen) for v in value)
220-
221-
if isinstance(value, list):
222-
return [cls._ser_numpy_scalar_helper(v, seen) for v in value]
223-
224-
if isinstance(value, slice):
225-
return slice(*(cls._ser_numpy_scalar_helper(v, seen) for v in (value.start, value.stop, value.step)))
226-
227-
if isinstance(value, Mapping):
228-
return {
229-
cls._ser_numpy_scalar_helper(key, seen): cls._ser_numpy_scalar_helper(val, seen)
230-
for key, val in value.items()
231-
}
232-
233-
if isinstance(value, np.generic):
234-
return value.item()
235-
236-
return value
237-
238-
239-
@field_serializer('*', mode='wrap')
240-
def ser_numpy_scalar(self, value: Any, handler) -> Any:
241-
"""Convert numpy scalars, which pydantic doesn't know how to deal with"""
242-
return handler(self._ser_numpy_scalar_helper(value))
243-
244216

245217
def replace(self: GPSelf, warn_unused=True, **changes) -> GPSelf:
246218
"""Create a GroupParams object with the given fields replaced"""
@@ -717,7 +689,7 @@ class MotionParams(GroupParams):
717689
strides: tuple[int, ...] = (96, 96) # how often to start a new patch in pw-rigid registration
718690
upsample_factor_grid: int = 4 # motion field upsampling factor during FFT shifts
719691
use_cuda: bool = False # flag for using a GPU
720-
indices: tuple[Slice, ...] = (slice(None), slice(None)) # part of FOV to be corrected
692+
indices: tuple[IntSlice, ...] = (slice(None), slice(None)) # part of FOV to be corrected
721693

722694

723695
def _compute_splits_from_data(self) -> Optional[int]:

0 commit comments

Comments
 (0)