Repository: pandas-dev/pandas
Pull request #56963 (2024-01-19 17:12:57)

Backport PR #56896 on branch 2.2.x (DEPS: Add warning if pyarrow is not installed)
Backport PR #56896: DEPS: Add warning if pyarrow is not installed


Patch:
diff --git a/pandas/__init__.py b/pandas/__init__.py
index 7fab662ed2..ed524c2bb3 100644
--- a/pandas/__init__.py
+++ b/pandas/__init__.py
@@ -202,8 +202,37 @@ if "PANDAS_DATA_MANAGER" in os.environ:
         FutureWarning,
         stacklevel=2,
     )
-# Don't allow users to use pandas.os or pandas.warnings
-del os, warnings
+
+# DeprecationWarning for missing pyarrow
+from pandas.compat.pyarrow import pa_version_under10p1, pa_not_found
+
+if pa_version_under10p1:
+    # pyarrow is either too old or nonexistent, warn
+    from pandas.compat._optional import VERSIONS
+
+    if pa_not_found:
+        pa_msg = "was not found to be installed on your system."
+    else:
+        pa_msg = (
+            f"was too old on your system - pyarrow {VERSIONS['pyarrow']} "
+            "is the current minimum supported version as of this release."
+        )
+
+    warnings.warn(
+        f"""
+Pyarrow will become a required dependency of pandas in the next major release of pandas (pandas 3.0),
+(to allow more performant data types, such as the Arrow string type, and better interoperability with other libraries)
+but {pa_msg}
+If this would cause problems for you,
+please provide us feedback at https://github.com/pandas-dev/pandas/issues/54466
+        """,  # noqa: E501
+        DeprecationWarning,
+        stacklevel=2,
+    )
+    del VERSIONS, pa_msg
+
+# Delete all unnecessary imported modules
+del pa_version_under10p1, pa_not_found, warnings, os
 
 # module level doc-string
 __doc__ = """
diff --git a/pandas/compat/pyarrow.py b/pandas/compat/pyarrow.py
index beb4814914..2e151123ef 100644
--- a/pandas/compat/pyarrow.py
+++ b/pandas/compat/pyarrow.py
@@ -8,6 +8,7 @@ try:
     import pyarrow as pa
 
     _palv = Version(Version(pa.__version__).base_version)
+    pa_not_found = False
     pa_version_under10p1 = _palv < Version("10.0.1")
     pa_version_under11p0 = _palv < Version("11.0.0")
     pa_version_under12p0 = _palv < Version("12.0.0")
@@ -16,6 +17,7 @@ try:
     pa_version_under14p1 = _palv < Version("14.0.1")
     pa_version_under15p0 = _palv < Version("15.0.0")
 except ImportError:
+    pa_not_found = True
     pa_version_under10p1 = True
     pa_version_under11p0 = True
     pa_version_under12p0 = True
diff --git a/pandas/core/dtypes/dtypes.py b/pandas/core/dtypes/dtypes.py
index e90e92fa0e..1c43ef55c1 100644
--- a/pandas/core/dtypes/dtypes.py
+++ b/pandas/core/dtypes/dtypes.py
@@ -919,7 +919,7 @@ class DatetimeTZDtype(PandasExtensionDtype):
         else:
             np_arr = array.to_numpy()
 
-        return DatetimeArray._from_sequence(np_arr, dtype=self, copy=False)
+        return DatetimeArray._simple_new(np_arr, dtype=self)
 
     def __setstate__(self, state) -> None:
         # for pickle compat. __get_state__ is defined in the


Test patch:
diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml
index dd5d090e09..a3cffb4b03 100644
--- a/.github/workflows/unit-tests.yml
+++ b/.github/workflows/unit-tests.yml
@@ -92,7 +92,10 @@ jobs:
           - name: "Numpy Dev"
             env_file: actions-311-numpydev.yaml
             pattern: "not slow and not network and not single_cpu"
-            test_args: "-W error::DeprecationWarning -W error::FutureWarning"
+            # Currently restricted the warnings that error to Deprecation Warnings from numpy
+            # done since pyarrow isn't compatible with numpydev always
+            # TODO: work with pyarrow to revert this?
+            test_args: "-W error::DeprecationWarning:numpy -W error::FutureWarning:numpy"
           - name: "Pyarrow Nightly"
             env_file: actions-311-pyarrownightly.yaml
             pattern: "not slow and not network and not single_cpu"
diff --git a/pandas/tests/arrays/datetimes/test_constructors.py b/pandas/tests/arrays/datetimes/test_constructors.py
index daf4aa3b47..3652b5fec4 100644
--- a/pandas/tests/arrays/datetimes/test_constructors.py
+++ b/pandas/tests/arrays/datetimes/test_constructors.py
@@ -223,7 +223,7 @@ COARSE_TO_FINE_SAFE = [123, None, -123]
         ("s", "ns", "US/Central", "Asia/Kolkata", COARSE_TO_FINE_SAFE),
     ],
 )
-def test_from_arrowtest_from_arrow_with_different_units_and_timezones_with_(
+def test_from_arrow_with_different_units_and_timezones_with(
     pa_unit, pd_unit, pa_tz, pd_tz, data
 ):
     pa = pytest.importorskip("pyarrow")
@@ -233,9 +233,8 @@ def test_from_arrowtest_from_arrow_with_different_units_and_timezones_with_(
     dtype = DatetimeTZDtype(unit=pd_unit, tz=pd_tz)
 
     result = dtype.__from_arrow__(arr)
-    expected = DatetimeArray._from_sequence(
-        np.array(data, dtype=f"datetime64[{pa_unit}]").astype(f"datetime64[{pd_unit}]"),
-        dtype=dtype,
+    expected = DatetimeArray._from_sequence(data, dtype=f"M8[{pa_unit}, UTC]").astype(
+        dtype, copy=False
     )
     tm.assert_extension_array_equal(result, expected)
 
diff --git a/pandas/tests/generic/test_to_xarray.py b/pandas/tests/generic/test_to_xarray.py
index e0d79c3f15..d8401a8b2a 100644
--- a/pandas/tests/generic/test_to_xarray.py
+++ b/pandas/tests/generic/test_to_xarray.py
@@ -41,7 +41,7 @@ class TestDataFrameToXArray:
         df.index.name = "foo"
         df.columns.name = "bar"
         result = df.to_xarray()
-        assert result.dims["foo"] == 4
+        assert result.sizes["foo"] == 4
         assert len(result.coords) == 1
         assert len(result.data_vars) == 8
         tm.assert_almost_equal(list(result.coords.keys()), ["foo"])
@@ -62,7 +62,7 @@ class TestDataFrameToXArray:
 
         df.index.name = "foo"
         result = df[0:0].to_xarray()
-        assert result.dims["foo"] == 0
+        assert result.sizes["foo"] == 0
         assert isinstance(result, Dataset)
 
     def test_to_xarray_with_multiindex(self, df, using_infer_string):
@@ -71,8 +71,8 @@ class TestDataFrameToXArray:
         # MultiIndex
         df.index = MultiIndex.from_product([["a"], range(4)], names=["one", "two"])
         result = df.to_xarray()
-        assert result.dims["one"] == 1
-        assert result.dims["two"] == 4
+        assert result.sizes["one"] == 1
+        assert result.sizes["two"] == 4
         assert len(result.coords) == 2
         assert len(result.data_vars) == 8
         tm.assert_almost_equal(list(result.coords.keys()), ["one", "two"])
diff --git a/pandas/tests/test_common.py b/pandas/tests/test_common.py
index e8a1c961c8..fe24755e8c 100644
--- a/pandas/tests/test_common.py
+++ b/pandas/tests/test_common.py
@@ -8,6 +8,8 @@ import textwrap
 import numpy as np
 import pytest
 
+import pandas.util._test_decorators as td
+
 import pandas as pd
 from pandas import Series
 import pandas._testing as tm
@@ -265,3 +267,23 @@ def test_bz2_missing_import():
     code = textwrap.dedent(code)
     call = [sys.executable, "-c", code]
     subprocess.check_output(call)
+
+
+@td.skip_if_installed("pyarrow")
+@pytest.mark.parametrize("module", ["pandas", "pandas.arrays"])
+def test_pyarrow_missing_warn(module):
+    # GH56896
+    response = subprocess.run(
+        [sys.executable, "-c", f"import {module}"],
+        capture_output=True,
+        check=True,
+    )
+    msg = """
+Pyarrow will become a required dependency of pandas in the next major release of pandas (pandas 3.0),
+(to allow more performant data types, such as the Arrow string type, and better interoperability with other libraries)
+but was not found to be installed on your system.
+If this would cause problems for you,
+please provide us feedback at https://github.com/pandas-dev/pandas/issues/54466
+"""  # noqa: E501
+    stderr_msg = response.stderr.decode("utf-8")
+    assert msg in stderr_msg, stderr_msg