prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  MAINT: Add `sparse_output` for `OneHotEncoder` to compat with sklearn1.2
  <!--
  Thanks for contributing a pull request!
  
  Please follow these standard acronyms to start the commit message:
  
  - ENH: enhancement
  - BUG: bug fix
  - DOC: documentation
  - TYP: type annotations
  - TST: addition or modification of tests
  - MAINT: maintenance commit (refactoring, typos, etc.)
  - BLD: change related to building
  - REL: related to releasing
  - API: an (incompatible) API change
  - DEP: deprecate something, or remove a deprecated object
  - DEV: development tool or utility
  - REV: revert an earlier commit
  - PERF: performance improvement
  - BOT: always commit via a bot
  - CI: related to CI or CD
  - CLN: Code cleanup
  -->
  
  - [x] closes https://github.com/Zeroto521/my-data-toolkit/actions/runs/3156312323/jobs/5135884971#step:5:960
  - [x] whatsnew entry
  
  In the latest (>= 1.1.2) sklearn version, `sparse` is replaced by `sparse_out`.
  And `sparse` will be removed in 1.4
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `dtoolkit/transformer/sklearn/OneHotEncoder.py`
  Content:
  ```
  1 from __future__ import annotations
  2 
  3 from textwrap import dedent
  4 from typing import Literal
  5 from typing import TYPE_CHECKING
  6 
  7 import numpy as np
  8 import pandas as pd
  9 from pandas.util._decorators import doc
  10 from sklearn.preprocessing import OneHotEncoder as SKOneHotEncoder
  11 
  12 from dtoolkit._typing import TwoDimArray
  13 from dtoolkit.accessor.dataframe import cols  # noqa: F401
  14 from dtoolkit.accessor.series import cols  # noqa: F401, F811
  15 from dtoolkit.transformer._compat import SKLEARN_GE_12
  16 
  17 
  18 if TYPE_CHECKING:
  19     from scipy.sparse import csr_matrix
  20 
  21 
  22 class OneHotEncoder(SKOneHotEncoder):
  23     """
  24     Encode categorical features as a one-hot numeric array.
  25 
  26     Parameters
  27     ----------
  28     categories_with_parent : bool, default False
  29         Returned column would hook parent labels if ``True`` else
  30         would be ``categories``.
  31 
  32     sparse : bool, default False
  33         Will return sparse matrix if ``True`` else will return an array.
  34 
  35     Other parameters
  36         See :obj:`sklearn.preprocessing.OneHotEncoder`.
  37 
  38     Notes
  39     -----
  40     Different to :obj:`sklearn.preprocessing.OneHotEncoder`.
  41     The result would return a :obj:`~pandas.DataFrame` which uses categories
  42     as columns.
  43 
  44     Examples
  45     --------
  46     Given a dataset with two features, we let the encoder find the unique
  47     values per feature and transform the data to a binary one-hot encoding.
  48 
  49     :obj:`~pandas.DataFrame` in, :obj:`~pandas.DataFrame` out with categories
  50     as columns.
  51 
  52     >>> from dtoolkit.transformer import OneHotEncoder
  53     >>> import pandas as pd
  54     >>> X = [['Male', 1], ['Female', 3], ['Female', 2]]
  55     >>> df = pd.DataFrame(X, columns=['gender', 'number'])
  56     >>> df
  57         gender  number
  58     0    Male       1
  59     1  Female       3
  60     2  Female       2
  61     >>> enc = OneHotEncoder()
  62     >>> enc.fit_transform(df)
  63        Female  Male    1    2    3
  64     0     0.0   1.0  1.0  0.0  0.0
  65     1     1.0   0.0  0.0  0.0  1.0
  66     2     1.0   0.0  0.0  1.0  0.0
  67 
  68     The encoded data also could hook parent labels.
  69 
  70     >>> enc = OneHotEncoder(categories_with_parent=True)
  71     >>> enc.fit_transform(df)
  72        gender_Female  gender_Male  number_1  number_2  number_3
  73     0            0.0          1.0       1.0       0.0       0.0
  74     1            1.0          0.0       0.0       0.0       1.0
  75     2            1.0          0.0       0.0       1.0       0.0
  76     """
  77 
  78     @doc(SKOneHotEncoder.__init__)
  79     def __init__(
  80         self,
  81         *,
  82         sparse: bool = False,
  83         sparse_output: bool = False,
  84         categories_with_parent: bool = False,
  85         categories="auto",
  86         drop=None,
  87         dtype=np.float64,
  88         handle_unknown: Literal["error", "ignore", "infrequent_if_exist"] = "error",
  89         min_frequency: int | float = None,
  90         max_categories: int = None,
  91     ):
  92         # TODO: Remove `sparse` in sklearn 1.4.
  93         # In the latest (>= 1.1.2) sklearn version, `sparse` is deprecated.
  94         super().__init__(
  95             categories=categories,
  96             drop=drop,
  97             dtype=dtype,
  98             handle_unknown=handle_unknown,
  99             min_frequency=min_frequency,
  100             max_categories=max_categories,
  101             **(
  102                 dict(sparse_output=sparse_output)
  103                 if SKLEARN_GE_12
  104                 else dict(sparse=sparse)
  105             ),
  106         )
  107         self.categories_with_parent = categories_with_parent
  108 
  109         # compat with sklearn lower version
  110         # `_parameter_constraints` comes out at sklearn 1.2
  111         # TODO: delete this condition when required sklearn version is >= 1.2
  112         if hasattr(self, "_parameter_constraints"):
  113             self._parameter_constraints["categories_with_parent"] = ["boolean"]
  114 
  115     @doc(
  116         SKOneHotEncoder.transform,
  117         dedent(
  118             """
  119         Notes
  120         -----
  121         This would let :obj:`~pandas.DataFrame` out.
  122         """,
  123         ),
  124     )
  125     def transform(self, X: TwoDimArray) -> TwoDimArray | csr_matrix:
  126         from itertools import chain
  127 
  128         Xt = super().transform(X)
  129 
  130         if self.sparse is False and isinstance(X, (pd.Series, pd.DataFrame)):
  131             # NOTE: `get_feature_names_out` requires sklearn >= 1.0
  132             categories = (
  133                 self.get_feature_names_out(X.cols(to_list=True))
  134                 if self.categories_with_parent
  135                 else chain.from_iterable(self.categories_)
  136             )
  137             return pd.DataFrame(Xt, columns=categories, index=X.index)
  138 
  139         return Xt
  140
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/dtoolkit/transformer/sklearn/OneHotEncoder.py b/dtoolkit/transformer/sklearn/OneHotEncoder.py
  --- a/dtoolkit/transformer/sklearn/OneHotEncoder.py
  +++ b/dtoolkit/transformer/sklearn/OneHotEncoder.py
  @@ -106,6 +106,9 @@
           )
           self.categories_with_parent = categories_with_parent
   
  +        # TODO: Remove the following line in sklearn 1.2.
  +        self.sparse_output = sparse_output
  +
           # compat with sklearn lower version
           # `_parameter_constraints` comes out at sklearn 1.2
           # TODO: delete this condition when required sklearn version is >= 1.2
  
verification_info: {"golden_diff": "diff --git a/dtoolkit/transformer/sklearn/OneHotEncoder.py b/dtoolkit/transformer/sklearn/OneHotEncoder.py\n--- a/dtoolkit/transformer/sklearn/OneHotEncoder.py\n+++ b/dtoolkit/transformer/sklearn/OneHotEncoder.py\n@@ -106,6 +106,9 @@\n         )\n         self.categories_with_parent = categories_with_parent\n \n+        # TODO: Remove the following line in sklearn 1.2.\n+        self.sparse_output = sparse_output\n+\n         # compat with sklearn lower version\n         # `_parameter_constraints` comes out at sklearn 1.2\n         # TODO: delete this condition when required sklearn version is >= 1.2\n", "issue": "MAINT: Add `sparse_output` for `OneHotEncoder` to compat with sklearn1.2\n<!--\r\nThanks for contributing a pull request!\r\n\r\nPlease follow these standard acronyms to start the commit message:\r\n\r\n- ENH: enhancement\r\n- BUG: bug fix\r\n- DOC: documentation\r\n- TYP: type annotations\r\n- TST: addition or modification of tests\r\n- MAINT: maintenance commit (refactoring, typos, etc.)\r\n- BLD: change related to building\r\n- REL: related to releasing\r\n- API: an (incompatible) API change\r\n- DEP: deprecate something, or remove a deprecated object\r\n- DEV: development tool or utility\r\n- REV: revert an earlier commit\r\n- PERF: performance improvement\r\n- BOT: always commit via a bot\r\n- CI: related to CI or CD\r\n- CLN: Code cleanup\r\n-->\r\n\r\n- [x] closes https://github.com/Zeroto521/my-data-toolkit/actions/runs/3156312323/jobs/5135884971#step:5:960\r\n- [x] whatsnew entry\r\n\r\nIn the latest (>= 1.1.2) sklearn version, `sparse` is replaced by `sparse_out`.\r\nAnd `sparse` will be removed in 1.4\n", "before_files": [{"content": "from __future__ import annotations\n\nfrom textwrap import dedent\nfrom typing import Literal\nfrom typing import TYPE_CHECKING\n\nimport numpy as np\nimport pandas as pd\nfrom pandas.util._decorators import doc\nfrom sklearn.preprocessing import OneHotEncoder as SKOneHotEncoder\n\nfrom dtoolkit._typing import TwoDimArray\nfrom dtoolkit.accessor.dataframe import cols  # noqa: F401\nfrom dtoolkit.accessor.series import cols  # noqa: F401, F811\nfrom dtoolkit.transformer._compat import SKLEARN_GE_12\n\n\nif TYPE_CHECKING:\n    from scipy.sparse import csr_matrix\n\n\nclass OneHotEncoder(SKOneHotEncoder):\n    \"\"\"\n    Encode categorical features as a one-hot numeric array.\n\n    Parameters\n    ----------\n    categories_with_parent : bool, default False\n        Returned column would hook parent labels if ``True`` else\n        would be ``categories``.\n\n    sparse : bool, default False\n        Will return sparse matrix if ``True`` else will return an array.\n\n    Other parameters\n        See :obj:`sklearn.preprocessing.OneHotEncoder`.\n\n    Notes\n    -----\n    Different to :obj:`sklearn.preprocessing.OneHotEncoder`.\n    The result would return a :obj:`~pandas.DataFrame` which uses categories\n    as columns.\n\n    Examples\n    --------\n    Given a dataset with two features, we let the encoder find the unique\n    values per feature and transform the data to a binary one-hot encoding.\n\n    :obj:`~pandas.DataFrame` in, :obj:`~pandas.DataFrame` out with categories\n    as columns.\n\n    >>> from dtoolkit.transformer import OneHotEncoder\n    >>> import pandas as pd\n    >>> X = [['Male', 1], ['Female', 3], ['Female', 2]]\n    >>> df = pd.DataFrame(X, columns=['gender', 'number'])\n    >>> df\n        gender  number\n    0    Male       1\n    1  Female       3\n    2  Female       2\n    >>> enc = OneHotEncoder()\n    >>> enc.fit_transform(df)\n       Female  Male    1    2    3\n    0     0.0   1.0  1.0  0.0  0.0\n    1     1.0   0.0  0.0  0.0  1.0\n    2     1.0   0.0  0.0  1.0  0.0\n\n    The encoded data also could hook parent labels.\n\n    >>> enc = OneHotEncoder(categories_with_parent=True)\n    >>> enc.fit_transform(df)\n       gender_Female  gender_Male  number_1  number_2  number_3\n    0            0.0          1.0       1.0       0.0       0.0\n    1            1.0          0.0       0.0       0.0       1.0\n    2            1.0          0.0       0.0       1.0       0.0\n    \"\"\"\n\n    @doc(SKOneHotEncoder.__init__)\n    def __init__(\n        self,\n        *,\n        sparse: bool = False,\n        sparse_output: bool = False,\n        categories_with_parent: bool = False,\n        categories=\"auto\",\n        drop=None,\n        dtype=np.float64,\n        handle_unknown: Literal[\"error\", \"ignore\", \"infrequent_if_exist\"] = \"error\",\n        min_frequency: int | float = None,\n        max_categories: int = None,\n    ):\n        # TODO: Remove `sparse` in sklearn 1.4.\n        # In the latest (>= 1.1.2) sklearn version, `sparse` is deprecated.\n        super().__init__(\n            categories=categories,\n            drop=drop,\n            dtype=dtype,\n            handle_unknown=handle_unknown,\n            min_frequency=min_frequency,\n            max_categories=max_categories,\n            **(\n                dict(sparse_output=sparse_output)\n                if SKLEARN_GE_12\n                else dict(sparse=sparse)\n            ),\n        )\n        self.categories_with_parent = categories_with_parent\n\n        # compat with sklearn lower version\n        # `_parameter_constraints` comes out at sklearn 1.2\n        # TODO: delete this condition when required sklearn version is >= 1.2\n        if hasattr(self, \"_parameter_constraints\"):\n            self._parameter_constraints[\"categories_with_parent\"] = [\"boolean\"]\n\n    @doc(\n        SKOneHotEncoder.transform,\n        dedent(\n            \"\"\"\n        Notes\n        -----\n        This would let :obj:`~pandas.DataFrame` out.\n        \"\"\",\n        ),\n    )\n    def transform(self, X: TwoDimArray) -> TwoDimArray | csr_matrix:\n        from itertools import chain\n\n        Xt = super().transform(X)\n\n        if self.sparse is False and isinstance(X, (pd.Series, pd.DataFrame)):\n            # NOTE: `get_feature_names_out` requires sklearn >= 1.0\n            categories = (\n                self.get_feature_names_out(X.cols(to_list=True))\n                if self.categories_with_parent\n                else chain.from_iterable(self.categories_)\n            )\n            return pd.DataFrame(Xt, columns=categories, index=X.index)\n\n        return Xt\n", "path": "dtoolkit/transformer/sklearn/OneHotEncoder.py"}], "after_files": [{"content": "from __future__ import annotations\n\nfrom textwrap import dedent\nfrom typing import Literal\nfrom typing import TYPE_CHECKING\n\nimport numpy as np\nimport pandas as pd\nfrom pandas.util._decorators import doc\nfrom sklearn.preprocessing import OneHotEncoder as SKOneHotEncoder\n\nfrom dtoolkit._typing import TwoDimArray\nfrom dtoolkit.accessor.dataframe import cols  # noqa: F401\nfrom dtoolkit.accessor.series import cols  # noqa: F401, F811\nfrom dtoolkit.transformer._compat import SKLEARN_GE_12\n\n\nif TYPE_CHECKING:\n    from scipy.sparse import csr_matrix\n\n\nclass OneHotEncoder(SKOneHotEncoder):\n    \"\"\"\n    Encode categorical features as a one-hot numeric array.\n\n    Parameters\n    ----------\n    categories_with_parent : bool, default False\n        Returned column would hook parent labels if ``True`` else\n        would be ``categories``.\n\n    sparse : bool, default False\n        Will return sparse matrix if ``True`` else will return an array.\n\n    Other parameters\n        See :obj:`sklearn.preprocessing.OneHotEncoder`.\n\n    Notes\n    -----\n    Different to :obj:`sklearn.preprocessing.OneHotEncoder`.\n    The result would return a :obj:`~pandas.DataFrame` which uses categories\n    as columns.\n\n    Examples\n    --------\n    Given a dataset with two features, we let the encoder find the unique\n    values per feature and transform the data to a binary one-hot encoding.\n\n    :obj:`~pandas.DataFrame` in, :obj:`~pandas.DataFrame` out with categories\n    as columns.\n\n    >>> from dtoolkit.transformer import OneHotEncoder\n    >>> import pandas as pd\n    >>> X = [['Male', 1], ['Female', 3], ['Female', 2]]\n    >>> df = pd.DataFrame(X, columns=['gender', 'number'])\n    >>> df\n        gender  number\n    0    Male       1\n    1  Female       3\n    2  Female       2\n    >>> enc = OneHotEncoder()\n    >>> enc.fit_transform(df)\n       Female  Male    1    2    3\n    0     0.0   1.0  1.0  0.0  0.0\n    1     1.0   0.0  0.0  0.0  1.0\n    2     1.0   0.0  0.0  1.0  0.0\n\n    The encoded data also could hook parent labels.\n\n    >>> enc = OneHotEncoder(categories_with_parent=True)\n    >>> enc.fit_transform(df)\n       gender_Female  gender_Male  number_1  number_2  number_3\n    0            0.0          1.0       1.0       0.0       0.0\n    1            1.0          0.0       0.0       0.0       1.0\n    2            1.0          0.0       0.0       1.0       0.0\n    \"\"\"\n\n    @doc(SKOneHotEncoder.__init__)\n    def __init__(\n        self,\n        *,\n        sparse: bool = False,\n        sparse_output: bool = False,\n        categories_with_parent: bool = False,\n        categories=\"auto\",\n        drop=None,\n        dtype=np.float64,\n        handle_unknown: Literal[\"error\", \"ignore\", \"infrequent_if_exist\"] = \"error\",\n        min_frequency: int | float = None,\n        max_categories: int = None,\n    ):\n        # TODO: Remove `sparse` in sklearn 1.4.\n        # In the latest (>= 1.1.2) sklearn version, `sparse` is deprecated.\n        super().__init__(\n            categories=categories,\n            drop=drop,\n            dtype=dtype,\n            handle_unknown=handle_unknown,\n            min_frequency=min_frequency,\n            max_categories=max_categories,\n            **(\n                dict(sparse_output=sparse_output)\n                if SKLEARN_GE_12\n                else dict(sparse=sparse)\n            ),\n        )\n        self.categories_with_parent = categories_with_parent\n\n        # TODO: Remove the following line in sklearn 1.2.\n        self.sparse_output = sparse_output\n\n        # compat with sklearn lower version\n        # `_parameter_constraints` comes out at sklearn 1.2\n        # TODO: delete this condition when required sklearn version is >= 1.2\n        if hasattr(self, \"_parameter_constraints\"):\n            self._parameter_constraints[\"categories_with_parent\"] = [\"boolean\"]\n\n    @doc(\n        SKOneHotEncoder.transform,\n        dedent(\n            \"\"\"\n        Notes\n        -----\n        This would let :obj:`~pandas.DataFrame` out.\n        \"\"\",\n        ),\n    )\n    def transform(self, X: TwoDimArray) -> TwoDimArray | csr_matrix:\n        from itertools import chain\n\n        Xt = super().transform(X)\n\n        if self.sparse is False and isinstance(X, (pd.Series, pd.DataFrame)):\n            # NOTE: `get_feature_names_out` requires sklearn >= 1.0\n            categories = (\n                self.get_feature_names_out(X.cols(to_list=True))\n                if self.categories_with_parent\n                else chain.from_iterable(self.categories_)\n            )\n            return pd.DataFrame(Xt, columns=categories, index=X.index)\n\n        return Xt\n", "path": "dtoolkit/transformer/sklearn/OneHotEncoder.py"}]}