| 
18 | 18 | 
  | 
19 | 19 | Our goal is to **wrap** a *partially-unknown* native object **in** a [generic class]:  | 
20 | 20 | 
  | 
21 |  | -    DataFrame[IntoDataFrameT]  | 
22 |  | -    LazyFrame[IntoLazyFrameT]  | 
23 |  | -    Series[IntoSeriesT]  | 
 | 21 | +    def wrapping_in_df(native: IntoDataFrameT) -> DataFrame[IntoDataFrameT]: ...  | 
 | 22 | +    def wrapping_in_ldf(native: IntoLazyFrameT) -> LazyFrame[IntoLazyFrameT]: ...  | 
 | 23 | +    def wrapping_in_ser(native: IntoSeriesT) -> Series[IntoSeriesT]: ...  | 
24 | 24 | 
  | 
25 | 25 | ### (1) `Native<Thing>`  | 
26 | 26 | Minimal [`Protocol`]s that are [assignable to] *almost any* supported native type of that group:  | 
@@ -57,24 +57,30 @@ class Thing(Generic[IntoThingT]):  | 
57 | 57 |         def to_native(self) -> IntoThingT: ...  | 
58 | 58 | 
  | 
59 | 59 | ## Matching to an `Implementation`  | 
60 |  | -[//]: # (TODO @dangotbanned: Introduce this section?)  | 
 | 60 | +This problem differs as we need to *create* a relationship between *otherwise-unrelated* types.  | 
 | 61 | +
  | 
 | 62 | +Comparing the problems side-by-side, we can more clearly see this difference:  | 
 | 63 | +
  | 
 | 64 | +    def wrapping_in_df(native: IntoDataFrameT) -> DataFrame[IntoDataFrameT]: ...  | 
 | 65 | +    def matching_to_polars(native: pl.DataFrame) -> Literal[Implementation.POLARS]: ...  | 
61 | 66 | 
  | 
62 | 67 | ### (4) `Native<Backend>`  | 
63 |  | -If we want to describe a set of more specific types (e.g. in [`@overload`s]), then these protocols/aliases are the right tool.  | 
 | 68 | +If we want to describe a set of specific types and **match** them in [`@overload`s], then these the tools we need.  | 
64 | 69 | 
  | 
65 |  | -For common and easily-installed backends, aliases are composed of the native type(s):  | 
 | 70 | +For common and easily-installed backends, [`TypeAlias`]s are composed of the native type(s):  | 
66 | 71 | 
  | 
67 | 72 |     NativePolars: TypeAlias = pl.DataFrame | pl.LazyFrame | pl.Series  | 
68 | 73 | 
  | 
69 |  | -Otherwise, we need to define a [`Protocol`] which the native type(s) can match against *when* installed:  | 
 | 74 | +Otherwise, we need to define a [`Protocol`] which the native type(s) can **match** against *when* installed:  | 
70 | 75 | 
  | 
71 | 76 |     class NativeDask(NativeLazyFrame, Protocol):  | 
72 | 77 |         _partition_type: type[pd.DataFrame]  | 
73 | 78 | 
  | 
74 |  | -Important:  | 
75 |  | -    The goal is to be as minimal as possible, while still being *specific-enough* to **not** match something else.  | 
 | 79 | +Tip:  | 
 | 80 | +    The goal is to be as minimal as possible, while still being *specific-enough* to **not match** something else.  | 
76 | 81 | 
  | 
77 |  | -For a more complete example, see [ibis#9276 comment].  | 
 | 82 | +Important:  | 
 | 83 | +    See [ibis#9276 comment] for a more *in-depth* example that doesn't fit here 😄  | 
78 | 84 | 
  | 
79 | 85 | ### (5) `is_native_<backend>`  | 
80 | 86 | [Type guards] for **(4)**, *similar* to those found in `nw.dependencies`.  | 
 | 
0 commit comments