Skip to content

Commit 9f11564

Browse files
author
Bas van Beek
committed
ENH: Add integer.is_integer
Match `int.is_integer`, which was added in python/cpython#6121
1 parent 5d86d8c commit 9f11564

File tree

5 files changed

+37
-2
lines changed

5 files changed

+37
-2
lines changed

numpy/__init__.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3190,6 +3190,7 @@ class integer(number[_NBit1]): # type: ignore
31903190
__args: Union[L[0], Tuple[()], Tuple[L[0]]] = ...,
31913191
) -> int: ...
31923192
def tolist(self) -> int: ...
3193+
def is_integer(self) -> L[True]: ...
31933194
def __index__(self) -> int: ...
31943195
__truediv__: _IntTrueDiv[_NBit1]
31953196
__rtruediv__: _IntTrueDiv[_NBit1]

numpy/core/_add_newdocs_scalars.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,18 @@ def add_newdoc_for_scalar_type(obj, fixed_aliases, doc):
240240
See :ref:`arrays.datetime` for more information.
241241
""")
242242

243+
add_newdoc('numpy.core.numerictypes', "integer", ('is_integer',
244+
f"""
245+
integer.is_integer() -> bool
246+
247+
Return ``True`` if the number is finite with integral value.
248+
249+
>>> np.int64(-2).is_integer()
250+
True
251+
>>> np.uint32(5).is_integer()
252+
True
253+
"""))
254+
243255
# TODO: work out how to put this on the base class, np.floating
244256
for float_name in ('half', 'single', 'double', 'longdouble'):
245257
add_newdoc('numpy.core.numerictypes', float_name, ('as_integer_ratio',

numpy/core/src/multiarray/scalartypes.c.src

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1937,6 +1937,11 @@ static PyObject *
19371937
}
19381938
/**end repeat**/
19391939

1940+
static PyObject *
1941+
integer_is_integer(PyObject *self) {
1942+
Py_RETURN_TRUE;
1943+
}
1944+
19401945
/*
19411946
* need to fill in doc-strings for these methods on import -- copy from
19421947
* array docstrings
@@ -2195,7 +2200,7 @@ static PyMethodDef @name@type_methods[] = {
21952200
/**end repeat**/
21962201

21972202
/**begin repeat
2198-
* #name = integer,floating, complexfloating#
2203+
* #name = floating, complexfloating#
21992204
*/
22002205
static PyMethodDef @name@type_methods[] = {
22012206
/* Hook for the round() builtin */
@@ -2206,6 +2211,17 @@ static PyMethodDef @name@type_methods[] = {
22062211
};
22072212
/**end repeat**/
22082213

2214+
static PyMethodDef integertype_methods[] = {
2215+
/* Hook for the round() builtin */
2216+
{"__round__",
2217+
(PyCFunction)integertype_dunder_round,
2218+
METH_VARARGS | METH_KEYWORDS, NULL},
2219+
{"is_integer",
2220+
(PyCFunction)integer_is_integer,
2221+
METH_NOARGS, NULL},
2222+
{NULL, NULL, 0, NULL} /* sentinel */
2223+
};
2224+
22092225
/**begin repeat
22102226
* #name = half,float,double,longdouble#
22112227
*/

numpy/core/tests/test_scalar_methods.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,19 +104,23 @@ def test_roundtrip(self, ftype, frac_vals, exp_vals):
104104
assert_equal(nf / df, f, "{}/{}".format(n, d))
105105

106106

107-
@pytest.mark.parametrize("code", np.typecodes["Float"])
108107
class TestIsInteger:
109108
@pytest.mark.parametrize("str_value", ["inf", "nan"])
109+
@pytest.mark.parametrize("code", np.typecodes["Float"])
110110
def test_special(self, code: str, str_value: str) -> None:
111111
cls = np.dtype(code).type
112112
value = cls(str_value)
113113
assert not value.is_integer()
114114

115+
@pytest.mark.parametrize(
116+
"code", np.typecodes["Float"] + np.typecodes["AllInteger"]
117+
)
115118
def test_true(self, code: str) -> None:
116119
float_array = np.arange(-5, 5).astype(code)
117120
for value in float_array:
118121
assert value.is_integer()
119122

123+
@pytest.mark.parametrize("code", np.typecodes["Float"])
120124
def test_false(self, code: str) -> None:
121125
float_array = np.arange(-5, 5).astype(code)
122126
float_array *= 1.1

numpy/typing/tests/data/reveal/scalars.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,5 @@
156156
if sys.version_info >= (3, 9):
157157
reveal_type(f8.__ceil__()) # E: int
158158
reveal_type(f8.__floor__()) # E: int
159+
160+
reveal_type(i8.is_integer()) # E: Literal[True]

0 commit comments

Comments
 (0)