@@ -193,13 +193,20 @@ def summarize_available_handles(self, limit: int = 5) -> dict[str, Any]:
193193 "n_available_handles" : len (handle_ids ),
194194 }
195195
196- def _resolve_source (self , source : str ) -> dict [str , Any ]:
197- """Resolve a source id to a series, trying data_handle then demo dataset."""
196+ def _resolve_source (self , source : str , prefer : str = "y" ) -> dict [str , Any ]:
197+ """Resolve a source id to a series, trying data_handle then demo dataset.
198+
199+ ``prefer`` selects which component of a demo dataset to return
200+ ("y" or "X"); the other is the fallback when the preferred one is
201+ absent. Data handles always resolve to their primary series.
202+ """
198203 if source in self ._data_handles :
199204 return {"success" : True , "data" : self ._data_handles [source ]["y" ]}
200205 res = self .load_dataset (source )
201206 if res ["success" ]:
202- return {"success" : True , "data" : res ["data" ]}
207+ first , second = ("X" , "y" ) if prefer == "X" else ("y" , "X" )
208+ data = res [first ] if res [first ] is not None else res [second ]
209+ return {"success" : True , "data" : data }
203210 return res
204211
205212 def instantiate (
@@ -277,7 +284,12 @@ def mock_all_estimators(*args, **kwargs):
277284
278285 # L-7: We can also add custom load_dataset functions here
279286 def load_dataset (self , name : str ) -> dict [str , Any ]:
280- """Load a demo dataset."""
287+ """Load a demo dataset.
288+
289+ Returns canonical keys with one consistent meaning for every
290+ dataset family: ``y`` is always the target/labels, ``X`` is always
291+ the features/panel (or None).
292+ """
281293 demo_datasets = _get_demo_datasets ()
282294 if name not in demo_datasets :
283295 return {
@@ -294,9 +306,8 @@ def load_dataset(self, name: str) -> dict[str, Any]:
294306 data = loader ()
295307
296308 if isinstance (data , tuple ):
297- # sktime classifier/clusterer datasets typically return (X, y)
298- # whereas forecaster datasets typically return (y) or (y, X)
299- # Let's check the shape/type to be safe, or just hardcode known ones
309+ # sktime classifier/clusterer datasets return (X-panel, y-labels)
310+ # whereas forecaster datasets return (y-target, X-exog)
300311 if name in (
301312 "arrow_head" ,
302313 "italy_power_demand" ,
@@ -306,26 +317,21 @@ def load_dataset(self, name: str) -> dict[str, Any]:
306317 "plaid" ,
307318 ):
308319 X , y = data [0 ], data [1 ] if len (data ) > 1 else None
309- # swap them back for our internal representation where 'data' is the primary object requested
310- return {
311- "success" : True ,
312- "name" : name ,
313- "data" : X ,
314- "exog" : y ,
315- "type" : str (type (X ).__name__ ),
316- }
320+ primary = X
317321 else :
318322 y , X = data [0 ], data [1 ] if len (data ) > 1 else None
323+ primary = y
319324 else :
320325 y , X = data , None
326+ primary = y
321327
322328 return {
323329 "success" : True ,
324330 "name" : name ,
325- "shape" : y .shape if hasattr (y , "shape" ) else len (y ),
326- "type" : str (type (y ).__name__ ),
327- "data " : y ,
328- "exog " : X ,
331+ "shape" : primary .shape if hasattr (primary , "shape" ) else len (primary ),
332+ "type" : str (type (primary ).__name__ ),
333+ "y " : y ,
334+ "X " : X ,
329335 }
330336 except Exception as e :
331337 return {"success" : False , "error" : str (e )}
@@ -560,19 +566,19 @@ async def predict_async(
560566 data_res = self .load_dataset (X_dataset )
561567 if not data_res ["success" ]:
562568 raise ValueError (data_res .get ("error" , "Failed to load dataset" ))
563- X = data_res ["data " ]
564- y = data_res . get ( "exog" )
569+ y = data_res ["y " ]
570+ X = data_res [ "X" ]
565571 else :
566572 if X_dataset :
567573 data_res = self .load_dataset (X_dataset )
568574 if not data_res ["success" ]:
569575 raise ValueError (data_res .get ("error" , "Failed to load dataset" ))
570- X = data_res ["data " ]
576+ X = data_res ["X" ] if data_res [ "X" ] is not None else data_res [ "y " ]
571577 if y_dataset :
572578 data_res = self .load_dataset (y_dataset )
573579 if not data_res ["success" ]:
574580 raise ValueError (data_res .get ("error" , "Failed to load dataset" ))
575- y = data_res ["data " ]
581+ y = data_res ["y " ]
576582
577583 fh = list (range (1 , horizon + 1 ))
578584
@@ -656,9 +662,14 @@ def call_method(
656662 if "available" in data_res :
657663 error_res ["available" ] = data_res ["available" ]
658664 return error_res
659- # Replace the kwarg with the actual data (e.g. y_dataset -> y)
665+ # Replace the kwarg with the actual data (e.g. y_dataset -> y);
666+ # the prefix selects the dataset component
660667 actual_key = k .replace ("_dataset" , "" )
661- kwargs [actual_key ] = data_res ["data" ]
668+ if actual_key == "X" :
669+ value = data_res ["X" ] if data_res ["X" ] is not None else data_res ["y" ]
670+ else :
671+ value = data_res ["y" ]
672+ kwargs [actual_key ] = value
662673 del kwargs [k ]
663674 elif k .endswith ("_data_handle" ) and isinstance (v , str ):
664675 if v in self ._data_handles :
@@ -802,23 +813,20 @@ async def fit_async(
802813 data_res = self .load_dataset (X_dataset )
803814 if not data_res ["success" ]:
804815 raise ValueError (data_res ["error" ])
805- if data_res .get ("exog" ) is not None :
806- X = data_res ["data" ]
807- y = data_res ["exog" ]
808- else :
809- y = data_res ["data" ]
816+ y = data_res ["y" ]
817+ X = data_res ["X" ]
810818 else :
811819 if X_dataset :
812820 data_res = self .load_dataset (X_dataset )
813821 if not data_res ["success" ]:
814822 raise ValueError (data_res ["error" ])
815- X = data_res ["data " ]
823+ X = data_res ["X" ] if data_res [ "X" ] is not None else data_res [ "y " ]
816824
817825 if y_dataset :
818826 data_res = self .load_dataset (y_dataset )
819827 if not data_res ["success" ]:
820828 raise ValueError (data_res ["error" ])
821- y = data_res ["data " ]
829+ y = data_res ["y " ]
822830
823831 # Step 2: Fit model
824832 self ._job_manager .update_job (
@@ -901,7 +909,7 @@ async def evaluate_async(
901909
902910 _X = None
903911 if X :
904- x_res = self ._resolve_source (X )
912+ x_res = self ._resolve_source (X , prefer = "X" )
905913 if not x_res ["success" ]:
906914 raise ValueError (x_res ["error" ])
907915 _X = x_res ["data" ]
0 commit comments