code: def convert_shards(
      shards: list[pa.Table], meta: pd.DataFrame
  ) -> pd.DataFrame:
      import pandas as pd
      from pandas.core.dtypes.cast import find_common_type  # type: ignore[attr-defined]
  
      from dask.dataframe.dispatch import from_pyarrow_table_dispatch
  
      table = concat_tables(shards)
      table = table.sort_by(_INPUT_PARTITION_ID_COLUMN)
      table = table.drop([_INPUT_PARTITION_ID_COLUMN])
  
      df = from_pyarrow_table_dispatch(meta, table, self_destruct=True)
      reconciled_dtypes = {}
      for column, dtype in meta.dtypes.items():
          actual = df[column].dtype
          if actual == dtype:
              continue
          # Use the specific string dtype from meta (e.g., string[pyarrow])
          if isinstance(actual, pd.StringDtype) and isinstance(
              dtype, pd.StringDtype
          ):
              reconciled_dtypes[column] = dtype
              continue
          # meta might not be aware of the actual categories so the two dtype objects are not equal
          # Also, the categories_dtype does not properly roundtrip through Arrow
          if isinstance(actual, pd.CategoricalDtype) and isinstance(
              dtype, pd.CategoricalDtype
          ):
              continue
          reconciled_dtypes[column] = find_common_type([actual, dtype])
      return df.astype(reconciled_dtypes, copy=False)
  
file_path: distributed/distributed/shuffle/_arrow.py
imports: from __future__ import annotations
  from collections.abc import Iterable
  from pathlib import Path
  from typing import TYPE_CHECKING
  from packaging.version import parse
  from dask.utils import parse_bytes
label_desc: Use image node_id 4 for calling a global function with example usage: convert_shards(shards, meta) and returns: df