(data)
| 171 | |
| 172 | |
| 173 | def isnull(data): |
| 174 | data = asarray(data) |
| 175 | |
| 176 | xp = get_array_namespace(data) |
| 177 | scalar_type = data.dtype |
| 178 | if dtypes.is_datetime_like(scalar_type): |
| 179 | # datetime types use NaT for null |
| 180 | # note: must check timedelta64 before integers, because currently |
| 181 | # timedelta64 inherits from np.integer |
| 182 | return isnat(data) |
| 183 | elif HAS_STRING_DTYPE and isinstance(scalar_type, np.dtypes.StringDType): |
| 184 | # na is settable, but it defaults to an empty string |
| 185 | na_object = getattr(scalar_type, "na_object", "") |
| 186 | if isna(na_object): |
| 187 | return xp.isnan(data) |
| 188 | else: |
| 189 | return data == na_object |
| 190 | elif dtypes.isdtype(scalar_type, ("real floating", "complex floating"), xp=xp): |
| 191 | # float types use NaN for null |
| 192 | return xp.isnan(data) |
| 193 | elif dtypes.isdtype(scalar_type, ("bool", "integral"), xp=xp) or ( |
| 194 | isinstance(scalar_type, np.dtype) |
| 195 | and ( |
| 196 | np.issubdtype(scalar_type, np.character) |
| 197 | or np.issubdtype(scalar_type, np.void) |
| 198 | ) |
| 199 | ): |
| 200 | # these types cannot represent missing values |
| 201 | # bool_ is for backwards compat with numpy<2, and cupy |
| 202 | dtype = xp.bool_ if hasattr(xp, "bool_") else xp.bool |
| 203 | return full_like(data, dtype=dtype, fill_value=False) |
| 204 | # at this point, array should have dtype=object |
| 205 | elif isinstance(data, np.ndarray) or pd.api.types.is_extension_array_dtype(data): # noqa: TID251 |
| 206 | return pandas_isnull(data) |
| 207 | else: |
| 208 | # Not reachable yet, but intended for use with other duck array |
| 209 | # types. For full consistency with pandas, we should accept None as |
| 210 | # a null value as well as NaN, but it isn't clear how to do this |
| 211 | # with duck typing. |
| 212 | return data != data # noqa: PLR0124 |
| 213 | |
| 214 | |
| 215 | def notnull(data): |
no test coverage detected
searching dependent graphs…