Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.9/dist-packages/pandas/core/dtypes/inference.py: 80%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

64 statements  

1""" basic inference routines """ 

2 

3from __future__ import annotations 

4 

5from collections import abc 

6from numbers import Number 

7import re 

8from re import Pattern 

9from typing import TYPE_CHECKING 

10 

11import numpy as np 

12 

13from pandas._libs import lib 

14 

15if TYPE_CHECKING: 

16 from collections.abc import Hashable 

17 

18 from pandas._typing import TypeGuard 

19 

20is_bool = lib.is_bool 

21 

22is_integer = lib.is_integer 

23 

24is_float = lib.is_float 

25 

26is_complex = lib.is_complex 

27 

28is_scalar = lib.is_scalar 

29 

30is_decimal = lib.is_decimal 

31 

32is_interval = lib.is_interval 

33 

34is_list_like = lib.is_list_like 

35 

36is_iterator = lib.is_iterator 

37 

38 

39def is_number(obj) -> TypeGuard[Number | np.number]: 

40 """ 

41 Check if the object is a number. 

42 

43 Returns True when the object is a number, and False if is not. 

44 

45 Parameters 

46 ---------- 

47 obj : any type 

48 The object to check if is a number. 

49 

50 Returns 

51 ------- 

52 bool 

53 Whether `obj` is a number or not. 

54 

55 See Also 

56 -------- 

57 api.types.is_integer: Checks a subgroup of numbers. 

58 

59 Examples 

60 -------- 

61 >>> from pandas.api.types import is_number 

62 >>> is_number(1) 

63 True 

64 >>> is_number(7.15) 

65 True 

66 

67 Booleans are valid because they are int subclass. 

68 

69 >>> is_number(False) 

70 True 

71 

72 >>> is_number("foo") 

73 False 

74 >>> is_number("5") 

75 False 

76 """ 

77 return isinstance(obj, (Number, np.number)) 

78 

79 

80def iterable_not_string(obj) -> bool: 

81 """ 

82 Check if the object is an iterable but not a string. 

83 

84 Parameters 

85 ---------- 

86 obj : The object to check. 

87 

88 Returns 

89 ------- 

90 is_iter_not_string : bool 

91 Whether `obj` is a non-string iterable. 

92 

93 Examples 

94 -------- 

95 >>> iterable_not_string([1, 2, 3]) 

96 True 

97 >>> iterable_not_string("foo") 

98 False 

99 >>> iterable_not_string(1) 

100 False 

101 """ 

102 return isinstance(obj, abc.Iterable) and not isinstance(obj, str) 

103 

104 

105def is_file_like(obj) -> bool: 

106 """ 

107 Check if the object is a file-like object. 

108 

109 For objects to be considered file-like, they must 

110 be an iterator AND have either a `read` and/or `write` 

111 method as an attribute. 

112 

113 Note: file-like objects must be iterable, but 

114 iterable objects need not be file-like. 

115 

116 Parameters 

117 ---------- 

118 obj : The object to check 

119 

120 Returns 

121 ------- 

122 bool 

123 Whether `obj` has file-like properties. 

124 

125 Examples 

126 -------- 

127 >>> import io 

128 >>> from pandas.api.types import is_file_like 

129 >>> buffer = io.StringIO("data") 

130 >>> is_file_like(buffer) 

131 True 

132 >>> is_file_like([1, 2, 3]) 

133 False 

134 """ 

135 if not (hasattr(obj, "read") or hasattr(obj, "write")): 

136 return False 

137 

138 return bool(hasattr(obj, "__iter__")) 

139 

140 

141def is_re(obj) -> TypeGuard[Pattern]: 

142 """ 

143 Check if the object is a regex pattern instance. 

144 

145 Parameters 

146 ---------- 

147 obj : The object to check 

148 

149 Returns 

150 ------- 

151 bool 

152 Whether `obj` is a regex pattern. 

153 

154 Examples 

155 -------- 

156 >>> from pandas.api.types import is_re 

157 >>> import re 

158 >>> is_re(re.compile(".*")) 

159 True 

160 >>> is_re("foo") 

161 False 

162 """ 

