Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions pandas-stubs/core/algorithms.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ def unique(values: IntervalIndex[IntervalT]) -> IntervalIndex[IntervalT]: ...
@overload
def unique(values: PeriodIndex) -> PeriodIndex: ...
@overload
# switch to DatetimeIndex after Pandas 3.0
# TODO: switch to DatetimeIndex after Pandas 3.0 pandas-dev/pandas#57064
def unique(values: DatetimeIndex) -> np_1darray_dt | DatetimeIndex: ...
@overload
# switch to TimedeltaIndex after Pandas 3.0
# TODO: switch to TimedeltaIndex after Pandas 3.0 pandas-dev/pandas#57064
def unique(values: TimedeltaIndex) -> np_1darray_td: ...
@overload
# switch to Index[int] after Pandas 3.0
Expand All @@ -59,7 +59,8 @@ else:
) -> np_ndarray: ...

@overload
def unique(values: Index) -> np_1darray | Index: ... # switch to Index after Pandas 3.0
# TODO: switch to Index after Pandas 3.0 pandas-dev/pandas#57064
def unique(values: Index) -> np_1darray | Index: ...
@overload
def unique(values: Categorical) -> Categorical: ...

Expand Down
44 changes: 33 additions & 11 deletions pandas-stubs/core/arrays/__init__.pyi
Original file line number Diff line number Diff line change
@@ -1,11 +1,33 @@
from pandas.core.arrays.base import ExtensionArray as ExtensionArray
from pandas.core.arrays.boolean import BooleanArray as BooleanArray
from pandas.core.arrays.categorical import Categorical as Categorical
from pandas.core.arrays.datetimes import DatetimeArray as DatetimeArray
from pandas.core.arrays.integer import IntegerArray as IntegerArray
from pandas.core.arrays.interval import IntervalArray as IntervalArray
from pandas.core.arrays.numpy_ import NumpyExtensionArray as NumpyExtensionArray
from pandas.core.arrays.period import PeriodArray as PeriodArray
from pandas.core.arrays.sparse import SparseArray as SparseArray
from pandas.core.arrays.string_ import StringArray as StringArray
from pandas.core.arrays.timedeltas import TimedeltaArray as TimedeltaArray
from pandas.core.arrays.arrow import ArrowExtensionArray
from pandas.core.arrays.base import ExtensionArray
from pandas.core.arrays.boolean import BooleanArray
from pandas.core.arrays.categorical import Categorical
from pandas.core.arrays.datetimes import DatetimeArray
from pandas.core.arrays.floating import FloatingArray
from pandas.core.arrays.integer import IntegerArray
from pandas.core.arrays.interval import IntervalArray
from pandas.core.arrays.masked import BaseMaskedArray
from pandas.core.arrays.numpy_ import NumpyExtensionArray
from pandas.core.arrays.period import PeriodArray
from pandas.core.arrays.sparse import SparseArray
from pandas.core.arrays.string_ import StringArray
from pandas.core.arrays.string_arrow import ArrowStringArray
from pandas.core.arrays.timedeltas import TimedeltaArray

__all__ = [
"ArrowExtensionArray",
"ArrowStringArray",
"BaseMaskedArray",
"BooleanArray",
"Categorical",
"DatetimeArray",
"ExtensionArray",
"FloatingArray",
"IntegerArray",
"IntervalArray",
"NumpyExtensionArray",
"PeriodArray",
"SparseArray",
"StringArray",
"TimedeltaArray",
]
97 changes: 95 additions & 2 deletions pandas-stubs/core/construction.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,57 @@ from collections.abc import (
MutableSequence,
Sequence,
)
from datetime import datetime
from datetime import (
datetime,
timedelta,
)
from typing import (
Any,
TypeAlias,
overload,
)

import numpy as np
from pandas.core.arrays.base import ExtensionArray
from pandas.core.arrays.boolean import BooleanArray
from pandas.core.arrays.categorical import Categorical
from pandas.core.arrays.datetimes import DatetimeArray
from pandas.core.arrays.floating import FloatingArray
from pandas.core.arrays.integer import IntegerArray
from pandas.core.arrays.interval import IntervalArray
from pandas.core.arrays.numpy_ import NumpyExtensionArray
from pandas.core.arrays.period import PeriodArray
from pandas.core.arrays.sparse.array import SparseArray
from pandas.core.arrays.string_ import (
BaseStringArray,
StringArray,
StringDtype,
)
from pandas.core.arrays.string_arrow import ArrowStringArray
from pandas.core.arrays.timedeltas import TimedeltaArray
from pandas.core.indexes.base import Index
from pandas.core.indexes.category import CategoricalIndex
from pandas.core.indexes.datetimes import DatetimeIndex
from pandas.core.indexes.interval import IntervalIndex
from pandas.core.indexes.period import PeriodIndex
from pandas.core.indexes.range import RangeIndex
from pandas.core.indexes.timedeltas import TimedeltaIndex
from pandas.core.series import Series
from typing_extensions import Never

