Skip to content

Commit 2183e20

Browse files
Merge remote-tracking branch 'upstream/main' into array-copy-false-extra-test
2 parents 31d7d72 + c15d823 commit 2183e20

31 files changed

+166
-99
lines changed

doc/source/whatsnew/v2.3.0.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,8 @@ Styler
173173

174174
Other
175175
^^^^^
176-
-
176+
- Fixed usage of ``inspect`` when the optional dependencies ``pyarrow`` or ``jinja2``
177+
are not installed (:issue:`60196`)
177178
-
178179

179180
.. ---------------------------------------------------------------------------

doc/source/whatsnew/v3.0.0.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,9 @@ Other
771771
- Bug in :meth:`DataFrame.apply` where passing ``engine="numba"`` ignored ``args`` passed to the applied function (:issue:`58712`)
772772
- Bug in :meth:`DataFrame.eval` and :meth:`DataFrame.query` which caused an exception when using NumPy attributes via ``@`` notation, e.g., ``df.eval("@np.floor(a)")``. (:issue:`58041`)
773773
- Bug in :meth:`DataFrame.eval` and :meth:`DataFrame.query` which did not allow to use ``tan`` function. (:issue:`55091`)
774+
- Bug in :meth:`DataFrame.query` where using duplicate column names led to a ``TypeError``. (:issue:`59950`)
774775
- Bug in :meth:`DataFrame.query` which raised an exception or produced incorrect results when expressions contained backtick-quoted column names containing the hash character ``#``, backticks, or characters that fall outside the ASCII range (U+0001..U+007F). (:issue:`59285`) (:issue:`49633`)
776+
- Bug in :meth:`DataFrame.shift` where passing a ``freq`` on a DataFrame with no columns did not shift the index correctly. (:issue:`60102`)
775777
- Bug in :meth:`DataFrame.sort_index` when passing ``axis="columns"`` and ``ignore_index=True`` and ``ascending=False`` not returning a :class:`RangeIndex` columns (:issue:`57293`)
776778
- Bug in :meth:`DataFrame.transform` that was returning the wrong order unless the index was monotonically increasing. (:issue:`57069`)
777779
- Bug in :meth:`DataFrame.where` where using a non-bool type array in the function would return a ``ValueError`` instead of a ``TypeError`` (:issue:`56330`)

pandas/_testing/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,8 @@ def shares_memory(left, right) -> bool:
501501
if isinstance(left, MultiIndex):
502502
return shares_memory(left._codes, right)
503503
if isinstance(left, (Index, Series)):
504+
if isinstance(right, (Index, Series)):
505+
return shares_memory(left._values, right._values)
504506
return shares_memory(left._values, right)
505507

506508
if isinstance(left, NDArrayBackedExtensionArray):

pandas/conftest.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ def multiindex_year_month_day_dataframe_random_data():
600600
"""
601601
tdf = DataFrame(
602602
np.random.default_rng(2).standard_normal((100, 4)),
603-
columns=Index(list("ABCD"), dtype=object),
603+
columns=Index(list("ABCD")),
604604
index=date_range("2000-01-01", periods=100, freq="B"),
605605
)
606606
ymd = tdf.groupby([lambda x: x.year, lambda x: x.month, lambda x: x.day]).sum()
@@ -787,7 +787,7 @@ def string_series() -> Series:
787787
"""
788788
return Series(
789789
np.arange(30, dtype=np.float64) * 1.1,
790-
index=Index([f"i_{i}" for i in range(30)], dtype=object),
790+
index=Index([f"i_{i}" for i in range(30)]),
791791
name="series",
792792
)
793793

@@ -798,7 +798,7 @@ def object_series() -> Series:
798798
Fixture for Series of dtype object with Index of unique strings
799799
"""
800800
data = [f"foo_{i}" for i in range(30)]
801-
index = Index([f"bar_{i}" for i in range(30)], dtype=object)
801+
index = Index([f"bar_{i}" for i in range(30)])
802802
return Series(data, index=index, name="objects", dtype=object)
803803

804804

@@ -890,8 +890,8 @@ def int_frame() -> DataFrame:
890890
"""
891891
return DataFrame(
892892
np.ones((30, 4), dtype=np.int64),
893-
index=Index([f"foo_{i}" for i in range(30)], dtype=object),
894-
columns=Index(list("ABCD"), dtype=object),
893+
index=Index([f"foo_{i}" for i in range(30)]),
894+
columns=Index(list("ABCD")),
895895
)
896896

897897

pandas/core/arrays/arrow/accessors.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def _is_valid_pyarrow_dtype(self, pyarrow_dtype) -> bool:
4646

4747
def _validate(self, data) -> None:
4848
dtype = data.dtype
49-
if not isinstance(dtype, ArrowDtype):
49+
if pa_version_under10p1 or not isinstance(dtype, ArrowDtype):
5050
# Raise AttributeError so that inspect can handle non-struct Series.
5151
raise AttributeError(self._validation_msg.format(dtype=dtype))
5252

