You are viewing a plain text version of this content. The canonical link for it is here.
Posted to reviews@spark.apache.org by "Spenserrrr (via GitHub)" <gi...@apache.org> on 2026/08/04 22:08:16 UTC

[PR] [SPARK-58576][PYTHON][TESTS] Add tests for pa.Array.to_pandas with integer_object_nulls [spark]

Spenserrrr opened a new pull request, #57774:
URL: https://github.com/apache/spark/pull/57774

   ### What changes were proposed in this pull request?
   
   Add `PyArrowArrayToPandasIntegerObjectNullsTests` to the existing `test_pyarrow_arrow_to_pandas_non_default.py`, pinning the behavior of `pa.Array.to_pandas(integer_object_nulls=True)` in a golden file. Sub-task of SPARK-54936.
   
   numpy integer dtypes cannot represent a null, so PyArrow must choose a representation when an integer array contains one. By default it widens to `float64` with `NaN`; with `integer_object_nulls=True` the result stays `object` dtype holding Python `int` and `None`.
   
   The row set reuses all 121 rows of the sibling `test_pyarrow_arrow_to_pandas_default.py` via `_build_source_arrays`, so both golden files pin the same types, plus 18 appended integer rows that the shared rows do not reach:
   
   - **Width extremes with a null** (8 rows) — the shared nullable rows use small values that `float64` represents exactly. At 64 bits the range exceeds float64's 53-bit mantissa and the value itself changes.
   - **`int64:all-null`, `int64:multi-chunk-nullable`** — no integer left to convert, and values split across buffers with the null in only one chunk. The latter is reachable in production: cogrouped `applyInPandas` is the one UDF path that does not call `combine_chunks()` first.
   - **Nested types with a null integer element** (7 rows) — `list`, `large_list`, `fixed_size_list`, `list<list>`, `struct`, `map`. The shared nested rows hold a missing *sub-list*, which this argument does not affect; a missing *element inside* one is what it changes. These are also the types `convert_legacy` still serves.
   - **`dictionary<int64>:nullable`** — control. Dictionary encoding stores the distinct values once plus an index per row, so the null lives in the indices and the int64 values hold none; with no null to represent, the argument has nothing to decide.
   
   Three output columns per row: the argument off, on, and the full `pandas_options` dict `convert_legacy` passes. The last is not a duplicate of the second — `coerce_temporal_nanoseconds` shifts the temporal rows to `ns` — and pinning the call as Spark makes it also catches PyArrow changing the `date_as_object=True` default it relies on.
   
   No `dev/sparktestsupport/modules.py` line is needed; the test file is already registered.
   
   ### Why are the changes needed?
   
   `integer_object_nulls=True` is passed unconditionally at `python/pyspark/sql/conversion.py:1839`, and again to `_create_converter_to_pandas` at `:1850` so the fix-up stage knows what it received. The object Series is an intermediate, not the result: it is narrowed to a nullable extension dtype (`Int8Dtype` .. `Int64Dtype`) via `_to_corrected_pandas_ext_type`, and it is the only bridge from Arrow to those dtypes that avoids `float64`.
   
   It was added by SPARK-54962 to fix a correctness bug where an identity pandas UDF returned a different number for a large nullable long, and its behavior has never been pinned by a test. Unlike `types_mapper` on the sibling `convert_numpy` path, which is gated by `spark.sql.execution.pythonUDF.pandas.preferIntExtensionDtype` (default false), this argument has no config to fall back on.
   
   Scope is worth being precise about: this argument serves the pandas UDF path over the complex types `convert_numpy` does not handle yet (`TODO(SPARK-55324)` at `conversion.py:1999-2007`). `df.toPandas()` builds its own options at `python/pyspark/sql/pandas/conversion.py:249-251` and does not pass it. That the covered type region is scheduled to move is itself an argument for recording the current semantics now.
   
   ### Does this PR introduce _any_ user-facing change?
   
   No. Tests only.
   
   ### How was this patch tested?
   
   New golden-file test, 139 rows x 4 columns. The argument changes 25 rows; the remaining 114 pin that it does not affect them.
   
   Validated across **16/16** environments — PyArrow 18/19/20/21/22/23/24/25 x pandas 2 and 3 — running the committed test file against the committed golden in a fresh venv per combination. Golden regeneration is byte-identical.
   
   Two `overrides` tiers were needed and both were verified load-bearing by disabling each and observing the failure: pandas 3 renders non-empty Arrow string arrays with its dedicated string dtype, while empty ones only gain it from PyArrow 24.
   
   ### Was this patch authored or co-authored using generative AI tooling?
   
   Generated-by: Claude Code (Opus 5)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


