code: def series(
      *,
      name: str | SearchStrategy[str] | None = None,
      dtype: PolarsDataType | None = None,
      size: int | None = None,
      min_size: int | None = 0,
      max_size: int | None = MAX_DATA_SIZE,
      strategy: SearchStrategy[object] | None = None,
      null_probability: float = 0.0,
      allow_infinities: bool = True,
      unique: bool = False,
      chunked: bool | None = None,
      allowed_dtypes: Collection[PolarsDataType]
      | PolarsDataType
      | None = None,
      excluded_dtypes: Collection[PolarsDataType]
      | PolarsDataType
      | None = None,
  ) -> SearchStrategy[Series]:
      """
      Hypothesis strategy for producing polars Series.
  
      Parameters
      ----------
      name : {str, strategy}, optional
          literal string or a strategy for strings (or None), passed to the Series
          constructor name-param.
      dtype : PolarsDataType, optional
          a valid polars DataType for the resulting series.
      size : int, optional
          if set, creates a Series of exactly this size (ignoring min_size/max_size
          params).
      min_size : int, optional
          if not passing an exact size, can set a minimum here (defaults to 0).
          no-op if `size` is set.
      max_size : int, optional
          if not passing an exact size, can set a maximum value here (defaults to
          MAX_DATA_SIZE). no-op if `size` is set.
      strategy : strategy, optional
          supports overriding the default strategy for the given dtype.
      null_probability : float, optional
          percentage chance (expressed between 0.0 => 1.0) that a generated value is
          None. this is applied independently of any None values generated by the
          underlying strategy.
      allow_infinities : bool, optional
          optionally disallow generation of +/-inf values for floating-point dtypes.
      unique : bool, optional
          indicate whether Series values should all be distinct.
      chunked : bool, optional
          ensure that Series with more than one element have `n_chunks` > 1.
          if omitted, chunking is applied at random.
      allowed_dtypes : {list,set}, optional
          when automatically generating Series data, allow only these dtypes.
      excluded_dtypes : {list,set}, optional
          when automatically generating Series data, exclude these dtypes.
  
      Notes
      -----
      In actual usage this is deployed as a unit test decorator, providing a strategy
      that generates multiple Series with the given dtype/size characteristics for the
      unit test. While developing a strategy/test, it can also be useful to call
      `.example()` directly on a given strategy to see concrete instances of the
      generated data.
  
      Examples
      --------
      >>> from polars.testing.parametric import series
      >>> from hypothesis import given
  
      In normal usage, as a simple unit test:
  
      >>> @given(s=series(null_probability=0.1))
      ... def test_repr_is_valid_string(s: pl.Series) -> None:
      ...     assert isinstance(repr(s), str)
  
      Experimenting locally with a custom List dtype strategy:
  
      >>> from polars.testing.parametric import create_list_strategy
      >>> s = series(
      ...     strategy=create_list_strategy(
      ...         inner_dtype=pl.String,
      ...         select_from=["xx", "yy", "zz"],
      ...     ),
      ...     min_size=2,
      ...     max_size=4,
      ... )
      >>> s.example()  # doctest: +SKIP
      shape: (4,)
      Series: '' [list[str]]
      [
          []
          ["yy", "yy", "zz"]
          ["zz", "yy", "zz"]
          ["xx"]
      ]
  
      """
      if isinstance(allowed_dtypes, (DataType, DataTypeClass)):
          allowed_dtypes = [allowed_dtypes]
      if isinstance(excluded_dtypes, (DataType, DataTypeClass)):
          excluded_dtypes = [excluded_dtypes]
  
      selectable_dtypes = [
          dtype
          for dtype in (allowed_dtypes or strategy_dtypes)
          if dtype not in (excluded_dtypes or ())
      ]
      if null_probability and not (0 <= null_probability <= 1):
          raise InvalidArgument(
              f"`null_probability` should be between 0.0 and 1.0, or None; found {null_probability}"
          )
      null_probability = float(null_probability or 0.0)
  
      @composite
      def draw_series(draw: DrawFn) -> Series:
          with StringCache():
              # create/assign series dtype and retrieve matching strategy
              series_dtype: PolarsDataType = (
                  draw(sampled_from(selectable_dtypes))  # type: ignore[assignment]
                  if dtype is None and strategy is None
                  else dtype
              )
              if strategy is None:
                  if (
                      series_dtype is Datetime
                      or series_dtype is Duration
                  ):
                      series_dtype = series_dtype(random.choice(_time_units))  # type: ignore[operator]
                  dtype_strategy = all_strategies[
                      series_dtype
                      if series_dtype in all_strategies
                      else series_dtype.base_type()
                  ]
              else:
                  dtype_strategy = strategy
  
              if series_dtype.is_float() and not allow_infinities:
                  dtype_strategy = dtype_strategy.filter(
                      lambda x: not isinstance(x, float) or isfinite(x)
                  )
  
              # create/assign series size
              series_size = (
                  between(
                      draw,
                      int,
                      min_=(min_size or 0),
                      max_=(max_size or MAX_DATA_SIZE),
                  )
                  if size is None
                  else size
              )
              # assign series name
              series_name = (
                  name
                  if isinstance(name, str) or name is None
                  else draw(name)
              )
  
              # create series using dtype-specific strategy to generate values
              if series_size == 0:
                  series_values = []
              elif null_probability == 1:
                  series_values = [None] * series_size
              else:
                  series_values = draw(
                      lists(
                          dtype_strategy,
                          min_size=series_size,
                          max_size=series_size,
                          unique_by=(_flexhash if unique else None),
                      )
                  )
  
              # apply null values (custom frequency)
              if null_probability and null_probability != 1:
                  for idx in range(series_size):
                      if random.random() < null_probability:
                          series_values[idx] = None
  
              # init series with strategy-generated data
              s = Series(
                  name=series_name,
                  dtype=series_dtype,
                  values=series_values,
              )
              if dtype == Categorical:
                  s = s.cast(Categorical)
              if series_size and (
                  chunked or (chunked is None and draw(booleans()))
              ):
                  split_at = series_size // 2
                  s = s[:split_at].append(s[split_at:])
              return s
  
      return draw_series()
  
imports: from __future__ import annotations
  import random
  import warnings
  from dataclasses import dataclass
  from math import isfinite
  from textwrap import dedent
  from typing import TYPE_CHECKING, Any, Collection, Sequence, overload
  from hypothesis.errors import InvalidArgument, NonInteractiveExampleWarning
  from hypothesis.strategies import booleans, composite, lists, sampled_from
  from hypothesis.strategies._internal.utils import defines_strategy
  from polars.dataframe import DataFrame
  from polars.datatypes import DTYPE_TEMPORAL_UNITS, Categorical, DataType, DataTypeClass, Datetime, Duration, List, is_polars_dtype, py_type_to_dtype
  from polars.series import Series
  from polars.string_cache import StringCache
  from polars.testing.parametric.strategies import _flexhash, all_strategies, between, create_list_strategy, scalar_strategies
label_desc: Use image node_id 3 for calling a global function with example usage: series() and returns: draw_series, s