from pandas._libs.interval import Interval
from pandas._libs.missing import NAType
from pandas._libs.tslibs.nattype import NaTType
from pandas._libs.tslibs.period import Period
from pandas._libs.tslibs.timedeltas import Timedelta
from pandas._libs.tslibs.timestamps import Timestamp
from pandas._typing import (
BuiltinNotStrDtypeArg,
CategoryDtypeArg,
IntervalT,
Just,
NumpyNotTimeDtypeArg,
NumpyTimedeltaDtypeArg,
NumpyTimestampDtypeArg,
PandasBaseStrDtypeArg,
PandasBooleanDtypeArg,
Expand All @@ -51,9 +70,14 @@ from pandas._typing import (
np_ndarray_dt,
np_ndarray_float,
np_ndarray_str,
np_ndarray_td,
)

from pandas.core.dtypes.dtypes import DatetimeTZDtype
from pandas.core.dtypes.dtypes import (
DatetimeTZDtype,
IntervalDtype,
PeriodDtype,
)

_NAStrElement: TypeAlias = str | np.str_ | NAType | None
_NaNStrElement: TypeAlias = Just[float] | _NAStrElement
Expand Down Expand Up @@ -86,6 +110,50 @@ def array( # type: ignore[overload-overlap] # pyright: ignore[reportOverlapping
copy: bool = True,
) -> NumpyExtensionArray: ...
@overload
def array(
data: MutableSequence[Any] | np_ndarray | ExtensionArray | Index | Series,
dtype: CategoryDtypeArg,
copy: bool = True,
) -> Categorical: ...
@overload
def array(
# TODO: Categorical Series pandas-dev/pandas-stubs#1415
data: Categorical | CategoricalIndex,
dtype: CategoryDtypeArg | None = None,
copy: bool = True,
) -> Categorical: ...
@overload
def array( # type: ignore[overload-overlap]
data: (
Sequence[Period | NaTType | None] | PeriodArray | PeriodIndex | Series[Period]
),
dtype: PeriodDtype | None = None,
copy: bool = True,
) -> PeriodArray: ...
@overload
def array(
data: (
Sequence[IntervalT | None | float]
| IntervalArray
| IntervalIndex
| Series[Interval]
),
dtype: IntervalDtype,
copy: bool = True,
) -> IntervalArray: ...
@overload
def array( # type: ignore[overload-overlap]
data: Sequence[IntervalT | None] | IntervalArray | IntervalIndex | Series[Interval],
dtype: None = None,
copy: bool = True,
) -> IntervalArray: ...
@overload
def array(
data: SparseArray,
dtype: None = None,
copy: bool = True,
) -> SparseArray: ...
@overload
def array( # pyright: ignore[reportOverlappingOverload]
data: (
Sequence[Timedelta]
Expand Down Expand Up @@ -169,6 +237,31 @@ def array( # type: ignore[overload-overlap]
copy: bool = True,
) -> DatetimeArray: ...
@overload
def array( # type: ignore[overload-overlap]
data: ( # TODO: merge the two Sequence's after 3.0 pandas-dev/pandas#57064
Sequence[datetime | NaTType | None]
| Sequence[np.datetime64 | NaTType | None]
| np_ndarray_dt
| DatetimeArray
| DatetimeIndex
| Series[Timestamp]
),
dtype: PandasTimestampDtypeArg | NumpyTimestampDtypeArg | None = None,
copy: bool = True,
) -> DatetimeArray: ...
@overload
def array( # type: ignore[overload-overlap]
data: (
Sequence[timedelta | np.timedelta64 | NaTType | None]
| np_ndarray_td
| TimedeltaArray
| TimedeltaIndex
| Series[Timedelta]
),
dtype: NumpyTimedeltaDtypeArg | None = None,
copy: bool = True,
) -> TimedeltaArray: ...
@overload
def array( # type: ignore[overload-overlap]
data: _NaNStrData, dtype: StringDtype[Never], copy: bool = True
) -> BaseStringArray: ...
Expand Down
1 change: 1 addition & 0 deletions tests/_typing.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# ruff: noqa: PLC0414
# This file serves as a stub file for static type checkers
# (pyright does not like it if I call the file tests/_typing.pyi).
# It can only import from pandas._typing.
Expand Down
24 changes: 24 additions & 0 deletions tests/arrays/test_datetime_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from typing import (
TYPE_CHECKING,
Any,
cast,
)
from zoneinfo import ZoneInfo

Expand Down Expand Up @@ -276,3 +277,26 @@ def test_properties() -> None:
np_1darray,
np.float64,
)


def test_constructor() -> None:
dt = datetime(2025, 11, 10)
check(assert_type(pd.array([dt]), DatetimeArray), DatetimeArray)
check(assert_type(pd.array([dt, pd.Timestamp(dt)]), DatetimeArray), DatetimeArray)
check(assert_type(pd.array([dt, None]), DatetimeArray), DatetimeArray)
check(assert_type(pd.array([dt, pd.NaT, None]), DatetimeArray), DatetimeArray)

np_dt = np.datetime64(dt)
check(assert_type(pd.array([np_dt]), DatetimeArray), DatetimeArray)
check(assert_type(pd.array([np_dt, None]), DatetimeArray), DatetimeArray)
dt_nat = cast(list[np.datetime64 | NaTType], [np_dt, pd.NaT])
check(assert_type(pd.array(dt_nat), DatetimeArray), DatetimeArray)

np_arr = np.array([dt], np.datetime64)
check(assert_type(pd.array(np_arr), DatetimeArray), DatetimeArray)

check(assert_type(pd.array(pd.array([dt])), DatetimeArray), DatetimeArray)

check(assert_type(pd.array(pd.Index([dt])), DatetimeArray), DatetimeArray)

check(assert_type(pd.array(pd.Series([dt])), DatetimeArray), DatetimeArray)
12 changes: 12 additions & 0 deletions tests/arrays/test_interval.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@
)


def test_construction() -> None:
itv = pd.Interval(0, 1)
check(assert_type(pd.array([itv]), IntervalArray), IntervalArray)
check(assert_type(pd.array([itv, None]), IntervalArray), IntervalArray)

check(assert_type(pd.array(pd.array([itv])), IntervalArray), IntervalArray)

check(assert_type(pd.array(pd.Index([itv])), IntervalArray), IntervalArray)

check(assert_type(pd.array(pd.Series([itv])), IntervalArray), IntervalArray)


def test_constructor() -> None:
"""Test constructor method for IntervalArray."""
intervals = [Interval(0, 1), Interval(1, 2), Interval(2, 3)]
Expand Down
13 changes: 13 additions & 0 deletions tests/arrays/test_period.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@
)