Re: [PR] [SPARK-58576][PYTHON][TESTS] Add tests for pa.Array.to_pandas with integer_object_nulls [spark]

Posted by "Spenserrrr (via GitHub)" <gi...@apache.org>.
Spenserrrr commented on code in PR #57774:
URL: https://github.com/apache/spark/pull/57774#discussion_r3716889184


##########
python/pyspark/tests/upstream/pyarrow/test_pyarrow_arrow_to_pandas_non_default.py:
##########
@@ -493,6 +493,178 @@ def compute_cell(row_name, col_name):
         )
 
 
+@unittest.skipIf(
+    not have_pyarrow or not have_pandas or not have_numpy,
+    pyarrow_requirement_message or pandas_requirement_message or numpy_requirement_message,
+)
+class PyArrowArrayToPandasIntegerObjectNullsTests(_PyArrowToPandasTestBase):
+    """
+    Tests pa.Array.to_pandas(integer_object_nulls=True) via golden file comparison.
+
+    numpy integers have no null, so by default PyArrow widens a null-bearing integer
+    array to ``float64`` with ``NaN`` -- which cannot hold every int64 exactly, so a
+    large value silently changes.  ``integer_object_nulls=True`` keeps ``object``
+    dtype (Python ``int`` and ``None``) instead, preserving the values.
+
+    PySpark passes it in ``ArrowArrayToPandasConversion.convert_legacy``
+    (``python/pyspark/sql/conversion.py``), bundled with ``date_as_object`` and
+    ``coerce_temporal_nanoseconds``, then narrows the object Series to a nullable
+    extension dtype (``Int8Dtype`` .. ``Int64Dtype``) -- the only bridge from Arrow to
+    those dtypes that avoids ``float64``.
+
+    Three output columns are recorded per source array: the argument off, on, and the
+    full ``pandas_options`` dict ``convert_legacy`` passes.  The last is not a
+    duplicate of the second -- ``coerce_temporal_nanoseconds`` shifts the temporal
+    rows to ``ns`` -- and pinning the call as Spark makes it also catches PyArrow
+    changing the ``date_as_object=True`` default it relies on.
+
+    The row set mirrors ``test_pyarrow_arrow_to_pandas_default.py``'s rows so both
+    golden files pin the same types, and appends the integer variants those rows do
+    not reach (see ``_build_source_arrays``).
+    """
+
+    def _build_source_arrays(self):
+        """
+        Reuse every row of the sibling default test, then add the integer variants
+        that only matter for this argument: the shared rows' nullable values are
+        small enough to survive ``float64``, and their nested rows are missing whole
+        sub-lists rather than a single integer inside one.
+        """
+        default_tests = test_pyarrow_arrow_to_pandas_default.PyArrowArrayToPandasDefaultTests
+        sources = default_tests._build_source_arrays(self)
+
+        # Each width's min and max alongside a null.  The shared rows use small values,
+        # which float64 represents exactly; only at 64 bits does the range exceed its
+        # 53-bit mantissa and the value itself change.
+        for pa_type in [
+            pa.int8(),
+            pa.int16(),
+            pa.int32(),
+            pa.int64(),
+            pa.uint8(),
+            pa.uint16(),
+            pa.uint32(),
+            pa.uint64(),
+        ]:
+            if pa.types.is_signed_integer(pa_type):
+                bounds = [2 ** (pa_type.bit_width - 1) - 1, -(2 ** (pa_type.bit_width - 1))]
+            else:
+                bounds = [2**pa_type.bit_width - 1, 0]
+            sources[f"{pa_type}:extremes-nullable"] = pa.array(bounds + [None], pa_type)
+
+        # Every value is null, so there is no integer left to convert.
+        sources["int64:all-null"] = pa.array([None, None], pa.int64())
+        # Values split across buffers, with the null in one chunk and not the other.
+        # Reachable in production: cogrouped applyInPandas is the one UDF path that does
+        # not call combine_chunks() first.
+        sources["int64:multi-chunk-nullable"] = pa.chunked_array(
+            [pa.array([1, None], pa.int64()), pa.array([2], pa.int64())]
+        )
+
+        # Nested types whose null is an integer ELEMENT, not a missing sub-list: the
+        # shared rows only cover the latter, which this argument does not affect.
+        # These are also the types convert_legacy still serves.
+        sources["list<int64>:null-element"] = pa.array([[1, None], [2, 3]], pa.list_(pa.int64()))
+        sources["list<int64>:null-element-extreme"] = pa.array(
+            [[2**63 - 1, None]], pa.list_(pa.int64())
+        )
+        sources["large_list<int64>:null-element"] = pa.array([[1, None]], pa.large_list(pa.int64()))
+        sources["fixed_size_list<int64>[3]:null-element"] = pa.array(
+            [[1, None, 3]], pa.list_(pa.int64(), 3)
+        )
+        sources["list<list<int64>>:null-element"] = pa.array(
+            [[[1, None], [2]]], pa.list_(pa.list_(pa.int64()))
+        )
+        sources["struct:null-int-field"] = pa.array(
+            [{"x": 1, "y": "a"}, {"x": None, "y": "b"}],
+            pa.struct([("x", pa.int64()), ("y", pa.string())]),
+        )
+        sources["map<string,int64>:null-value"] = pa.array(
+            [[("a", 1), ("b", None)]], pa.map_(pa.string(), pa.int64())
+        )
+        # Control: dictionary encoding stores the distinct values once plus an index per
+        # row, so the null lives in the indices and the int64 values hold none.  With no
+        # null to represent there, the argument has nothing to decide -- both columns
+        # stay category, whose own values also remain int64.
+        sources["dictionary<int64>:nullable"] = pa.array(
+            [1, None, 1], pa.int64()
+        ).dictionary_encode()
+
+        return sources
+
+    # Output column for the default: a null-bearing integer array widens to float64.
+    COL_INTEGER_OBJECT_NULLS_OFF = "integer_object_nulls=False"
+    # Output column for the argument on: the result stays object dtype.
+    COL_INTEGER_OBJECT_NULLS_ON = "integer_object_nulls=True"
+    # Output column for all three arguments as convert_legacy passes them together.
+    COL_SPARK_PANDAS_OPTIONS = "spark pandas_options"
+
+    # Kept as one dict so the column cannot drift from the call site it mirrors.
+    SPARK_PANDAS_OPTIONS = {
+        "date_as_object": True,
+        "coerce_temporal_nanoseconds": True,
+        "integer_object_nulls": True,
+    }
+
+    def test_to_pandas_integer_object_nulls(self):
+        """Test pa.Array.to_pandas(integer_object_nulls=True/False) against golden file."""
+        sources = self._build_source_arrays()
+        row_names = list(sources.keys())
+        col_names = [
+            "pyarrow array",
+            self.COL_INTEGER_OBJECT_NULLS_OFF,
+            self.COL_INTEGER_OBJECT_NULLS_ON,
+            self.COL_SPARK_PANDAS_OPTIONS,
+        ]
+
+        # Version-specific expected values go here, keyed by (row, col), when a
+        # newer pandas/PyArrow/NumPy legitimately changes a cell's output.
+        overrides: dict[tuple[str, str], str] = {}
+        # Pandas 3 renders Arrow string arrays with its dedicated string dtype.  This
+        # argument does not touch strings, so every output column shifts together.
+        if LooseVersion(pd.__version__) >= LooseVersion("3.0.0"):
+
+            def override_all_outputs(row, expected):
+                for col in col_names[1:]:
+                    overrides[(row, col)] = expected
+
+            for row, expected in [
+                ("string:standard", "['hello', 'world', '']@Series[str]"),
+                ("string:nullable", "['hello', nan, 'world']@Series[str]"),
+                ("large_string:standard", "['hello', 'world']@Series[str]"),
+                ("large_string:nullable", "['hello', nan]@Series[str]"),
+            ]:
+                override_all_outputs(row, expected)
+
+            # Empty string arrays only gain that dtype from PyArrow 24; before that
+            # they stay object even on pandas 3, so the baseline still holds there.
+            if LooseVersion(pa.__version__) >= LooseVersion("24.0.0"):
+                for row in ["string:empty", "large_string:empty"]:
+                    override_all_outputs(row, "[]@Series[str]")

