Skip to content
Merged
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
6 changes: 2 additions & 4 deletions pandas-stubs/core/arrays/boolean.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@ from pandas._typing import (
type_t,
)

from pandas.core.dtypes.base import ExtensionDtype as ExtensionDtype
from pandas.core.dtypes.dtypes import BaseMaskedDtype

class BooleanDtype(ExtensionDtype):
@property
def na_value(self) -> NAType: ...
class BooleanDtype(BaseMaskedDtype):
@classmethod
def construct_array_type(cls) -> type_t[BooleanArray]: ...

Expand Down
21 changes: 18 additions & 3 deletions pandas-stubs/core/arrays/floating.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,21 @@ from pandas.core.arrays.numeric import (
NumericDtype,
)

class Float32Dtype(NumericDtype): ...
class Float64Dtype(NumericDtype): ...
class FloatingArray(NumericArray): ...
from pandas._typing import (
np_ndarray_bool,
np_ndarray_float,
)

class FloatingDtype(NumericDtype):
@classmethod
def construct_array_type(cls) -> type[FloatingArray]: ...

class FloatingArray(NumericArray):
@property
def dtype(self) -> FloatingDtype: ...
def __init__(
self, values: np_ndarray_float, mask: np_ndarray_bool, copy: bool = False
) -> None: ...

class Float32Dtype(FloatingDtype): ...
class Float64Dtype(FloatingDtype): ...
39 changes: 17 additions & 22 deletions pandas-stubs/core/arrays/integer.pyi
Original file line number Diff line number Diff line change
@@ -1,37 +1,32 @@
from pandas.core.arrays.masked import BaseMaskedArray
from pandas.core.arrays.numeric import (
NumericArray,
NumericDtype,
)

from pandas._libs.missing import NAType
from pandas._typing import (
AnyArrayLike,
np_ndarray_anyint,
np_ndarray_bool,
)

from pandas.core.dtypes.base import ExtensionDtype as ExtensionDtype

class _IntegerDtype(ExtensionDtype):
class IntegerDtype(NumericDtype):
base: None
@property
def na_value(self) -> NAType: ...
@property
def itemsize(self) -> int: ...
@classmethod
def construct_array_type(cls) -> type[IntegerArray]: ...

class IntegerArray(BaseMaskedArray):
class IntegerArray(NumericArray):
@property
def dtype(self) -> _IntegerDtype: ...
def dtype(self) -> IntegerDtype: ...
def __init__(
self,
values: AnyArrayLike,
mask: np_ndarray_bool,
copy: bool = False,
self, values: np_ndarray_anyint, mask: np_ndarray_bool, copy: bool = False
) -> None: ...

class Int8Dtype(_IntegerDtype): ...
class Int16Dtype(_IntegerDtype): ...
class Int32Dtype(_IntegerDtype): ...
class Int64Dtype(_IntegerDtype): ...
class UInt8Dtype(_IntegerDtype): ...
class UInt16Dtype(_IntegerDtype): ...
class UInt32Dtype(_IntegerDtype): ...
class UInt64Dtype(_IntegerDtype): ...
class Int8Dtype(IntegerDtype): ...
class Int16Dtype(IntegerDtype): ...
class Int32Dtype(IntegerDtype): ...
class Int64Dtype(IntegerDtype): ...
class UInt8Dtype(IntegerDtype): ...
class UInt16Dtype(IntegerDtype): ...
class UInt32Dtype(IntegerDtype): ...
class UInt64Dtype(IntegerDtype): ...
6 changes: 5 additions & 1 deletion pandas-stubs/core/dtypes/dtypes.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ from pandas.core.indexes.base import Index
from pandas.core.series import Series

