44from functools import lru_cache
55from itertools import chain
66from types import MappingProxyType
7- from typing import TYPE_CHECKING , Any , Protocol , TypeVar , overload
7+ from typing import TYPE_CHECKING , Any , Protocol , TypeVar , final , overload
88
99from narwhals ._plan ._expr_ir import NamedIR
1010from narwhals ._plan ._immutable import Immutable
1111from narwhals ._utils import _hasattr_static
1212from narwhals .dtypes import Unknown
1313
1414if TYPE_CHECKING :
15- from collections .abc import ItemsView , Iterator , KeysView , ValuesView
15+ from collections .abc import ItemsView , Iterable , Iterator , KeysView , ValuesView
1616
1717 from typing_extensions import Never , TypeAlias , TypeIs
1818
2222
2323
2424IntoFrozenSchema : TypeAlias = (
25- "IntoSchema | Iterator [tuple[str, DType]] | FrozenSchema | HasSchema"
25+ "IntoSchema | Iterable [tuple[str, DType]] | FrozenSchema | HasSchema"
2626)
2727"""A schema to freeze, or an already frozen one.
2828
3535_T2 = TypeVar ("_T2" )
3636
3737
38+ @final
3839class FrozenSchema (Immutable ):
3940 """Use `freeze_schema(...)` constructor to trigger caching!"""
4041
4142 __slots__ = ("_mapping" ,)
4243 _mapping : MappingProxyType [str , DType ]
4344
44- def __init_subclass__ (cls , * _ : Never , ** __ : Never ) -> Never : # pragma: no cover
45- msg = f"Cannot subclass { cls .__name__ !r} "
45+ def __init_subclass__ (cls , * _ : Never , ** __ : Never ) -> Never :
46+ msg = f"Cannot subclass { FrozenSchema .__name__ !r} "
4647 raise TypeError (msg )
4748
4849 def merge (self , other : FrozenSchema , / ) -> FrozenSchema :
@@ -111,7 +112,7 @@ def items(self) -> ItemsView[str, DType]:
111112 def keys (self ) -> KeysView [str ]:
112113 return self ._mapping .keys ()
113114
114- def values (self ) -> ValuesView [DType ]: # pragma: no cover
115+ def values (self ) -> ValuesView [DType ]:
115116 return self ._mapping .values ()
116117
117118 @overload
@@ -121,15 +122,15 @@ def get(self, key: str, default: DType | _T2, /) -> DType | _T2: ...
121122 def get (self , key : str , default : DType | _T2 | None = None , / ) -> DType | _T2 | None :
122123 if default is not None :
123124 return self ._mapping .get (key , default )
124- return self ._mapping .get (key ) # pragma: no cover
125+ return self ._mapping .get (key )
125126
126127 def __iter__ (self ) -> Iterator [str ]:
127128 yield from self ._mapping
128129
129- def __contains__ (self , key : object ) -> bool : # pragma: no cover
130+ def __contains__ (self , key : object ) -> bool :
130131 return self ._mapping .__contains__ (key )
131132
132- def __getitem__ (self , key : str , / ) -> DType : # pragma: no cover
133+ def __getitem__ (self , key : str , / ) -> DType :
133134 return self ._mapping .__getitem__ (key )
134135
135136 def __len__ (self ) -> int :
0 commit comments