Review Comment:
   Thanks for the review, @Yicong-Huang! I've just revised according to the suggestion.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


Re: [PR] [SPARK-58576][PYTHON][TESTS] Add tests for pa.Array.to_pandas with integer_object_nulls [spark]

Posted by "uros-b (via GitHub)" <gi...@apache.org>.
uros-b closed pull request #57774: [SPARK-58576][PYTHON][TESTS] Add tests for pa.Array.to_pandas with integer_object_nulls
URL: https://github.com/apache/spark/pull/57774


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


Re: [PR] [SPARK-58576][PYTHON][TESTS] Add tests for pa.Array.to_pandas with integer_object_nulls [spark]

Posted by "Yicong-Huang (via GitHub)" <gi...@apache.org>.
Yicong-Huang commented on code in PR #57774:
URL: https://github.com/apache/spark/pull/57774#discussion_r3716745889


##########
python/pyspark/tests/upstream/pyarrow/test_pyarrow_arrow_to_pandas_non_default.py:
##########
@@ -493,6 +493,178 @@ def compute_cell(row_name, col_name):
         )
 
 
+@unittest.skipIf(
+    not have_pyarrow or not have_pandas or not have_numpy,
+    pyarrow_requirement_message or pandas_requirement_message or numpy_requirement_message,
+)
+class PyArrowArrayToPandasIntegerObjectNullsTests(_PyArrowToPandasTestBase):
+    """
+    Tests pa.Array.to_pandas(integer_object_nulls=True) via golden file comparison.
+
+    numpy integers have no null, so by default PyArrow widens a null-bearing integer
+    array to ``float64`` with ``NaN`` -- which cannot hold every int64 exactly, so a
+    large value silently changes.  ``integer_object_nulls=True`` keeps ``object``
+    dtype (Python ``int`` and ``None``) instead, preserving the values.
+
+    PySpark passes it in ``ArrowArrayToPandasConversion.convert_legacy``
+    (``python/pyspark/sql/conversion.py``), bundled with ``date_as_object`` and
+    ``coerce_temporal_nanoseconds``, then narrows the object Series to a nullable
+    extension dtype (``Int8Dtype`` .. ``Int64Dtype``) -- the only bridge from Arrow to
+    those dtypes that avoids ``float64``.
+
+    Three output columns are recorded per source array: the argument off, on, and the
+    full ``pandas_options`` dict ``convert_legacy`` passes.  The last is not a
+    duplicate of the second -- ``coerce_temporal_nanoseconds`` shifts the temporal
+    rows to ``ns`` -- and pinning the call as Spark makes it also catches PyArrow
+    changing the ``date_as_object=True`` default it relies on.
+
+    The row set mirrors ``test_pyarrow_arrow_to_pandas_default.py``'s rows so both
+    golden files pin the same types, and appends the integer variants those rows do
+    not reach (see ``_build_source_arrays``).
+    """
+
+    def _build_source_arrays(self):
+        """
+        Reuse every row of the sibling default test, then add the integer variants
+        that only matter for this argument: the shared rows' nullable values are
+        small enough to survive ``float64``, and their nested rows are missing whole
+        sub-lists rather than a single integer inside one.
+        """
+        default_tests = test_pyarrow_arrow_to_pandas_default.PyArrowArrayToPandasDefaultTests
+        sources = default_tests._build_source_arrays(self)
+
+        # Each width's min and max alongside a null.  The shared rows use small values,
+        # which float64 represents exactly; only at 64 bits does the range exceed its
+        # 53-bit mantissa and the value itself change.
+        for pa_type in [
+            pa.int8(),
+            pa.int16(),
+            pa.int32(),
+            pa.int64(),
+            pa.uint8(),
+            pa.uint16(),
+            pa.uint32(),
+            pa.uint64(),
+        ]:
+            if pa.types.is_signed_integer(pa_type):
+                bounds = [2 ** (pa_type.bit_width - 1) - 1, -(2 ** (pa_type.bit_width - 1))]
+            else:
+                bounds = [2**pa_type.bit_width - 1, 0]
+            sources[f"{pa_type}:extremes-nullable"] = pa.array(bounds + [None], pa_type)
+
+        # Every value is null, so there is no integer left to convert.
+        sources["int64:all-null"] = pa.array([None, None], pa.int64())
+        # Values split across buffers, with the null in one chunk and not the other.
+        # Reachable in production: cogrouped applyInPandas is the one UDF path that does
+        # not call combine_chunks() first.
+        sources["int64:multi-chunk-nullable"] = pa.chunked_array(
+            [pa.array([1, None], pa.int64()), pa.array([2], pa.int64())]
+        )
+
+        # Nested types whose null is an integer ELEMENT, not a missing sub-list: the
+        # shared rows only cover the latter, which this argument does not affect.
+        # These are also the types convert_legacy still serves.
+        sources["list<int64>:null-element"] = pa.array([[1, None], [2, 3]], pa.list_(pa.int64()))
+        sources["list<int64>:null-element-extreme"] = pa.array(
+            [[2**63 - 1, None]], pa.list_(pa.int64())
+        )
+        sources["large_list<int64>:null-element"] = pa.array([[1, None]], pa.large_list(pa.int64()))
+        sources["fixed_size_list<int64>[3]:null-element"] = pa.array(
+            [[1, None, 3]], pa.list_(pa.int64(), 3)
+        )
+        sources["list<list<int64>>:null-element"] = pa.array(
+            [[[1, None], [2]]], pa.list_(pa.list_(pa.int64()))
+        )
+        sources["struct:null-int-field"] = pa.array(
+            [{"x": 1, "y": "a"}, {"x": None, "y": "b"}],
+            pa.struct([("x", pa.int64()), ("y", pa.string())]),
+        )
+        sources["map<string,int64>:null-value"] = pa.array(
+            [[("a", 1), ("b", None)]], pa.map_(pa.string(), pa.int64())
+        )
+        # Control: dictionary encoding stores the distinct values once plus an index per
+        # row, so the null lives in the indices and the int64 values hold none.  With no
+        # null to represent there, the argument has nothing to decide -- both columns
+        # stay category, whose own values also remain int64.
+        sources["dictionary<int64>:nullable"] = pa.array(
+            [1, None, 1], pa.int64()
+        ).dictionary_encode()
+
+        return sources
+
+    # Output column for the default: a null-bearing integer array widens to float64.
+    COL_INTEGER_OBJECT_NULLS_OFF = "integer_object_nulls=False"
+    # Output column for the argument on: the result stays object dtype.
+    COL_INTEGER_OBJECT_NULLS_ON = "integer_object_nulls=True"
+    # Output column for all three arguments as convert_legacy passes them together.
+    COL_SPARK_PANDAS_OPTIONS = "spark pandas_options"
+
+    # Kept as one dict so the column cannot drift from the call site it mirrors.
+    SPARK_PANDAS_OPTIONS = {
+        "date_as_object": True,
+        "coerce_temporal_nanoseconds": True,
+        "integer_object_nulls": True,
+    }
+
+    def test_to_pandas_integer_object_nulls(self):
+        """Test pa.Array.to_pandas(integer_object_nulls=True/False) against golden file."""
+        sources = self._build_source_arrays()
+        row_names = list(sources.keys())
+        col_names = [
+            "pyarrow array",
+            self.COL_INTEGER_OBJECT_NULLS_OFF,
+            self.COL_INTEGER_OBJECT_NULLS_ON,
+            self.COL_SPARK_PANDAS_OPTIONS,
+        ]
+
+        # Version-specific expected values go here, keyed by (row, col), when a
+        # newer pandas/PyArrow/NumPy legitimately changes a cell's output.
+        overrides: dict[tuple[str, str], str] = {}
+        # Pandas 3 renders Arrow string arrays with its dedicated string dtype.  This
+        # argument does not touch strings, so every output column shifts together.
+        if LooseVersion(pd.__version__) >= LooseVersion("3.0.0"):
+
+            def override_all_outputs(row, expected):
+                for col in col_names[1:]:
+                    overrides[(row, col)] = expected
+
+            for row, expected in [
+                ("string:standard", "['hello', 'world', '']@Series[str]"),
+                ("string:nullable", "['hello', nan, 'world']@Series[str]"),
+                ("large_string:standard", "['hello', 'world']@Series[str]"),
+                ("large_string:nullable", "['hello', nan]@Series[str]"),
+            ]:
+                override_all_outputs(row, expected)
+
+            # Empty string arrays only gain that dtype from PyArrow 24; before that
+            # they stay object even on pandas 3, so the baseline still holds there.
+            if LooseVersion(pa.__version__) >= LooseVersion("24.0.0"):
+                for row in ["string:empty", "large_string:empty"]:
+                    override_all_outputs(row, "[]@Series[str]")

