Skip to content

Commit

Permalink
Merge branch 'main' into issue2
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmedibrhm committed Jul 10, 2022
2 parents 8f67c9f + 56dc719 commit fa4e26b
Show file tree
Hide file tree
Showing 58 changed files with 883 additions and 202 deletions.
8 changes: 4 additions & 4 deletions pandas/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# flake8: noqa
from __future__ import annotations

__docformat__ = "restructuredtext"
Expand All @@ -20,7 +19,7 @@
del _hard_dependencies, _dependency, _missing_dependencies

# numpy compat
from pandas.compat import is_numpy_dev as _is_numpy_dev
from pandas.compat import is_numpy_dev as _is_numpy_dev # pyright: ignore # noqa:F401

try:
from pandas._libs import hashtable as _hashtable, lib as _lib, tslib as _tslib
Expand All @@ -44,7 +43,7 @@
)

# let init-time option registration happen
import pandas.core.config_init
import pandas.core.config_init # pyright: ignore # noqa:F401

from pandas.core.api import (
# dtype
Expand Down Expand Up @@ -134,7 +133,8 @@
qcut,
)

from pandas import api, arrays, errors, io, plotting, testing, tseries
from pandas import api, arrays, errors, io, plotting, tseries
from pandas import testing # noqa:PDF015
from pandas.util._print_versions import show_versions

from pandas.io.api import (
Expand Down
2 changes: 1 addition & 1 deletion pandas/_config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"options",
]
from pandas._config import config
from pandas._config import dates # noqa:F401
from pandas._config import dates # pyright: ignore # noqa:F401
from pandas._config.config import (
describe_option,
get_option,
Expand Down
24 changes: 13 additions & 11 deletions pandas/_libs/interval.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ import numpy.typing as npt

from pandas._libs import lib
from pandas._typing import (
IntervalClosedType,
IntervalInclusiveType,
Timedelta,
Timestamp,
)

VALID_CLOSED: frozenset[str]
VALID_INCLUSIVE: frozenset[str]

_OrderableScalarT = TypeVar("_OrderableScalarT", int, float)
_OrderableTimesT = TypeVar("_OrderableTimesT", Timestamp, Timedelta)
Expand Down Expand Up @@ -52,29 +52,31 @@ class IntervalMixin:
def open_right(self) -> bool: ...
@property
def is_empty(self) -> bool: ...
def _check_closed_matches(self, other: IntervalMixin, name: str = ...) -> None: ...
def _check_inclusive_matches(
self, other: IntervalMixin, name: str = ...
) -> None: ...

def _warning_interval(
inclusive, closed
) -> tuple[IntervalClosedType, lib.NoDefault]: ...
) -> tuple[IntervalInclusiveType, lib.NoDefault]: ...

class Interval(IntervalMixin, Generic[_OrderableT]):
@property
def left(self: Interval[_OrderableT]) -> _OrderableT: ...
@property
def right(self: Interval[_OrderableT]) -> _OrderableT: ...
@property
def inclusive(self) -> IntervalClosedType: ...
def inclusive(self) -> IntervalInclusiveType: ...
@property
def closed(self) -> IntervalClosedType: ...
def closed(self) -> IntervalInclusiveType: ...
mid: _MidDescriptor
length: _LengthDescriptor
def __init__(
self,
left: _OrderableT,
right: _OrderableT,
inclusive: IntervalClosedType = ...,
closed: IntervalClosedType = ...,
inclusive: IntervalInclusiveType = ...,
closed: IntervalInclusiveType = ...,
) -> None: ...
def __hash__(self) -> int: ...
@overload
Expand Down Expand Up @@ -150,15 +152,15 @@ class Interval(IntervalMixin, Generic[_OrderableT]):
def overlaps(self: Interval[_OrderableT], other: Interval[_OrderableT]) -> bool: ...

def intervals_to_interval_bounds(
intervals: np.ndarray, validate_closed: bool = ...
) -> tuple[np.ndarray, np.ndarray, str]: ...
intervals: np.ndarray, validate_inclusive: bool = ...
) -> tuple[np.ndarray, np.ndarray, IntervalInclusiveType]: ...

class IntervalTree(IntervalMixin):
def __init__(
self,
left: np.ndarray,
right: np.ndarray,
inclusive: IntervalClosedType = ...,
inclusive: IntervalInclusiveType = ...,
leaf_size: int = ...,
) -> None: ...
@property
Expand Down
50 changes: 25 additions & 25 deletions pandas/_libs/interval.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ from pandas._libs.tslibs.util cimport (
is_timedelta64_object,
)

VALID_CLOSED = frozenset(['both', 'neither', 'left', 'right'])
VALID_INCLUSIVE = frozenset(['both', 'neither', 'left', 'right'])


