Skip to content

Commit 37cc235

Browse files
authored
Merge branch 'main' into fix-interval_range-dtype
2 parents 9faeaeb + fa5b90a commit 37cc235

35 files changed

+341
-164
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
- [ ] All [code checks passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#pre-commit).
44
- [ ] Added [type annotations](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#type-hints) to new arguments/methods/functions.
55
- [ ] Added an entry in the latest `doc/source/whatsnew/vX.X.X.rst` file if fixing a bug or adding a new feature.
6+
- [ ] If I used AI to develop this pull request, I prompted it to follow `AGENTS.md`.

AGENTS.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# pandas Agent Instructions
2+
3+
## Project Overview
4+
`pandas` is an open source, BSD-licensed library providing high-performance, easy-to-use data structures and data analysis tools for the Python programming language.
5+
6+
## Purpose
7+
- Assist contributors by suggesting code changes, tests, and documentation edits for the pandas repository while preserving stability and compatibility.
8+
9+
## Persona & Tone
10+
- Concise, neutral, code-focused. Prioritize correctness, readability, and tests.
11+
12+
## Project Guidelines
13+
- Be sure to follow all guidelines for contributing to the codebase specified at https://pandas.pydata.org/docs/development/contributing_codebase.html
14+
- These guidelines are also available in the following local files, which should be loaded into context and adhered to
15+
- doc/source/development/contributing_codebase.rst
16+
- doc/source/development/contributing_docstring.rst
17+
- doc/source/development/contributing_documentation.rst
18+
- doc/source/development/contributing.rst
19+
20+
## Decision heuristics
21+
- Favor small, backward-compatible changes with tests.
22+
- If a change would be breaking, propose it behind a deprecation path and document the rationale.
23+
- Prefer readability over micro-optimizations unless benchmarks are requested.
24+
- Add tests for behavioral changes; update docs only after code change is final.
25+
26+
## Type hints guidance (summary)
27+
- Prefer PEP 484 style and types in pandas._typing when appropriate.
28+
- Avoid unnecessary use of typing.cast; prefer refactors that convey types to type-checkers.
29+
- Use builtin generics (list, dict) when possible.
30+
31+
## Docstring guidance (summary)
32+
- Follow NumPy / numpydoc conventions used across the repo: short summary, extended summary, Parameters, Returns/Yields, See Also, Notes, Examples.
33+
- Ensure examples are deterministic, import numpy/pandas as documented, and pass doctest rules used by docs validation.
34+
- Preserve formatting rules: triple double-quotes, no blank line before/after docstring, parameter formatting ("name : type, default ..."), types and examples conventions.
35+
36+
## Pull Requests (summary)
37+
- Pull request titles should be descriptive and include one of the following prefixes:
38+
- ENH: Enhancement, new functionality
39+
- BUG: Bug fix
40+
- DOC: Additions/updates to documentation
41+
- TST: Additions/updates to tests
42+
- BLD: Updates to the build process/scripts
43+
- PERF: Performance improvement
44+
- TYP: Type annotations
45+
- CLN: Code cleanup
46+
- Pull request descriptions should follow the template, and **succinctly** describe the change being made. Usually a few sentences is sufficient.
47+
- Pull requests which are resolving an existing Github Issue should include a link to the issue in the PR Description.
48+
- Do not add summaries or additional comments to individual commit messages. The single PR description is sufficient.

doc/source/whatsnew/v3.0.0.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1032,13 +1032,13 @@ Bug fixes
10321032
Categorical
10331033
^^^^^^^^^^^
10341034
- Bug in :class:`Categorical` where constructing from a pandas :class:`Series` or :class:`Index` with ``dtype='object'`` did not preserve the categories' dtype as ``object``; now the ``categories.dtype`` is preserved as ``object`` for these cases, while numpy arrays and Python sequences with ``dtype='object'`` continue to infer the most specific dtype (for example, ``str`` if all elements are strings) (:issue:`61778`)
1035+
- Bug in :class:`pandas.Categorical` displaying string categories without quotes when using "string" dtype (:issue:`63045`)
10351036
- Bug in :func:`Series.apply` where ``nan`` was ignored for :class:`CategoricalDtype` (:issue:`59938`)
10361037
- Bug in :func:`bdate_range` raising ``ValueError`` with frequency ``freq="cbh"`` (:issue:`62849`)
10371038
- Bug in :func:`testing.assert_index_equal` raising ``TypeError`` instead of ``AssertionError`` for incomparable ``CategoricalIndex`` when ``check_categorical=True`` and ``exact=False`` (:issue:`61935`)
10381039
- Bug in :meth:`Categorical.astype` where ``copy=False`` would still trigger a copy of the codes (:issue:`62000`)
10391040
- Bug in :meth:`DataFrame.pivot` and :meth:`DataFrame.set_index` raising an ``ArrowNotImplementedError`` for columns with pyarrow dictionary dtype (:issue:`53051`)
10401041
- Bug in :meth:`Series.convert_dtypes` with ``dtype_backend="pyarrow"`` where empty :class:`CategoricalDtype` :class:`Series` raised an error or got converted to ``null[pyarrow]`` (:issue:`59934`)
1041-
-
10421042

10431043
Datetimelike
10441044
^^^^^^^^^^^^

pandas/_libs/internals.pyi

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,7 @@ class BlockValuesRefs:
9494
def add_reference(self, blk: Block) -> None: ...
9595
def add_index_reference(self, index: Index) -> None: ...
9696
def has_reference(self) -> bool: ...
97+
98+
class SetitemMixin:
99+
def __setitem__(self, key, value) -> None: ...
100+
def __delitem__(self, key) -> None: ...

pandas/_libs/internals.pyx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
from collections import defaultdict
2+
import sys
3+
import warnings
24

35
cimport cython
6+
from cpython cimport PY_VERSION_HEX
47
from cpython.object cimport PyObject
58
from cpython.pyport cimport PY_SSIZE_T_MAX
69
from cpython.slice cimport PySlice_GetIndicesEx
@@ -20,6 +23,9 @@ from numpy cimport (
2023
cnp.import_array()
2124

2225
from pandas._libs.algos import ensure_int64
26+
from pandas.compat import CHAINED_WARNING_DISABLED
27+
from pandas.errors import ChainedAssignmentError
28+
from pandas.errors.cow import _chained_assignment_msg
2329

2430
from pandas._libs.util cimport (
2531
is_array,
@@ -996,3 +1002,43 @@ cdef class BlockValuesRefs:
9961002
return self._has_reference_maybe_locked()
9971003
ELSE:
9981004
return self._has_reference_maybe_locked()
1005+
1006+
1007+
cdef extern from "Python.h":
1008+
"""
1009+
#if PY_VERSION_HEX < 0x030E0000
1010+
int __Pyx_PyUnstable_Object_IsUniqueReferencedTemporary(PyObject *ref);
1011+
#else
1012+
#define __Pyx_PyUnstable_Object_IsUniqueReferencedTemporary \
1013+
PyUnstable_Object_IsUniqueReferencedTemporary
1014+
#endif
1015+
"""
1016+
int PyUnstable_Object_IsUniqueReferencedTemporary\
1017+
"__Pyx_PyUnstable_Object_IsUniqueReferencedTemporary"(object o) except -1
1018+
1019+
1020+
# Python version compatibility for PyUnstable_Object_IsUniqueReferencedTemporary
1021+
cdef inline bint _is_unique_referenced_temporary(object obj) except -1:
1022+
if PY_VERSION_HEX >= 0x030E0000:
1023+
# Python 3.14+ has PyUnstable_Object_IsUniqueReferencedTemporary
1024+
return PyUnstable_Object_IsUniqueReferencedTemporary(obj)
1025+
else:
1026+
# Fallback for older Python versions using sys.getrefcount
1027+
return sys.getrefcount(obj) <= 1
1028+
1029+
1030+
cdef class SetitemMixin:
1031+
# class used in DataFrame and Series for checking for chained assignment
1032+
1033+
def __setitem__(self, key, value) -> None:
1034+
cdef bint is_unique = 0
1035+
if not CHAINED_WARNING_DISABLED:
1036+
is_unique = _is_unique_referenced_temporary(self)
1037+
if is_unique:
1038+
warnings.warn(
1039+
_chained_assignment_msg, ChainedAssignmentError, stacklevel=1
1040+
)
1041+
self._setitem(key, value)
1042+
1043+
def __delitem__(self, key) -> None:
1044+
self._delitem(key)

pandas/_libs/lib.pyx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ def item_from_zerodim(val: object) -> object:
322322
>>> item_from_zerodim(np.array([1]))
323323
array([1])
324324
"""
325-
if cnp.PyArray_IsZeroDim(val):
325+
if cnp.PyArray_IsZeroDim(val) and cnp.PyArray_CheckExact(val):
326326
return cnp.PyArray_ToScalar(cnp.PyArray_DATA(val), val)
327327
return val
328328

@@ -2716,18 +2716,16 @@ def maybe_convert_objects(ndarray[object] objects,
27162716
if convert_non_numeric:
27172717
if getattr(val, "tzinfo", None) is not None:
27182718
seen.datetimetz_ = True
2719-
break
27202719
else:
27212720
seen.datetime_ = True
27222721
try:
27232722
convert_to_tsobject(val, None, None, 0, 0)
27242723
except OutOfBoundsDatetime:
27252724
# e.g. test_out_of_s_bounds_datetime64
27262725
seen.object_ = True
2727-
break
27282726
else:
27292727
seen.object_ = True
2730-
break
2728+
break
27312729
elif is_period_object(val):
27322730
if convert_non_numeric:
27332731
seen.period_ = True

pandas/_libs/tslibs/timestamps.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3492,7 +3492,7 @@ default 'raise'
34923492
year -= 1
34933493
month += 12
34943494
return (day +
3495-
np.fix((153 * month - 457) / 5) +
3495+
np.trunc((153 * month - 457) / 5) +
34963496
365 * year +
34973497
np.floor(year / 4) -
34983498
np.floor(year / 100) +

pandas/_testing/contexts.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
import uuid
1414

1515
from pandas.compat import (
16-
PYPY,
17-
WARNING_CHECK_DISABLED,
16+
CHAINED_WARNING_DISABLED,
17+
CHAINED_WARNING_DISABLED_INPLACE_METHOD,
1818
)
1919
from pandas.errors import ChainedAssignmentError
2020

@@ -163,10 +163,18 @@ def with_csv_dialect(name: str, **kwargs) -> Generator[None]:
163163
csv.unregister_dialect(name)
164164

165165

166-
def raises_chained_assignment_error(extra_warnings=(), extra_match=()):
166+
def raises_chained_assignment_error(
167+
extra_warnings=(), extra_match=(), inplace_method=False
168+
):
167169
from pandas._testing import assert_produces_warning
168170

169-
if PYPY or WARNING_CHECK_DISABLED:
171+
WARNING_DISABLED = (
172+
CHAINED_WARNING_DISABLED_INPLACE_METHOD
173+
if inplace_method
174+
else CHAINED_WARNING_DISABLED
175+
)
176+
177+
if WARNING_DISABLED:
170178
if not extra_warnings:
171179
from contextlib import nullcontext
172180

pandas/compat/__init__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@
1616
from typing import TYPE_CHECKING
1717

1818
from pandas.compat._constants import (
19+
CHAINED_WARNING_DISABLED,
20+
CHAINED_WARNING_DISABLED_INPLACE_METHOD,
1921
IS64,
2022
ISMUSL,
2123
PY312,
2224
PY314,
2325
PYPY,
24-
WARNING_CHECK_DISABLED,
2526
WASM,
2627
)
2728
from pandas.compat.numpy import is_numpy_dev
@@ -152,14 +153,15 @@ def is_ci_environment() -> bool:
152153

153154

154155
__all__ = [
156+
"CHAINED_WARNING_DISABLED",
157+
"CHAINED_WARNING_DISABLED_INPLACE_METHOD",
155158
"HAS_PYARROW",
156159
"IS64",
157160
"ISMUSL",
158161
"PY312",
159162
"PY314",
160163
"PYARROW_MIN_VERSION",
161164
"PYPY",
162-
"WARNING_CHECK_DISABLED",
163165
"WASM",
164166
"is_numpy_dev",
165167
"pa_version_under14p0",

pandas/compat/_constants.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
WASM = (sys.platform == "emscripten") or (platform.machine() in ["wasm32", "wasm64"])
2020
ISMUSL = "musl" in (sysconfig.get_config_var("HOST_GNU_TYPE") or "")
2121
REF_COUNT = 2
22-
WARNING_CHECK_DISABLED = PY314
22+
CHAINED_WARNING_DISABLED = PYPY or (PY314 and not sys._is_gil_enabled()) # type: ignore[attr-defined]
23+
CHAINED_WARNING_DISABLED_INPLACE_METHOD = PYPY or PY314
2324

2425

2526
__all__ = [

0 commit comments

Comments
 (0)