from pandas._libs import NaTType
from pandas._libs.missing import NAType
from pandas._libs.tslibs import BaseOffset
from pandas._libs.tslibs.offsets import (
RelativeDeltaOffset,
Expand All @@ -26,7 +27,10 @@ from pandas.core.dtypes.base import (
register_extension_dtype as register_extension_dtype,
)

class BaseMaskedDtype(ExtensionDtype): ...
class BaseMaskedDtype(ExtensionDtype):
@property
def na_value(self) -> NAType: ...

class PandasExtensionDtype(ExtensionDtype): ...

class CategoricalDtype(PandasExtensionDtype, ExtensionDtype):
Expand Down
73 changes: 70 additions & 3 deletions tests/arrays/test_boolean_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@
import pytest
from typing_extensions import assert_type

from tests import check
from pandas._libs.missing import NAType

from tests import (
TYPE_CHECKING_INVALID_USAGE,
check,
)
from tests._typing import PandasBooleanDtypeArg
from tests.dtypes import PANDAS_BOOL_ARGS
from tests.utils import powerset


Expand Down Expand Up @@ -57,5 +64,65 @@ def test_construction_array_like() -> None:
)


def test_construction_dtype_na() -> None:
check(assert_type(pd.array([np.nan], "boolean"), BooleanArray), BooleanArray)
@pytest.mark.parametrize("data", powerset([False, np.bool(False)]))
@pytest.mark.parametrize(("dtype", "target_dtype"), PANDAS_BOOL_ARGS.items())
def test_construction_dtype(
data: tuple[bool | np.bool, ...], dtype: PandasBooleanDtypeArg, target_dtype: type
) -> None:
dtype_notna = target_dtype if data else None
check(pd.array([*data], dtype), BooleanArray, dtype_notna)
check(pd.array([True, *data], dtype), BooleanArray, dtype_notna)
check(pd.array([np.bool(True), *data], dtype), BooleanArray, dtype_notna)

dtype_na = target_dtype if data else NAType
check(pd.array([*data, np.nan], dtype), BooleanArray, dtype_na)
check(pd.array([True, *data, np.nan], dtype), BooleanArray, target_dtype)
check(pd.array([np.bool(True), *data, np.nan], dtype), BooleanArray, target_dtype)

if TYPE_CHECKING:
assert_type(pd.array([], pd.BooleanDtype()), BooleanArray)
assert_type(pd.array([], "boolean"), BooleanArray)

assert_type(pd.array([np.nan], pd.BooleanDtype()), BooleanArray)
assert_type(pd.array([np.nan], "boolean"), BooleanArray)

assert_type(pd.array([False], pd.BooleanDtype()), BooleanArray)
assert_type(pd.array([False], "boolean"), BooleanArray)

assert_type(pd.array([False, True], pd.BooleanDtype()), BooleanArray)
assert_type(pd.array([False, True], "boolean"), BooleanArray)

assert_type(pd.array([False, np.nan], pd.BooleanDtype()), BooleanArray)
assert_type(pd.array([False, np.nan], "boolean"), BooleanArray)

assert_type(pd.array([np.bool(False)], pd.BooleanDtype()), BooleanArray)
assert_type(pd.array([np.bool(False)], "boolean"), BooleanArray)

assert_type(
pd.array([np.bool(False), np.bool(True)], pd.BooleanDtype()), BooleanArray
)
assert_type(pd.array([np.bool(False), np.bool(True)], "boolean"), BooleanArray)

assert_type(pd.array([np.bool(False), np.nan], pd.BooleanDtype()), BooleanArray)
assert_type(pd.array([np.bool(False), np.nan], "boolean"), BooleanArray)

assert_type(pd.array([False, np.bool(True)], pd.BooleanDtype()), BooleanArray)
assert_type(pd.array([np.bool(False), True], "boolean"), BooleanArray)


def test_constructor() -> None:
check(
assert_type(BooleanArray(np.array([True]), np.array([False])), BooleanArray),
BooleanArray,
)

if TYPE_CHECKING_INVALID_USAGE:
_list_np = BooleanArray([True], np.array([False])) # type: ignore[arg-type] # pyright: ignore[reportArgumentType]
_np_list = BooleanArray(np.array([True]), [False]) # type: ignore[arg-type] # pyright: ignore[reportArgumentType]
_pd_arr = BooleanArray(pd.array([True]), np.array([False])) # type: ignore[arg-type] # pyright: ignore[reportArgumentType]
_i = BooleanArray(pd.Index([False]), np.array([False])) # type: ignore[arg-type] # pyright: ignore[reportArgumentType]
_s = BooleanArray(pd.Series([True]), np.array([False])) # type: ignore[arg-type] # pyright: ignore[reportArgumentType]