pandas/core/arrays/string_.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
from functools import partial
34
import operator
45
from typing import (
56
TYPE_CHECKING,
@@ -64,6 +65,8 @@
6465
from pandas.core.indexers import check_array_indexer
6566
from pandas.core.missing import isna
6667

68+
from pandas.io.formats import printing
69+
6770
if TYPE_CHECKING:
6871
import pyarrow
6972

@@ -391,6 +394,14 @@ def _from_scalars(cls, scalars, dtype: DtypeObj) -> Self:
391394
raise ValueError
392395
return cls._from_sequence(scalars, dtype=dtype)
393396

397+
def _formatter(self, boxed: bool = False):
398+
formatter = partial(
399+
printing.pprint_thing,
400+
escape_chars=("\t", "\r", "\n"),
401+
quote_strings=not boxed,
402+
)
403+
return formatter
404+
394405
def _str_map(
395406
self,
396407
f,
@@ -757,6 +768,12 @@ def _putmask(self, mask: npt.NDArray[np.bool_], value) -> None:
757768
# base class implementation that uses __setitem__
758769
ExtensionArray._putmask(self, mask, value)
759770

771+
def _where(self, mask: npt.NDArray[np.bool_], value) -> Self:
772+
# the super() method NDArrayBackedExtensionArray._where uses
773+
# np.putmask which doesn't properly handle None/pd.NA, so using the
774+
# base class implementation that uses __setitem__
775+
return ExtensionArray._where(self, mask, value)
776+
760777
def isin(self, values: ArrayLike) -> npt.NDArray[np.bool_]:
761778
if isinstance(values, BaseStringArray) or (
762779
isinstance(values, ExtensionArray) and is_string_dtype(values.dtype)

pandas/core/arrays/string_arrow.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from pandas.compat import (
1818
pa_version_under10p1,
1919
pa_version_under13p0,
20+
pa_version_under16p0,
2021
)
2122
from pandas.util._exceptions import find_stack_level
2223

@@ -71,6 +72,10 @@ def _chk_pyarrow_available() -> None:
7172
raise ImportError(msg)
7273

7374

75+
def _is_string_view(typ):
76+
return not pa_version_under16p0 and pa.types.is_string_view(typ)
77+
78+
7479
# TODO: Inherit directly from BaseStringArrayMethods. Currently we inherit from
7580
# ObjectStringArrayMixin because we want to have the object-dtype based methods as
7681
# fallback for the ones that pyarrow doesn't yet support
@@ -128,11 +133,13 @@ def __init__(self, values) -> None:
128133
_chk_pyarrow_available()
129134
if isinstance(values, (pa.Array, pa.ChunkedArray)) and (
130135
pa.types.is_string(values.type)
136+
or _is_string_view(values.type)
131137
or (
132138
pa.types.is_dictionary(values.type)
133139
and (
134140
pa.types.is_string(values.type.value_type)
135141
or pa.types.is_large_string(values.type.value_type)
142+
or _is_string_view(values.type.value_type)
136143
)
137144
)
138145
):

pandas/core/base.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,8 +361,11 @@ def __len__(self) -> int:
361361
# We need this defined here for mypy
362362
raise AbstractMethodError(self)
363363

364+
# Temporarily avoid using `-> Literal[1]:` because of an IPython (jedi) bug
365+
# https://github.com/ipython/ipython/issues/14412
366+
# https://github.com/davidhalter/jedi/issues/1990
364367
@property
365-
def ndim(self) -> Literal[1]:
368+
def ndim(self) -> int:
366369
"""
367370
Number of dimensions of the underlying data, by definition 1.
368371

pandas/core/config_init.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,10 @@ def use_numba_cb(key: str) -> None:
100100
: int
101101
If max_rows is exceeded, switch to truncate view. Depending on
102102
`large_repr`, objects are either centrally truncated or printed as
103-
a summary view. 'None' value means unlimited.
103+
a summary view.
104+
105+
'None' value means unlimited. Beware that printing a large number of rows
106+
could cause your rendering environment (the browser, etc.) to crash.
104107
105108
In case python/IPython is running in a terminal and `large_repr`
106109
equals 'truncate' this can be set to 0 and pandas will auto-detect
@@ -121,7 +124,11 @@ def use_numba_cb(key: str) -> None:
121124
: int
122125
If max_cols is exceeded, switch to truncate view. Depending on
123126
`large_repr`, objects are either centrally truncated or printed as
124-
a summary view. 'None' value means unlimited.
127+
a summary view.
128+
129+
'None' value means unlimited. Beware that printing a large number of
130+
columns could cause your rendering environment (the browser, etc.) to
131+
crash.
125132
126133
In case python/IPython is running in a terminal and `large_repr`
127134
equals 'truncate' this can be set to 0 or None and pandas will auto-detect

pandas/core/frame.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1397,6 +1397,11 @@ def style(self) -> Styler:
13971397
Please see
13981398
`Table Visualization <../../user_guide/style.ipynb>`_ for more examples.
13991399
"""
1400+
# Raise AttributeError so that inspect works even if jinja2 is not installed.
1401+
has_jinja2 = import_optional_dependency("jinja2", errors="ignore")
1402+
if not has_jinja2:
1403+
raise AttributeError("The '.style' accessor requires jinja2")
1404+
14001405
from pandas.io.formats.style import Styler
14011406

14021407
return Styler(self)
@@ -5705,7 +5710,7 @@ def shift(
57055710
"Passing a 'freq' together with a 'fill_value' is not allowed."
57065711
)
57075712

5708-
if self.empty:
5713+
if self.empty and freq is None:
57095714
return self.copy()
57105715

57115716
axis = self._get_axis_number(axis)

0 commit comments

Comments
 (0)