163 return isinstance(obj, Pattern) 

164 

165 

166def is_re_compilable(obj) -> bool: 

167 """ 

168 Check if the object can be compiled into a regex pattern instance. 

169 

170 Parameters 

171 ---------- 

172 obj : The object to check 

173 

174 Returns 

175 ------- 

176 bool 

177 Whether `obj` can be compiled as a regex pattern. 

178 

179 Examples 

180 -------- 

181 >>> from pandas.api.types import is_re_compilable 

182 >>> is_re_compilable(".*") 

183 True 

184 >>> is_re_compilable(1) 

185 False 

186 """ 

187 try: 

188 re.compile(obj) 

189 except TypeError: 

190 return False 

191 else: 

192 return True 

193 

194 

195def is_array_like(obj) -> bool: 

196 """ 

197 Check if the object is array-like. 

198 

199 For an object to be considered array-like, it must be list-like and 

200 have a `dtype` attribute. 

201 

202 Parameters 

203 ---------- 

204 obj : The object to check 

205 

206 Returns 

207 ------- 

208 is_array_like : bool 

209 Whether `obj` has array-like properties. 

210 

211 Examples 

212 -------- 

213 >>> is_array_like(np.array([1, 2, 3])) 

214 True 

215 >>> is_array_like(pd.Series(["a", "b"])) 

216 True 

217 >>> is_array_like(pd.Index(["2016-01-01"])) 

218 True 

219 >>> is_array_like([1, 2, 3]) 

220 False 

221 >>> is_array_like(("a", "b")) 

222 False 

223 """ 

224 return is_list_like(obj) and hasattr(obj, "dtype") 

225 

226 

227def is_nested_list_like(obj) -> bool: 

228 """ 

229 Check if the object is list-like, and that all of its elements 

230 are also list-like. 

231 

232 Parameters 

233 ---------- 

234 obj : The object to check 

235 

236 Returns 

237 ------- 

238 is_list_like : bool 

239 Whether `obj` has list-like properties. 

240 

241 Examples 

242 -------- 

243 >>> is_nested_list_like([[1, 2, 3]]) 

244 True 

245 >>> is_nested_list_like([{1, 2, 3}, {1, 2, 3}]) 

246 True 

247 >>> is_nested_list_like(["foo"]) 

248 False 

249 >>> is_nested_list_like([]) 

250 False 

251 >>> is_nested_list_like([[1, 2, 3], 1]) 

252 False 

253 

254 Notes 

255 ----- 

256 This won't reliably detect whether a consumable iterator (e. g. 

257 a generator) is a nested-list-like without consuming the iterator. 

258 To avoid consuming it, we always return False if the outer container 

259 doesn't define `__len__`. 

260 

261 See Also 

262 -------- 

263 is_list_like 

264 """ 

265 return ( 

266 is_list_like(obj) 

267 and hasattr(obj, "__len__") 

268 and len(obj) > 0 

269 and all(is_list_like(item) for item in obj) 

270 ) 

271 

272 

273def is_dict_like(obj) -> bool: 

274 """ 

275 Check if the object is dict-like. 

276 

277 Parameters 

278 ---------- 

279 obj : The object to check 

280 

281 Returns 

282 ------- 

283 bool 

284 Whether `obj` has dict-like properties. 

285 

286 Examples 

287 -------- 

288 >>> from pandas.api.types import is_dict_like 

289 >>> is_dict_like({1: 2}) 

290 True 

291 >>> is_dict_like([1, 2, 3]) 

292 False 

293 >>> is_dict_like(dict) 

294 False 

295 >>> is_dict_like(dict()) 

296 True 

297 """ 