def test_dtype() -> None:
check(assert_type(pd.array([True]).dtype, pd.BooleanDtype), pd.BooleanDtype)
24 changes: 17 additions & 7 deletions tests/arrays/test_floating_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@

import numpy as np
import pandas as pd
from pandas.core.arrays.floating import FloatingArray
from pandas.core.arrays.floating import (
FloatingArray,
FloatingDtype,
)
from pandas.core.arrays.numpy_ import NumpyExtensionArray
import pytest
from typing_extensions import assert_type
Expand Down Expand Up @@ -95,14 +98,21 @@ def test_construction_dtype(dtype: PandasFloatDtypeArg, target_dtype: type) -> N
exc = exception_on_platform(dtype)
if exc:
with pytest.raises(exc, match=rf"data type {dtype!r} not understood"):
assert_type(pd.array([1.0], dtype=dtype), FloatingArray)
assert_type(pd.array([1.0], dtype), FloatingArray)
else:
check(pd.array([1.0], dtype=dtype), FloatingArray, target_dtype)
check(pd.array([1.0], dtype), FloatingArray, target_dtype)

if TYPE_CHECKING:
# pandas Float32
assert_type(pd.array([1.0], dtype=pd.Float32Dtype()), FloatingArray)
assert_type(pd.array([1.0], dtype="Float32"), FloatingArray)
assert_type(pd.array([1.0], pd.Float32Dtype()), FloatingArray)
assert_type(pd.array([1.0], "Float32"), FloatingArray)
# pandas Float64
assert_type(pd.array([1.0], dtype=pd.Float64Dtype()), FloatingArray)
assert_type(pd.array([1.0], dtype="Float64"), FloatingArray)
assert_type(pd.array([1.0], pd.Float64Dtype()), FloatingArray)
assert_type(pd.array([1.0], "Float64"), FloatingArray)


def test_dtype() -> None:
check(assert_type(pd.array([1.0]).dtype, FloatingDtype), pd.Float64Dtype)

check(assert_type(pd.array([1.0], "Float32").dtype, FloatingDtype), pd.Float32Dtype)
check(assert_type(pd.array([1.0], "Float64").dtype, FloatingDtype), pd.Float64Dtype)
96 changes: 92 additions & 4 deletions tests/arrays/test_integer_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,27 @@

import numpy as np
import pandas as pd
from pandas.core.arrays.integer import IntegerArray
from pandas.core.arrays.integer import (
IntegerArray,
IntegerDtype,
)
import pytest
from typing_extensions import assert_type

from tests import check
from pandas._libs.missing import NAType

from tests import (
TYPE_CHECKING_INVALID_USAGE,
check,
)
from tests._typing import (
PandasIntDtypeArg,
PandasUIntDtypeArg,
)
from tests.dtypes import (
PANDAS_INT_ARGS,
PANDAS_UINT_ARGS,
)
from tests.utils import powerset


Expand Down Expand Up @@ -52,5 +68,77 @@ def test_construction_array_like() -> None:
check(assert_type(pd.array(pd.array([1, np.int16(1)])), IntegerArray), IntegerArray)


def test_construction_dtype_na() -> None:
check(assert_type(pd.array([np.nan], "Int8"), IntegerArray), IntegerArray)
@pytest.mark.parametrize(("dtype", "target_dtype"), PANDAS_INT_ARGS.items(), ids=repr)
def test_construction_dtype_signed(
dtype: PandasIntDtypeArg, target_dtype: type
) -> None:
check(pd.array([np.nan], dtype), IntegerArray, NAType)
check(pd.array([-1, 2, np.nan], dtype), IntegerArray, target_dtype)
check(pd.array([1, -np.int64(2), np.nan], dtype), IntegerArray, target_dtype)

