Skip to content

REF: move PandasDtype to dtypes.dtypes #39385

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 25, 2021
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
4 changes: 2 additions & 2 deletions pandas/core/algorithms.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
needs_i8_conversion,
pandas_dtype,
)
from pandas.core.dtypes.dtypes import PandasDtype
from pandas.core.dtypes.generic import (
ABCDatetimeArray,
ABCExtensionArray,
Expand Down Expand Up @@ -1929,7 +1930,6 @@ def diff(arr, n: int, axis: int = 0, stacklevel=3):
-------
shifted
"""
from pandas.core.arrays import PandasDtype

n = int(n)
na = np.nan
Expand All @@ -1942,7 +1942,7 @@ def diff(arr, n: int, axis: int = 0, stacklevel=3):

if isinstance(dtype, PandasDtype):
# PandasArray cannot necessarily hold shifted versions of itself.
arr = np.asarray(arr)
arr = arr.to_numpy()
dtype = arr.dtype

if is_extension_array_dtype(dtype):
Expand Down
3 changes: 1 addition & 2 deletions pandas/core/arrays/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
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 PandasArray, PandasDtype
from pandas.core.arrays.numpy_ import PandasArray
from pandas.core.arrays.period import PeriodArray, period_array
from pandas.core.arrays.sparse import SparseArray
from pandas.core.arrays.string_ import StringArray
Expand All @@ -28,7 +28,6 @@
"IntegerArray",
"IntervalArray",
"PandasArray",
"PandasDtype",
"PeriodArray",
"period_array",
"SparseArray",
Expand Down
99 changes: 2 additions & 97 deletions pandas/core/arrays/numpy_.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

import numbers
from typing import Optional, Tuple, Type, Union
from typing import Optional, Tuple, Union

import numpy as np
from numpy.lib.mixins import NDArrayOperatorsMixin
Expand All @@ -10,7 +10,7 @@
from pandas._typing import Dtype, NpDtype, Scalar
from pandas.compat.numpy import function as nv

from pandas.core.dtypes.dtypes import ExtensionDtype
from pandas.core.dtypes.dtypes import PandasDtype
from pandas.core.dtypes.missing import isna

from pandas.core import nanops, ops
Expand All @@ -19,101 +19,6 @@
from pandas.core.strings.object_array import ObjectStringArrayMixin


class PandasDtype(ExtensionDtype):
"""
A Pandas ExtensionDtype for NumPy dtypes.

.. versionadded:: 0.24.0

This is mostly for internal compatibility, and is not especially
useful on its own.

Parameters
----------
dtype : object
Object to be converted to a NumPy data type object.

See Also
--------
numpy.dtype
"""

_metadata = ("_dtype",)

def __init__(self, dtype: Optional[NpDtype]):
self._dtype = np.dtype(dtype)

def __repr__(self) -> str:
return f"PandasDtype({repr(self.name)})"

@property
def numpy_dtype(self) -> np.dtype:
"""
The NumPy dtype this PandasDtype wraps.
"""
return self._dtype

@property
def name(self) -> str:
"""
A bit-width name for this data-type.
"""
return self._dtype.name

@property
def type(self) -> Type[np.generic]:
"""
The type object used to instantiate a scalar of this NumPy data-type.
"""
return self._dtype.type

@property
def _is_numeric(self) -> bool:
# exclude object, str, unicode, void.
return self.kind in set("biufc")

@property
def _is_boolean(self) -> bool:
return self.kind == "b"

@classmethod
def construct_from_string(cls, string: str) -> PandasDtype:
try:
dtype = np.dtype(string)
except TypeError as err:
if not isinstance(string, str):
msg = f"'construct_from_string' expects a string, got {type(string)}"
else:
msg = f"Cannot construct a 'PandasDtype' from '{string}'"
raise TypeError(msg) from err
return cls(dtype)

@classmethod
def construct_array_type(cls) -> Type[PandasArray]:
"""
Return the array type associated with this dtype.

Returns
-------
type
"""
return PandasArray

@property
def kind(self) -> str:
"""
A character code (one of 'biufcmMOSUV') identifying the general kind of data.
"""
return self._dtype.kind

@property
def itemsize(self) -> int:
"""
The element size of this data-type object.
"""
return self._dtype.itemsize


class PandasArray(
OpsMixin,
NDArrayBackedExtensionArray,
Expand Down
109 changes: 107 additions & 2 deletions pandas/core/dtypes/dtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
to_offset,
tz_compare,
)
from pandas._typing import Dtype, DtypeObj, Ordered
from pandas._typing import Dtype, DtypeObj, NpDtype, Ordered

from pandas.core.dtypes.base import ExtensionDtype, register_extension_dtype
from pandas.core.dtypes.generic import ABCCategoricalIndex, ABCIndex
Expand All @@ -41,7 +41,12 @@
import pyarrow

from pandas import Categorical
from pandas.core.arrays import DatetimeArray, IntervalArray, PeriodArray
from pandas.core.arrays import (
DatetimeArray,
IntervalArray,
PandasArray,
PeriodArray,
)

str_type = str

Expand Down Expand Up @@ -1230,3 +1235,103 @@ def _get_common_dtype(self, dtypes: List[DtypeObj]) -> Optional[DtypeObj]:
if common == object:
return np.dtype(object)
return IntervalDtype(common, closed=closed)


class PandasDtype(ExtensionDtype):
"""
A Pandas ExtensionDtype for NumPy dtypes.

.. versionadded:: 0.24.0

This is mostly for internal compatibility, and is not especially
useful on its own.

Parameters
----------
dtype : object
Object to be converted to a NumPy data type object.

See Also
--------
numpy.dtype
"""

_metadata = ("_dtype",)

def __init__(self, dtype: Optional[Union[NpDtype, PandasDtype]]):
if isinstance(dtype, PandasDtype):
# make constructor univalent
dtype = dtype.numpy_dtype
self._dtype = np.dtype(dtype)

def __repr__(self) -> str:
return f"PandasDtype({repr(self.name)})"

@property
def numpy_dtype(self) -> np.dtype:
"""
The NumPy dtype this PandasDtype wraps.
"""
return self._dtype

@property
def name(self) -> str:
"""
A bit-width name for this data-type.
"""
return self._dtype.name

@property
def type(self) -> Type[np.generic]:
"""
The type object used to instantiate a scalar of this NumPy data-type.
"""
return self._dtype.type

@property
def _is_numeric(self) -> bool:
# exclude object, str, unicode, void.
return self.kind in set("biufc")

@property
def _is_boolean(self) -> bool:
return self.kind == "b"

@classmethod
def construct_from_string(cls, string: str) -> PandasDtype:
try:
dtype = np.dtype(string)
except TypeError as err:
if not isinstance(string, str):
msg = f"'construct_from_string' expects a string, got {type(string)}"
else:
msg = f"Cannot construct a 'PandasDtype' from '{string}'"
raise TypeError(msg) from err
return cls(dtype)

@classmethod
def construct_array_type(cls) -> Type[PandasArray]:
"""
Return the array type associated with this dtype.

Returns
-------
type
"""
from pandas.core.arrays import PandasArray

return PandasArray

@property
def kind(self) -> str:
"""
A character code (one of 'biufcmMOSUV') identifying the general kind of data.
"""
return self._dtype.kind

@property
def itemsize(self) -> int:
"""
The element size of this data-type object.
"""
return self._dtype.itemsize
4 changes: 2 additions & 2 deletions pandas/core/internals/array_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
is_extension_array_dtype,
is_numeric_dtype,
)
from pandas.core.dtypes.dtypes import ExtensionDtype
from pandas.core.dtypes.dtypes import ExtensionDtype, PandasDtype
from pandas.core.dtypes.generic import ABCDataFrame, ABCSeries
from pandas.core.dtypes.missing import isna

import pandas.core.algorithms as algos
from pandas.core.arrays import ExtensionArray, PandasDtype
from pandas.core.arrays import ExtensionArray
from pandas.core.arrays.sparse import SparseDtype
from pandas.core.construction import extract_array
from pandas.core.indexers import maybe_convert_indices
Expand Down
3 changes: 1 addition & 2 deletions pandas/core/internals/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
is_sparse,
pandas_dtype,
)
from pandas.core.dtypes.dtypes import CategoricalDtype, ExtensionDtype
from pandas.core.dtypes.dtypes import CategoricalDtype, ExtensionDtype, PandasDtype
from pandas.core.dtypes.generic import ABCDataFrame, ABCIndex, ABCPandasArray, ABCSeries
from pandas.core.dtypes.missing import isna

Expand All @@ -67,7 +67,6 @@
DatetimeArray,
ExtensionArray,
PandasArray,
PandasDtype,
TimedeltaArray,
)
from pandas.core.base import PandasObject
Expand Down
10 changes: 9 additions & 1 deletion pandas/tests/arrays/test_numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
import numpy as np
import pytest

from pandas.core.dtypes.dtypes import PandasDtype

import pandas as pd
import pandas._testing as tm
from pandas.arrays import PandasArray
from pandas.core.arrays.numpy_ import PandasDtype


@pytest.fixture(
Expand Down Expand Up @@ -86,6 +87,13 @@ def test_constructor_from_string():
assert result == expected


def test_dtype_univalent(any_numpy_dtype):
dtype = PandasDtype(any_numpy_dtype)

result = PandasDtype(dtype)
assert result == dtype


# ----------------------------------------------------------------------------
# Construction

Expand Down
8 changes: 6 additions & 2 deletions pandas/tests/extension/test_numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
import numpy as np
import pytest

from pandas.core.dtypes.dtypes import ExtensionDtype
from pandas.core.dtypes.dtypes import ExtensionDtype, PandasDtype

import pandas as pd
import pandas._testing as tm
from pandas.core.arrays.numpy_ import PandasArray, PandasDtype
from pandas.core.arrays.numpy_ import PandasArray

from . import base

Expand Down Expand Up @@ -313,6 +313,10 @@ def test_arith_series_with_scalar(self, data, all_arithmetic_operators):
def test_arith_series_with_array(self, data, all_arithmetic_operators):
super().test_arith_series_with_array(data, all_arithmetic_operators)

@skip_nested
def test_arith_frame_with_scalar(self, data, all_arithmetic_operators):
super().test_arith_frame_with_scalar(data, all_arithmetic_operators)


class TestPrinting(BaseNumPyTests, base.BasePrintingTests):
pass
Expand Down