11from __future__ import annotations
22
3- from typing import TYPE_CHECKING , Any , Iterable , Literal
3+ from typing import TYPE_CHECKING , Any , Callable , Iterable , Literal , Protocol
44
55import ibis
66from ibis .expr import datatypes as dt
77from ibis .expr import types as ir
88
9- from mismo import _util , joins
9+ from mismo import _typing , _util , joins
1010from mismo .types ._table_wrapper import TableWrapper
1111
1212if TYPE_CHECKING :
@@ -17,7 +17,9 @@ class Filters:
1717 """A simple namespace for filter functions."""
1818
1919 @staticmethod
20- def all_different (subset : Iterable [str ] | None = None ):
20+ def all_different (
21+ subset : Iterable [str ] | None = None , /
22+ ) -> Callable [[ir .Table ], Literal [True ] | ir .BooleanValue ]:
2123 """
2224 Make a Updates filter function that gives rows where all columns are different.
2325
@@ -44,7 +46,7 @@ def all_different(subset: Iterable[str] | None = None):
4446 ... ) # doctest: +SKIP
4547 """ # noqa: E501
4648
47- def filter_func (table : ir .Table ) :
49+ def filter_func (table : ir .Table , / ) -> ir . BooleanValue | Literal [ True ] :
4850 nonlocal subset
4951 if subset is None :
5052 u = Updates (table , check_schemas = "lax" )
@@ -56,7 +58,9 @@ def filter_func(table: ir.Table):
5658 return filter_func
5759
5860 @staticmethod
59- def any_different (subset : Iterable [str ] | None = None ):
61+ def any_different (
62+ subset : Iterable [str ] | None = None , /
63+ ) -> Callable [[ir .Table ], ir .BooleanValue | Literal [True ]]:
6064 """Make a Updates filter function that gives rows where any column is different.
6165
6266 Parameters
@@ -77,7 +81,7 @@ def any_different(subset: Iterable[str] | None = None):
7781 >>> u.filter(u.filters.any_different(["name", "age"])) # doctest: +SKIP
7882 """
7983
80- def filter_func (table : ir .Table ) :
84+ def filter_func (table : ir .Table , / ) -> ir . BooleanValue | Literal [ True ] :
8185 nonlocal subset
8286 if subset is None :
8387 u = Updates (table , check_schemas = "lax" )
@@ -280,17 +284,17 @@ def after(self) -> ibis.Table:
280284 """The table after the changes."""
281285 return self .select (** self .after_values ())
282286
283- def is_changed (self , column : str , / ) -> ibis .ir .BooleanColumn :
287+ def is_changed (self , column : str , / ) -> ibis .ir .BooleanValue :
284288 """Is column.before different from column.after? Never returns NULL."""
285- resolved_col = _util .bind_one (self ._t , column )
289+ resolved_col : HasBeforeAfter = _util .bind_one (self ._t , column )
286290 return is_changed (resolved_col )
287291
288- def filter (self , * args , ** kwargs ):
292+ def filter (self , * args , ** kwargs ) -> _typing . Self :
289293 return self .__class__ (
290294 self ._t .filter (* args , ** kwargs ), check_schemas = self .check_schemas
291295 )
292296
293- def cache (self ):
297+ def cache (self ) -> _typing . Self :
294298 return self .__class__ (self ._t .cache (), check_schemas = self .check_schemas )
295299
296300 def apply_to (
@@ -341,16 +345,21 @@ def apply_to(
341345 f"default value { already_there } already exist in the input table"
342346 )
343347
344- t = t .mutate (defaults )
348+ t = t .mutate (defaults ) # ty:ignore[invalid-argument-type]
345349
346350 t = t .select (self .after ().columns )
347351 t = t .union (self .after (), distinct = False )
348352 return t
349353
350354
351- def is_changed (val : ibis .Value , / ) -> ibis .ir .BooleanColumn :
355+ class HasBeforeAfter (Protocol ):
356+ before : ibis .Value
357+ after : ibis .Value
358+
359+
360+ def is_changed (val : HasBeforeAfter , / ) -> ibis .ir .BooleanValue :
352361 """Is val.before different from val.after? Never returns NULL."""
353362 return ibis .or_ (
354- (val .before != val .after ).fill_null (False ),
363+ (val .before != val .after ).fill_null (False ), # ty:ignore[invalid-argument-type]
355364 val .before .isnull () != val .after .isnull (),
356365 )
0 commit comments