298 dict_like_attrs = ("__getitem__", "keys", "__contains__") 

299 return ( 

300 all(hasattr(obj, attr) for attr in dict_like_attrs) 

301 # [GH 25196] exclude classes 

302 and not isinstance(obj, type) 

303 ) 

304 

305 

306def is_named_tuple(obj) -> bool: 

307 """ 

308 Check if the object is a named tuple. 

309 

310 Parameters 

311 ---------- 

312 obj : The object to check 

313 

314 Returns 

315 ------- 

316 bool 

317 Whether `obj` is a named tuple. 

318 

319 Examples 

320 -------- 

321 >>> from collections import namedtuple 

322 >>> from pandas.api.types import is_named_tuple 

323 >>> Point = namedtuple("Point", ["x", "y"]) 

324 >>> p = Point(1, 2) 

325 >>> 

326 >>> is_named_tuple(p) 

327 True 

328 >>> is_named_tuple((1, 2)) 

329 False 

330 """ 

331 return isinstance(obj, abc.Sequence) and hasattr(obj, "_fields") 

332 

333 

334def is_hashable(obj) -> TypeGuard[Hashable]: 

335 """ 

336 Return True if hash(obj) will succeed, False otherwise. 

337 

338 Some types will pass a test against collections.abc.Hashable but fail when 

339 they are actually hashed with hash(). 

340 

341 Distinguish between these and other types by trying the call to hash() and 

342 seeing if they raise TypeError. 

343 

344 Returns 

345 ------- 

346 bool 

347 

348 Examples 

349 -------- 

350 >>> import collections 

351 >>> from pandas.api.types import is_hashable 

352 >>> a = ([],) 

353 >>> isinstance(a, collections.abc.Hashable) 

354 True 

355 >>> is_hashable(a) 

356 False 

357 """ 

358 # Unfortunately, we can't use isinstance(obj, collections.abc.Hashable), 

359 # which can be faster than calling hash. That is because numpy scalars 

360 # fail this test. 

361 

362 # Reconsider this decision once this numpy bug is fixed: 

363 # https://github.com/numpy/numpy/issues/5562 

364 

365 try: 

366 hash(obj) 

367 except TypeError: 

368 return False 

369 else: 

370 return True 

371 

372 

373def is_sequence(obj) -> bool: 

374 """ 

375 Check if the object is a sequence of objects. 

376 String types are not included as sequences here. 

377 

378 Parameters 

379 ---------- 

380 obj : The object to check 

381 

382 Returns 

383 ------- 

384 is_sequence : bool 

385 Whether `obj` is a sequence of objects. 

386 

387 Examples 

388 -------- 

389 >>> l = [1, 2, 3] 

390 >>> 

391 >>> is_sequence(l) 

392 True 

393 >>> is_sequence(iter(l)) 

394 False 

395 """ 

396 try: 

397 iter(obj) # Can iterate over it. 

398 len(obj) # Has a length associated with it. 

399 return not isinstance(obj, (str, bytes)) 

400 except (TypeError, AttributeError): 

401 return False 

402 

403 

404def is_dataclass(item) -> bool: 

405 """ 

406 Checks if the object is a data-class instance 

407 

408 Parameters 

409 ---------- 

410 item : object 

411 

412 Returns 

413 -------- 

414 is_dataclass : bool 

415 True if the item is an instance of a data-class, 

416 will return false if you pass the data class itself 

417 

418 Examples 

419 -------- 

420 >>> from dataclasses import dataclass 

421 >>> @dataclass 

422 ... class Point: 

423 ... x: int 

424 ... y: int 

425 

426 >>> is_dataclass(Point) 

427 False 

428 >>> is_dataclass(Point(0,2)) 

429 True 

430 

431 """ 

432 try: 

433 import dataclasses 

434 

435 return dataclasses.is_dataclass(item) and not isinstance(item, type) 

436 except ImportError: 

437 return False