def test_construction() -> None:
prd = pd.Period("2023-01-01")
check(assert_type(pd.array([prd]), PeriodArray), PeriodArray)
check(assert_type(pd.array([prd, None]), PeriodArray), PeriodArray)
check(assert_type(pd.array([prd, pd.NaT, None]), PeriodArray), PeriodArray)

check(assert_type(pd.array(pd.array([prd])), PeriodArray), PeriodArray)

check(assert_type(pd.array(pd.Index([prd])), PeriodArray), PeriodArray)

check(assert_type(pd.array(pd.Series([prd])), PeriodArray), PeriodArray)


def test_constructor() -> None:
"""Test init method for PeriodArray."""
# From numpy array of integers (ordinals) with dtype
Expand Down
4 changes: 4 additions & 0 deletions tests/arrays/test_sparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
)


def test_construction() -> None:
check(assert_type(pd.array(SparseArray([1])), SparseArray), SparseArray)


def test_constructor() -> None:
"""Test __new__ method for SparseArray."""
arr = SparseArray([1, 0, 0, 2, 3])
Expand Down
14 changes: 14 additions & 0 deletions tests/arrays/test_timedeltas.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,25 @@

def test_construction() -> None:
"""Test pd.array method for TimedeltaArray."""

td = timedelta(2025, 11, 10)
np_dt = np.timedelta64(td)
check(assert_type(pd.array([td]), TimedeltaArray), TimedeltaArray)
check(
assert_type(pd.array([td, pd.Timedelta(td), np_dt]), TimedeltaArray),
TimedeltaArray,
)
check(assert_type(pd.array([td, None]), TimedeltaArray), TimedeltaArray)
check(assert_type(pd.array([td, pd.NaT, None]), TimedeltaArray), TimedeltaArray)

# From TimedeltaIndex
idx = pd.TimedeltaIndex(["1 days", "2 days", "3 days"])
arr = pd.array(idx)
check(assert_type(arr, TimedeltaArray), TimedeltaArray)

# From Series
check(assert_type(pd.array(pd.Series(idx)), TimedeltaArray), TimedeltaArray)

# From numpy array of timedelta64
values = np.array(
[np.timedelta64(1, "D"), np.timedelta64(2, "D"), np.timedelta64(3, "D")]
Expand Down