class_docstr: Base implementation of a Continual Learning benchmark instance.
  A Continual Learning benchmark instance is defined by a set of streams of
  experiences (batches or tasks depending on the terminology). Each
  experience contains the training (or test, or validation, ...) data that
  becomes available at a certain time instant.
  
  Experiences are usually defined in children classes, with this class
  serving as the more general implementation. This class handles the most
  simple type of assignment: each stream is defined as a list of experiences,
  each experience is defined by a dataset.
  
  Defining the "train" and "test" streams is mandatory. This class supports
  custom streams as well. Custom streams can be accessed by using the
  `streamname_stream` field of the created instance.
  
  The name of custom streams can only contain letters, numbers or the "_"
  character and must not start with a number.
code: def _check_and_adapt_user_stream_def(
      stream_def: Union[
          StreamDef[TCLDataset],
          StreamUserDef[TCLDataset],
          TStreamUserDef,
      ],
      stream_name: str,
  ) -> StreamDef[TCLDataset]:
      if isinstance(stream_def, StreamDef):
          return stream_def
  
      if isinstance(stream_def, StreamUserDef):
          stream_def = (
              stream_def.exps_data,
              stream_def.exps_task_labels,
              stream_def.origin_dataset,
              stream_def.is_lazy,
          )
  
      exp_data: TStreamDataOrigin = stream_def[0]
      task_labels: TStreamTaskLabels = None
      origin_dataset: TOriginDataset = None
      is_lazy: Optional[bool] = None
  
      if exp_data is None:
          raise ValueError("Experience data can't be None")
  
      if len(stream_def) > 1:
          task_labels = stream_def[1]  # type: ignore
  
      if len(stream_def) > 2:
          origin_dataset = stream_def[2]  # type: ignore
  
      if len(stream_def) > 3:
          is_lazy = stream_def[3]  # type: ignore
  
      if is_lazy or (isinstance(exp_data, tuple) and (is_lazy is None)):
          # Creation based on a generator
          if is_lazy:
              # We also check for LazyDatasetSequence, which is sufficient
              # per se (only if is_lazy==True, otherwise is treated as a
              # standard Sequence)
              if not isinstance(exp_data, LazyDatasetSequence):
                  if (not isinstance(exp_data, tuple)) or (
                      not len(exp_data) == 2
                  ):
                      raise ValueError(
                          f"The stream {stream_name} was flagged as "
                          f"lazy-generated but its definition is not a "
                          f"2-elements tuple (generator and stream length)."
                      )
          else:
              if (
                  (not isinstance(exp_data, Sequence))
                  or (not len(exp_data) == 2)
                  or (not isinstance(exp_data[1], int))
              ):
                  raise ValueError(
                      f"The stream {stream_name} was detected "
                      f"as lazy-generated but its definition is not a "
                      f"2-elements tuple. If you're trying to define a "
                      f"non-lazily generated stream, don't use a tuple "
                      f"when passing the list of datasets, use a list "
                      f"instead."
                  )
  
          if isinstance(exp_data, LazyDatasetSequence):
              stream_length = len(exp_data)
          else:
              # exp_data[0] must contain the generator
              stream_length = exp_data[1]
          is_lazy = True
      elif isinstance(exp_data, AvalancheDataset):
          # Single element
          exp_data = [exp_data]
          is_lazy = False
          stream_length = 1
      else:
          # Standard def
          stream_length = len(exp_data)  # type: ignore
          is_lazy = False
  
      if not is_lazy:
          for i, dataset in enumerate(exp_data):  # type: ignore
              if not isinstance(dataset, AvalancheDataset):
                  raise ValueError(
                      "All experience datasets must be subclasses of"
                      " AvalancheDataset"
                  )
  
      task_labels_list: List[Set[int]] = []
      if task_labels is None:
          if is_lazy:
              raise ValueError(
                  "Task labels must be defined for each experience when "
                  "creating the stream using a generator."
              )
  
          # Extract task labels from the dataset
          exp_dataset: AvalancheDataset
          for i, exp_dataset in enumerate(exp_data):  # type: ignore
              task_labels_list.append(
                  set(exp_dataset.targets_task_labels)
              )  # type: ignore
      else:
          # Standardize task labels structure
          for t_l in task_labels:
              if isinstance(t_l, int):
                  task_labels_list.append({t_l})
              elif not isinstance(t_l, set):
                  task_labels_list.append(set(t_l))
              else:
                  task_labels_list.append(t_l)
  
      if stream_length != len(task_labels_list):
          raise ValueError(
              f"{stream_length} experiences have been defined, but task "
              f"labels for {len(task_labels_list)} experiences are given."
          )
  
      lazy_sequence: LazyDatasetSequence[TCLDataset]
      if is_lazy:
          if isinstance(exp_data, LazyDatasetSequence):
              lazy_sequence = exp_data  # type: ignore
          else:
              lazy_sequence = LazyDatasetSequence(
                  exp_data[0], stream_length  # type: ignore
              )  # type: ignore
      else:
          lazy_sequence = LazyDatasetSequence(
              exp_data, stream_length  # type: ignore
          )  # type: ignore
          lazy_sequence.load_all_experiences()
  
      return StreamDef(
          lazy_sequence, task_labels_list, origin_dataset, is_lazy
      )
  
imports: from abc import ABC, abstractmethod
  from dataclasses import dataclass
  import re
  from typing import Generic, TypeVar, Union, Sequence, Callable, Optional, Dict, Any, Iterable, List, Set, Tuple, Mapping, TYPE_CHECKING
  from .None import DatasetExperience
  from ..generic_scenario import CLScenario, CLExperience, CLStream, SequenceCLStream
  from .lazy_dataset_sequence import LazyDatasetSequence
  from avalanche.benchmarks.utils import AvalancheDataset
  from torch.utils.data.dataset import Dataset
label_desc: Use image node_id 9 for calling the DatasetScenario obj's underlying member method code with example usage: obj._check_and_adapt_user_stream_def(stream_def, stream_name) and returns: StreamDef, stream_def