Review Comment:
   nit: I think it might be better to write this format for readability? I want to avoid nested if and loops. 
   
   if pandas > 3 and  18 <= arrow < 24:
       overrides[(r1, c1)] = "xxx"
       overrides[(r2, c2)] = "yyy"
   if pandas > 3 and arrow > 24:
       overrides[(r2, c2)] = "zzz"
   ...



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


Re: [PR] [SPARK-58576][PYTHON][TESTS] Add tests for pa.Array.to_pandas with integer_object_nulls [spark]

Posted by "Spenserrrr (via GitHub)" <gi...@apache.org>.
Spenserrrr commented on PR #57774:
URL: https://github.com/apache/spark/pull/57774#issuecomment-5185215283

   Hi @Yicong-Huang @zhengruifeng! Could you take a look when you have a moment? Thank you!


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


Re: [PR] [SPARK-58576][PYTHON][TESTS] Add tests for pa.Array.to_pandas with integer_object_nulls [spark]

Posted by "uros-b (via GitHub)" <gi...@apache.org>.
uros-b commented on PR #57774:
URL: https://github.com/apache/spark/pull/57774#issuecomment-5189623026

   **Merge Summary:**
   - merged into master https://github.com/apache/spark/commit/a8dcc97d1382fd9405b5b363e33d0065b8f7db31
   - merged into branch-4.x https://github.com/apache/spark/commit/083a70d57c59184de1b37ef4fea58ba5d44b1ad8
   
   *Posted by `merge_spark_pr.py`*


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


Re: [PR] [SPARK-58576][PYTHON][TESTS] Add tests for pa.Array.to_pandas with integer_object_nulls [spark]

Posted by "uros-b (via GitHub)" <gi...@apache.org>.
uros-b commented on PR #57774:
URL: https://github.com/apache/spark/pull/57774#issuecomment-5189616848

   Thank you @Spenserrrr and @Yicong-Huang @zhengruifeng!


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org