cdef class IntervalMixin:
Expand Down Expand Up @@ -85,7 +85,7 @@ cdef class IntervalMixin:
Returns
-------
bool
True if the Interval is closed on the left-side.
True if the Interval is closed on the right-side.
"""
return self.inclusive in ('right', 'both')

Expand All @@ -99,7 +99,7 @@ cdef class IntervalMixin:
Returns
-------
bool
True if the Interval is closed on the left-side.
True if the Interval is not closed on the left-side.
"""
return not self.closed_left

Expand All @@ -113,7 +113,7 @@ cdef class IntervalMixin:
Returns
-------
bool
True if the Interval is closed on the left-side.
True if the Interval is not closed on the right-side.
"""
return not self.closed_right

Expand Down Expand Up @@ -188,7 +188,7 @@ cdef class IntervalMixin:
"""
return (self.right == self.left) & (self.inclusive != 'both')

def _check_closed_matches(self, other, name='other'):
def _check_inclusive_matches(self, other, name='other'):
"""
Check if the inclusive attribute of `other` matches.
Expand All @@ -203,7 +203,7 @@ cdef class IntervalMixin:
Raises
------
ValueError
When `other` is not closed exactly the same as self.
When `other` is not inclusive exactly the same as self.
"""
if self.inclusive != other.inclusive:
raise ValueError(f"'{name}.inclusive' is {repr(other.inclusive)}, "
Expand Down Expand Up @@ -259,14 +259,14 @@ cdef class Interval(IntervalMixin):
.. deprecated:: 1.5.0
inclusive : {'both', 'neither', 'left', 'right'}, default 'both'
Whether the interval is closed on the left-side, right-side, both or
Whether the interval is inclusive on the left-side, right-side, both or
neither. See the Notes for more detailed explanation.
.. versionadded:: 1.5.0
See Also
--------
IntervalIndex : An Index of Interval objects that are all closed on the
IntervalIndex : An Index of Interval objects that are all inclusive on the
same side.
cut : Convert continuous data into discrete bins (Categorical
of Interval objects).
Expand All @@ -279,13 +279,13 @@ cdef class Interval(IntervalMixin):
The parameters `left` and `right` must be from the same type, you must be
able to compare them and they must satisfy ``left <= right``.
A closed interval (in mathematics denoted by square brackets) contains
its endpoints, i.e. the closed interval ``[0, 5]`` is characterized by the
A inclusive interval (in mathematics denoted by square brackets) contains
its endpoints, i.e. the inclusive interval ``[0, 5]`` is characterized by the
conditions ``0 <= x <= 5``. This is what ``inclusive='both'`` stands for.
An open interval (in mathematics denoted by parentheses) does not contain
its endpoints, i.e. the open interval ``(0, 5)`` is characterized by the
conditions ``0 < x < 5``. This is what ``inclusive='neither'`` stands for.
Intervals can also be half-open or half-closed, i.e. ``[0, 5)`` is
Intervals can also be half-open or half-inclusive, i.e. ``[0, 5)`` is
described by ``0 <= x < 5`` (``inclusive='left'``) and ``(0, 5]`` is
described by ``0 < x <= 5`` (``inclusive='right'``).
Expand Down Expand Up @@ -352,7 +352,7 @@ cdef class Interval(IntervalMixin):

cdef readonly str inclusive
"""
Whether the interval is closed on the left-side, right-side, both or
Whether the interval is inclusive on the left-side, right-side, both or
neither.
"""

Expand All @@ -368,7 +368,7 @@ cdef class Interval(IntervalMixin):
if inclusive is None:
inclusive = "right"

if inclusive not in VALID_CLOSED:
if inclusive not in VALID_INCLUSIVE:
raise ValueError(f"invalid option for 'inclusive': {inclusive}")
if not left <= right:
raise ValueError("left side of interval must be <= right side")
Expand Down Expand Up @@ -522,7 +522,7 @@ cdef class Interval(IntervalMixin):
"""
Check whether two Interval objects overlap.
Two intervals overlap if they share a common point, including closed
Two intervals overlap if they share a common point, including inclusive
endpoints. Intervals that only have an open endpoint in common do not
overlap.
Expand Down Expand Up @@ -551,7 +551,7 @@ cdef class Interval(IntervalMixin):
>>> i1.overlaps(i3)
False
Intervals that share closed endpoints overlap:
Intervals that share inclusive endpoints overlap:
>>> i4 = pd.Interval(0, 1, inclusive='both')
>>> i5 = pd.Interval(1, 2, inclusive='both')
Expand All @@ -568,7 +568,7 @@ cdef class Interval(IntervalMixin):
raise TypeError("`other` must be an Interval, "
f"got {type(other).__name__}")

# equality is okay if both endpoints are closed (overlap at a point)
# equality is okay if both endpoints are inclusive (overlap at a point)
op1 = le if (self.closed_left and other.closed_right) else lt
op2 = le if (other.closed_left and self.closed_right) else lt

Expand All @@ -580,16 +580,16 @@ cdef class Interval(IntervalMixin):

@cython.wraparound(False)
@cython.boundscheck(False)
def intervals_to_interval_bounds(ndarray intervals, bint validate_closed=True):
def intervals_to_interval_bounds(ndarray intervals, bint validate_inclusive=True):
"""
Parameters
----------
intervals : ndarray
Object array of Intervals / nulls.
validate_closed: bool, default True
Boolean indicating if all intervals must be closed on the same side.
Mismatching closed will raise if True, else return None for closed.
validate_inclusive: bool, default True
Boolean indicating if all intervals must be inclusive on the same side.
Mismatching inclusive will raise if True, else return None for inclusive.
Returns
-------
Expand All @@ -602,7 +602,7 @@ def intervals_to_interval_bounds(ndarray intervals, bint validate_closed=True):
object inclusive = None, interval
Py_ssize_t i, n = len(intervals)
ndarray left, right
bint seen_closed = False
bint seen_inclusive = False

left = np.empty(n, dtype=intervals.dtype)
right = np.empty(n, dtype=intervals.dtype)
Expand All @@ -620,13 +620,13 @@ def intervals_to_interval_bounds(ndarray intervals, bint validate_closed=True):

left[i] = interval.left
right[i] = interval.right
if not seen_closed:
seen_closed = True
if not seen_inclusive:
seen_inclusive = True
inclusive = interval.inclusive
elif inclusive != interval.inclusive:
inclusive = None
if validate_closed:
raise ValueError("intervals must all be closed on the same side")
if validate_inclusive:
raise ValueError("intervals must all be inclusive on the same side")

return left, right, inclusive

Expand Down
28 changes: 23 additions & 5 deletions pandas/_libs/lib.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ from cpython.number cimport PyNumber_Check
from cpython.object cimport (
Py_EQ,
PyObject_RichCompareBool,
PyTypeObject,
)
from cpython.ref cimport Py_INCREF
from cpython.sequence cimport PySequence_Check
Expand Down Expand Up @@ -54,6 +55,11 @@ from numpy cimport (

cnp.import_array()

cdef extern from "Python.h":
# Note: importing extern-style allows us to declare these as nogil
# functions, whereas `from cpython cimport` does not.
bint PyObject_TypeCheck(object obj, PyTypeObject* type) nogil

cdef extern from "numpy/arrayobject.h":
# cython's numpy.dtype specification is incorrect, which leads to
# errors in issubclass(self.dtype.type, np.bool_), so we directly
Expand All @@ -71,6 +77,9 @@ cdef extern from "numpy/arrayobject.h":
object fields
tuple names

PyTypeObject PySignedIntegerArrType_Type
PyTypeObject PyUnsignedIntegerArrType_Type

cdef extern from "numpy/ndarrayobject.h":
bint PyArray_CheckScalar(obj) nogil

Expand Down Expand Up @@ -1283,9 +1292,9 @@ cdef class Seen:
In addition to setting a flag that an integer was seen, we
also set two flags depending on the type of integer seen:
1) sint_ : a negative (signed) number in the
1) sint_ : a signed numpy integer type or a negative (signed) number in the
range of [-2**63, 0) was encountered
2) uint_ : a positive number in the range of
2) uint_ : an unsigned numpy integer type or a positive number in the range of
[2**63, 2**64) was encountered
Parameters
Expand All @@ -1294,8 +1303,18 @@ cdef class Seen:
Value with which to set the flags.
"""
self.int_ = True
self.sint_ = self.sint_ or (oINT64_MIN <= val < 0)
self.uint_ = self.uint_ or (oINT64_MAX < val <= oUINT64_MAX)
self.sint_ = (
self.sint_
or (oINT64_MIN <= val < 0)
# Cython equivalent of `isinstance(val, np.signedinteger)`
or PyObject_TypeCheck(val, &PySignedIntegerArrType_Type)
)
self.uint_ = (
self.uint_
or (oINT64_MAX < val <= oUINT64_MAX)
# Cython equivalent of `isinstance(val, np.unsignedinteger)`
or PyObject_TypeCheck(val, &PyUnsignedIntegerArrType_Type)
)

@property
def numeric_(self):
Expand Down Expand Up @@ -2542,7 +2561,6 @@ def maybe_convert_objects(ndarray[object] objects,
floats[i] = <float64_t>val
complexes[i] = <double complex>val
if not seen.null_:
val = int(val)
seen.saw_int(val)

if ((seen.uint_ and seen.sint_) or
Expand Down
Loading

0 comments on commit fa4e26b

Please sign in to comment.