if TYPE_CHECKING:
# pandas Int8
assert_type(pd.array([-1, 2, np.nan], pd.Int8Dtype()), IntegerArray)
assert_type(pd.array([-1, 2, np.nan], "Int8"), IntegerArray)
# pandas Int16
assert_type(pd.array([-1, 2, np.nan], pd.Int16Dtype()), IntegerArray)
assert_type(pd.array([-1, 2, np.nan], "Int16"), IntegerArray)
# pandas Int32
assert_type(pd.array([-1, 2, np.nan], pd.Int32Dtype()), IntegerArray)
assert_type(pd.array([-1, 2, np.nan], "Int32"), IntegerArray)
# pandas Int64
assert_type(pd.array([-1, 2, np.nan], pd.Int64Dtype()), IntegerArray)
assert_type(pd.array([-1, 2, np.nan], "Int64"), IntegerArray)


@pytest.mark.parametrize(("dtype", "target_dtype"), PANDAS_UINT_ARGS.items(), ids=repr)
def test_construction_dtype_unsigned(
dtype: PandasUIntDtypeArg, target_dtype: type
) -> None:
check(pd.array([np.nan], dtype), IntegerArray, NAType)
check(pd.array([1, 2], dtype), IntegerArray, target_dtype)
check(pd.array([1, np.uint64(2), np.nan], dtype), IntegerArray, target_dtype)

if TYPE_CHECKING:
# pandas UInt8
assert_type(pd.array([1, 2, np.nan], pd.UInt8Dtype()), IntegerArray)
assert_type(pd.array([1, 2, np.nan], "UInt8"), IntegerArray)
# pandas UInt16
assert_type(pd.array([1, 2, np.nan], pd.UInt16Dtype()), IntegerArray)
assert_type(pd.array([1, 2, np.nan], "UInt16"), IntegerArray)
# pandas UInt32
assert_type(pd.array([1, 2, np.nan], pd.UInt32Dtype()), IntegerArray)
assert_type(pd.array([1, 2, np.nan], "UInt32"), IntegerArray)
# pandas UInt64
assert_type(pd.array([1, 2, np.nan], pd.UInt64Dtype()), IntegerArray)
assert_type(pd.array([1, 2, np.nan], "Int64"), IntegerArray)


def test_constructor() -> None:
check(
assert_type(IntegerArray(np.array([1]), np.array([False])), IntegerArray),
IntegerArray,
)

if TYPE_CHECKING_INVALID_USAGE:
_list_np = IntegerArray([1], np.array([False])) # type: ignore[arg-type] # pyright: ignore[reportArgumentType]
_np_list = IntegerArray(np.array([1]), [False]) # type: ignore[arg-type] # pyright: ignore[reportArgumentType]
_pd_arr = IntegerArray(pd.array([1]), np.array([False])) # type: ignore[arg-type] # pyright: ignore[reportArgumentType]
_i = IntegerArray(pd.Index([1]), np.array([False])) # type: ignore[arg-type] # pyright: ignore[reportArgumentType]
_s = IntegerArray(pd.Series([1]), np.array([False])) # type: ignore[arg-type] # pyright: ignore[reportArgumentType]


def test_dtype_signed() -> None:
check(assert_type(pd.array([-1]).dtype, IntegerDtype), pd.Int64Dtype)

check(assert_type(pd.array([-1], "Int8").dtype, IntegerDtype), pd.Int8Dtype)
check(assert_type(pd.array([-1], "Int16").dtype, IntegerDtype), pd.Int16Dtype)
check(assert_type(pd.array([-1], "Int32").dtype, IntegerDtype), pd.Int32Dtype)
check(assert_type(pd.array([-1], "Int64").dtype, IntegerDtype), pd.Int64Dtype)


def test_dtype_unsigned() -> None:
check(assert_type(pd.array([1], "UInt8").dtype, IntegerDtype), pd.UInt8Dtype)
check(assert_type(pd.array([1], "UInt16").dtype, IntegerDtype), pd.UInt16Dtype)
check(assert_type(pd.array([1], "UInt32").dtype, IntegerDtype), pd.UInt32Dtype)
check(assert_type(pd.array([1], "UInt64").dtype, IntegerDtype), pd.UInt64Dtype)