Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/numpy/lib/utils.py: 9%

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

461 statements  

1import os 

2import sys 

3import textwrap 

4import types 

5import re 

6import warnings 

7import functools 

8 

9from numpy.core.numerictypes import issubclass_, issubsctype, issubdtype 

10from numpy.core.overrides import set_module 

11from numpy.core import ndarray, ufunc, asarray 

12import numpy as np 

13 

14__all__ = [ 

15 'issubclass_', 'issubsctype', 'issubdtype', 'deprecate', 

16 'deprecate_with_doc', 'get_include', 'info', 'source', 'who', 

17 'lookfor', 'byte_bounds', 'safe_eval', 'show_runtime' 

18 ] 

19 

20 

21def show_runtime(): 

22 """ 

23 Print information about various resources in the system 

24 including available intrinsic support and BLAS/LAPACK library 

25 in use 

26 

27 See Also 

28 -------- 

29 show_config : Show libraries in the system on which NumPy was built. 

30 

31 Notes 

32 ----- 

33 1. Information is derived with the help of `threadpoolctl <https://pypi.org/project/threadpoolctl/>`_ 

34 library. 

35 2. SIMD related information is derived from ``__cpu_features__``, 

36 ``__cpu_baseline__`` and ``__cpu_dispatch__`` 

37 

38 Examples 

39 -------- 

40 >>> import numpy as np 

41 >>> np.show_runtime() 

42 [{'simd_extensions': {'baseline': ['SSE', 'SSE2', 'SSE3'], 

43 'found': ['SSSE3', 

44 'SSE41', 

45 'POPCNT', 

46 'SSE42', 

47 'AVX', 

48 'F16C', 

49 'FMA3', 

50 'AVX2'], 

51 'not_found': ['AVX512F', 

52 'AVX512CD', 

53 'AVX512_KNL', 

54 'AVX512_KNM', 

55 'AVX512_SKX', 

56 'AVX512_CLX', 

57 'AVX512_CNL', 

58 'AVX512_ICL']}}, 

59 {'architecture': 'Zen', 

60 'filepath': '/usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.20.so', 

61 'internal_api': 'openblas', 

62 'num_threads': 12, 

63 'prefix': 'libopenblas', 

64 'threading_layer': 'pthreads', 

65 'user_api': 'blas', 

66 'version': '0.3.20'}] 

67 """ 

68 from numpy.core._multiarray_umath import ( 

69 __cpu_features__, __cpu_baseline__, __cpu_dispatch__ 

70 ) 

71 from pprint import pprint 

72 config_found = [] 

73 features_found, features_not_found = [], [] 

74 for feature in __cpu_dispatch__: 

75 if __cpu_features__[feature]: 

76 features_found.append(feature) 

77 else: 

78 features_not_found.append(feature) 

79 config_found.append({ 

80 "simd_extensions": { 

81 "baseline": __cpu_baseline__, 

82 "found": features_found, 

83 "not_found": features_not_found 

84 } 

85 }) 

86 try: 

87 from threadpoolctl import threadpool_info 

88 config_found.extend(threadpool_info()) 

89 except ImportError: 

90 print("WARNING: `threadpoolctl` not found in system!" 

91 " Install it by `pip install threadpoolctl`." 

92 " Once installed, try `np.show_runtime` again" 

93 " for more detailed build information") 

94 pprint(config_found) 

95 

96 

97def get_include(): 

98 """ 

99 Return the directory that contains the NumPy \\*.h header files. 

100 

101 Extension modules that need to compile against NumPy should use this 

102 function to locate the appropriate include directory. 

103 

104 Notes 

105 ----- 

106 When using ``distutils``, for example in ``setup.py``:: 

107 

108 import numpy as np 

109 ... 

110 Extension('extension_name', ... 

111 include_dirs=[np.get_include()]) 

112 ... 

113 

114 """ 

115 import numpy 

116 if numpy.show_config is None: 

117 # running from numpy source directory 

118 d = os.path.join(os.path.dirname(numpy.__file__), 'core', 'include') 

119 else: 

120 # using installed numpy core headers 

121 import numpy.core as core 

122 d = os.path.join(os.path.dirname(core.__file__), 'include') 

123 return d 

124 

125 

126class _Deprecate: 

127 """ 

128 Decorator class to deprecate old functions. 

129 

130 Refer to `deprecate` for details. 

131 

132 See Also 

133 -------- 

134 deprecate 

135 

136 """ 

137 

138 def __init__(self, old_name=None, new_name=None, message=None): 

139 self.old_name = old_name 

140 self.new_name = new_name 

141 self.message = message 

142 

143 def __call__(self, func, *args, **kwargs): 

144 """ 

145 Decorator call. Refer to ``decorate``. 

146 

147 """ 

148 old_name = self.old_name 

149 new_name = self.new_name 

150 message = self.message 

151 

152 if old_name is None: 

153 old_name = func.__name__ 

154 if new_name is None: 

155 depdoc = "`%s` is deprecated!" % old_name 

156 else: 

157 depdoc = "`%s` is deprecated, use `%s` instead!" % \ 

158 (old_name, new_name) 

159 

160 if message is not None: 

161 depdoc += "\n" + message 

162 

163 @functools.wraps(func) 

164 def newfunc(*args, **kwds): 

165 warnings.warn(depdoc, DeprecationWarning, stacklevel=2) 

166 return func(*args, **kwds) 

167 

168 newfunc.__name__ = old_name 

169 doc = func.__doc__ 

170 if doc is None: 

171 doc = depdoc 

172 else: 

173 lines = doc.expandtabs().split('\n') 

174 indent = _get_indent(lines[1:]) 

175 if lines[0].lstrip(): 

176 # Indent the original first line to let inspect.cleandoc() 

177 # dedent the docstring despite the deprecation notice. 

178 doc = indent * ' ' + doc 

179 else: 

180 # Remove the same leading blank lines as cleandoc() would. 

181 skip = len(lines[0]) + 1 

182 for line in lines[1:]: 

183 if len(line) > indent: 

184 break 

185 skip += len(line) + 1 

186 doc = doc[skip:] 

187 depdoc = textwrap.indent(depdoc, ' ' * indent) 

188 doc = '\n\n'.join([depdoc, doc]) 

189 newfunc.__doc__ = doc 

190 

191 return newfunc 

192 

193 

194def _get_indent(lines): 

195 """ 

196 Determines the leading whitespace that could be removed from all the lines. 

197 """ 

198 indent = sys.maxsize 

199 for line in lines: 

200 content = len(line.lstrip()) 

201 if content: 

202 indent = min(indent, len(line) - content) 

203 if indent == sys.maxsize: 

204 indent = 0 

205 return indent 

206 

207 

208def deprecate(*args, **kwargs): 

209 """ 

210 Issues a DeprecationWarning, adds warning to `old_name`'s 

211 docstring, rebinds ``old_name.__name__`` and returns the new 

212 function object. 

213 

214 This function may also be used as a decorator. 

215 

216 Parameters 

217 ---------- 

218 func : function 

219 The function to be deprecated. 

220 old_name : str, optional 

221 The name of the function to be deprecated. Default is None, in 

222 which case the name of `func` is used. 

223 new_name : str, optional 

224 The new name for the function. Default is None, in which case the 

225 deprecation message is that `old_name` is deprecated. If given, the 

226 deprecation message is that `old_name` is deprecated and `new_name` 

227 should be used instead. 

228 message : str, optional 

229 Additional explanation of the deprecation. Displayed in the 

230 docstring after the warning. 

231 

232 Returns 

233 ------- 

234 old_func : function 

235 The deprecated function. 

236 

237 Examples 

238 -------- 

239 Note that ``olduint`` returns a value after printing Deprecation 

240 Warning: 

241 

242 >>> olduint = np.deprecate(np.uint) 

243 DeprecationWarning: `uint64` is deprecated! # may vary 

244 >>> olduint(6) 

245 6 

246 

247 """ 

248 # Deprecate may be run as a function or as a decorator 

249 # If run as a function, we initialise the decorator class 

250 # and execute its __call__ method. 

251 

252 if args: 

253 fn = args[0] 

254 args = args[1:] 

255 

256 return _Deprecate(*args, **kwargs)(fn) 

257 else: 

258 return _Deprecate(*args, **kwargs) 

259 

260 

261def deprecate_with_doc(msg): 

262 """ 

263 Deprecates a function and includes the deprecation in its docstring. 

264 

265 This function is used as a decorator. It returns an object that can be 

266 used to issue a DeprecationWarning, by passing the to-be decorated 

267 function as argument, this adds warning to the to-be decorated function's 

268 docstring and returns the new function object. 

269 

270 See Also 

271 -------- 

272 deprecate : Decorate a function such that it issues a `DeprecationWarning` 

273 

274 Parameters 

275 ---------- 

276 msg : str 

277 Additional explanation of the deprecation. Displayed in the 

278 docstring after the warning. 

279 

280 Returns 

281 ------- 

282 obj : object 

283 

284 """ 

285 return _Deprecate(message=msg) 

286 

287 

288#-------------------------------------------- 

289# Determine if two arrays can share memory 

290#-------------------------------------------- 

291 

292def byte_bounds(a): 

293 """ 

294 Returns pointers to the end-points of an array. 

295 

296 Parameters 

297 ---------- 

298 a : ndarray 

299 Input array. It must conform to the Python-side of the array 

300 interface. 

301 

302 Returns 

303 ------- 

304 (low, high) : tuple of 2 integers 

305 The first integer is the first byte of the array, the second 

306 integer is just past the last byte of the array. If `a` is not 

307 contiguous it will not use every byte between the (`low`, `high`) 

308 values. 

309 

310 Examples 

311 -------- 

312 >>> I = np.eye(2, dtype='f'); I.dtype 

313 dtype('float32') 

314 >>> low, high = np.byte_bounds(I) 

315 >>> high - low == I.size*I.itemsize 

316 True 

317 >>> I = np.eye(2); I.dtype 

318 dtype('float64') 

319 >>> low, high = np.byte_bounds(I) 

320 >>> high - low == I.size*I.itemsize 

321 True 

322 

323 """ 

324 ai = a.__array_interface__ 

325 a_data = ai['data'][0] 

326 astrides = ai['strides'] 

327 ashape = ai['shape'] 

328 bytes_a = asarray(a).dtype.itemsize 

329 

330 a_low = a_high = a_data 

331 if astrides is None: 

332 # contiguous case 

333 a_high += a.size * bytes_a 

334 else: 

335 for shape, stride in zip(ashape, astrides): 

336 if stride < 0: 

337 a_low += (shape-1)*stride 

338 else: 

339 a_high += (shape-1)*stride 

340 a_high += bytes_a 

341 return a_low, a_high 

342 

343 

344#----------------------------------------------------------------------------- 

345# Function for output and information on the variables used. 

346#----------------------------------------------------------------------------- 

347 

348 

349def who(vardict=None): 

350 """ 

351 Print the NumPy arrays in the given dictionary. 

352 

353 If there is no dictionary passed in or `vardict` is None then returns 

354 NumPy arrays in the globals() dictionary (all NumPy arrays in the 

355 namespace). 

356 

357 Parameters 

358 ---------- 

359 vardict : dict, optional 

360 A dictionary possibly containing ndarrays. Default is globals(). 

361 

362 Returns 

363 ------- 

364 out : None 

365 Returns 'None'. 

366 

367 Notes 

368 ----- 

369 Prints out the name, shape, bytes and type of all of the ndarrays 

370 present in `vardict`. 

371 

372 Examples 

373 -------- 

374 >>> a = np.arange(10) 

375 >>> b = np.ones(20) 

376 >>> np.who() 

377 Name Shape Bytes Type 

378 =========================================================== 

379 a 10 80 int64 

380 b 20 160 float64 

381 Upper bound on total bytes = 240 

382 

383 >>> d = {'x': np.arange(2.0), 'y': np.arange(3.0), 'txt': 'Some str', 

384 ... 'idx':5} 

385 >>> np.who(d) 

386 Name Shape Bytes Type 

387 =========================================================== 

388 x 2 16 float64 

389 y 3 24 float64 

390 Upper bound on total bytes = 40 

391 

392 """ 

393 if vardict is None: 

394 frame = sys._getframe().f_back 

395 vardict = frame.f_globals 

396 sta = [] 

397 cache = {} 

398 for name in vardict.keys(): 

399 if isinstance(vardict[name], ndarray): 

400 var = vardict[name] 

401 idv = id(var) 

402 if idv in cache.keys(): 

403 namestr = name + " (%s)" % cache[idv] 

404 original = 0 

405 else: 

406 cache[idv] = name 

407 namestr = name 

408 original = 1 

409 shapestr = " x ".join(map(str, var.shape)) 

410 bytestr = str(var.nbytes) 

411 sta.append([namestr, shapestr, bytestr, var.dtype.name, 

412 original]) 

413 

414 maxname = 0 

415 maxshape = 0 

416 maxbyte = 0 

417 totalbytes = 0 

418 for val in sta: 

419 if maxname < len(val[0]): 

420 maxname = len(val[0]) 

421 if maxshape < len(val[1]): 

422 maxshape = len(val[1]) 

423 if maxbyte < len(val[2]): 

424 maxbyte = len(val[2]) 

425 if val[4]: 

426 totalbytes += int(val[2]) 

427 

428 if len(sta) > 0: 

429 sp1 = max(10, maxname) 

430 sp2 = max(10, maxshape) 

431 sp3 = max(10, maxbyte) 

432 prval = "Name %s Shape %s Bytes %s Type" % (sp1*' ', sp2*' ', sp3*' ') 

433 print(prval + "\n" + "="*(len(prval)+5) + "\n") 

434 

435 for val in sta: 

436 print("%s %s %s %s %s %s %s" % (val[0], ' '*(sp1-len(val[0])+4), 

437 val[1], ' '*(sp2-len(val[1])+5), 

438 val[2], ' '*(sp3-len(val[2])+5), 

439 val[3])) 

440 print("\nUpper bound on total bytes = %d" % totalbytes) 

441 return 

442 

443#----------------------------------------------------------------------------- 

444 

445 

446# NOTE: pydoc defines a help function which works similarly to this 

447# except it uses a pager to take over the screen. 

448 

449# combine name and arguments and split to multiple lines of width 

450# characters. End lines on a comma and begin argument list indented with 

451# the rest of the arguments. 

452def _split_line(name, arguments, width): 

453 firstwidth = len(name) 

454 k = firstwidth 

455 newstr = name 

456 sepstr = ", " 

457 arglist = arguments.split(sepstr) 

458 for argument in arglist: 

459 if k == firstwidth: 

460 addstr = "" 

461 else: 

462 addstr = sepstr 

463 k = k + len(argument) + len(addstr) 

464 if k > width: 

465 k = firstwidth + 1 + len(argument) 

466 newstr = newstr + ",\n" + " "*(firstwidth+2) + argument 

467 else: 

468 newstr = newstr + addstr + argument 

469 return newstr 

470 

471_namedict = None 

472_dictlist = None 

473 

474# Traverse all module directories underneath globals 

475# to see if something is defined 

476def _makenamedict(module='numpy'): 

477 module = __import__(module, globals(), locals(), []) 

478 thedict = {module.__name__:module.__dict__} 

479 dictlist = [module.__name__] 

480 totraverse = [module.__dict__] 

481 while True: 

482 if len(totraverse) == 0: 

483 break 

484 thisdict = totraverse.pop(0) 

485 for x in thisdict.keys(): 

486 if isinstance(thisdict[x], types.ModuleType): 

487 modname = thisdict[x].__name__ 

488 if modname not in dictlist: 

489 moddict = thisdict[x].__dict__ 

490 dictlist.append(modname) 

491 totraverse.append(moddict) 

492 thedict[modname] = moddict 

493 return thedict, dictlist 

494 

495 

496def _info(obj, output=None): 

497 """Provide information about ndarray obj. 

498 

499 Parameters 

500 ---------- 

501 obj : ndarray 

502 Must be ndarray, not checked. 

503 output 

504 Where printed output goes. 

505 

506 Notes 

507 ----- 

508 Copied over from the numarray module prior to its removal. 

509 Adapted somewhat as only numpy is an option now. 

510 

511 Called by info. 

512 

513 """ 

514 extra = "" 

515 tic = "" 

516 bp = lambda x: x 

517 cls = getattr(obj, '__class__', type(obj)) 

518 nm = getattr(cls, '__name__', cls) 

519 strides = obj.strides 

520 endian = obj.dtype.byteorder 

521 

522 if output is None: 

523 output = sys.stdout 

524 

525 print("class: ", nm, file=output) 

526 print("shape: ", obj.shape, file=output) 

527 print("strides: ", strides, file=output) 

528 print("itemsize: ", obj.itemsize, file=output) 

529 print("aligned: ", bp(obj.flags.aligned), file=output) 

530 print("contiguous: ", bp(obj.flags.contiguous), file=output) 

531 print("fortran: ", obj.flags.fortran, file=output) 

532 print( 

533 "data pointer: %s%s" % (hex(obj.ctypes._as_parameter_.value), extra), 

534 file=output 

535 ) 

536 print("byteorder: ", end=' ', file=output) 

537 if endian in ['|', '=']: 

538 print("%s%s%s" % (tic, sys.byteorder, tic), file=output) 

539 byteswap = False 

540 elif endian == '>': 

541 print("%sbig%s" % (tic, tic), file=output) 

542 byteswap = sys.byteorder != "big" 

543 else: 

544 print("%slittle%s" % (tic, tic), file=output) 

545 byteswap = sys.byteorder != "little" 

546 print("byteswap: ", bp(byteswap), file=output) 

547 print("type: %s" % obj.dtype, file=output) 

548 

549 

550@set_module('numpy') 

551def info(object=None, maxwidth=76, output=None, toplevel='numpy'): 

552 """ 

553 Get help information for a function, class, or module. 

554 

555 Parameters 

556 ---------- 

557 object : object or str, optional 

558 Input object or name to get information about. If `object` is a 

559 numpy object, its docstring is given. If it is a string, available 

560 modules are searched for matching objects. If None, information 

561 about `info` itself is returned. 

562 maxwidth : int, optional 

563 Printing width. 

564 output : file like object, optional 

565 File like object that the output is written to, default is 

566 ``None``, in which case ``sys.stdout`` will be used. 

567 The object has to be opened in 'w' or 'a' mode. 

568 toplevel : str, optional 

569 Start search at this level. 

570 

571 See Also 

572 -------- 

573 source, lookfor 

574 

575 Notes 

576 ----- 

577 When used interactively with an object, ``np.info(obj)`` is equivalent 

578 to ``help(obj)`` on the Python prompt or ``obj?`` on the IPython 

579 prompt. 

580 

581 Examples 

582 -------- 

583 >>> np.info(np.polyval) # doctest: +SKIP 

584 polyval(p, x) 

585 Evaluate the polynomial p at x. 

586 ... 

587 

588 When using a string for `object` it is possible to get multiple results. 

589 

590 >>> np.info('fft') # doctest: +SKIP 

591 *** Found in numpy *** 

592 Core FFT routines 

593 ... 

594 *** Found in numpy.fft *** 

595 fft(a, n=None, axis=-1) 

596 ... 

597 *** Repeat reference found in numpy.fft.fftpack *** 

598 *** Total of 3 references found. *** 

599 

600 """ 

601 global _namedict, _dictlist 

602 # Local import to speed up numpy's import time. 

603 import pydoc 

604 import inspect 

605 

606 if (hasattr(object, '_ppimport_importer') or 

607 hasattr(object, '_ppimport_module')): 

608 object = object._ppimport_module 

609 elif hasattr(object, '_ppimport_attr'): 

610 object = object._ppimport_attr 

611 

612 if output is None: 

613 output = sys.stdout 

614 

615 if object is None: 

616 info(info) 

617 elif isinstance(object, ndarray): 

618 _info(object, output=output) 

619 elif isinstance(object, str): 

620 if _namedict is None: 

621 _namedict, _dictlist = _makenamedict(toplevel) 

622 numfound = 0 

623 objlist = [] 

624 for namestr in _dictlist: 

625 try: 

626 obj = _namedict[namestr][object] 

627 if id(obj) in objlist: 

628 print("\n " 

629 "*** Repeat reference found in %s *** " % namestr, 

630 file=output 

631 ) 

632 else: 

633 objlist.append(id(obj)) 

634 print(" *** Found in %s ***" % namestr, file=output) 

635 info(obj) 

636 print("-"*maxwidth, file=output) 

637 numfound += 1 

638 except KeyError: 

639 pass 

640 if numfound == 0: 

641 print("Help for %s not found." % object, file=output) 

642 else: 

643 print("\n " 

644 "*** Total of %d references found. ***" % numfound, 

645 file=output 

646 ) 

647 

648 elif inspect.isfunction(object) or inspect.ismethod(object): 

649 name = object.__name__ 

650 try: 

651 arguments = str(inspect.signature(object)) 

652 except Exception: 

653 arguments = "()" 

654 

655 if len(name+arguments) > maxwidth: 

656 argstr = _split_line(name, arguments, maxwidth) 

657 else: 

658 argstr = name + arguments 

659 

660 print(" " + argstr + "\n", file=output) 

661 print(inspect.getdoc(object), file=output) 

662 

663 elif inspect.isclass(object): 

664 name = object.__name__ 

665 try: 

666 arguments = str(inspect.signature(object)) 

667 except Exception: 

668 arguments = "()" 

669 

670 if len(name+arguments) > maxwidth: 

671 argstr = _split_line(name, arguments, maxwidth) 

672 else: 

673 argstr = name + arguments 

674 

675 print(" " + argstr + "\n", file=output) 

676 doc1 = inspect.getdoc(object) 

677 if doc1 is None: 

678 if hasattr(object, '__init__'): 

679 print(inspect.getdoc(object.__init__), file=output) 

680 else: 

681 print(inspect.getdoc(object), file=output) 

682 

683 methods = pydoc.allmethods(object) 

684 

685 public_methods = [meth for meth in methods if meth[0] != '_'] 

686 if public_methods: 

687 print("\n\nMethods:\n", file=output) 

688 for meth in public_methods: 

689 thisobj = getattr(object, meth, None) 

690 if thisobj is not None: 

691 methstr, other = pydoc.splitdoc( 

692 inspect.getdoc(thisobj) or "None" 

693 ) 

694 print(" %s -- %s" % (meth, methstr), file=output) 

695 

696 elif hasattr(object, '__doc__'): 

697 print(inspect.getdoc(object), file=output) 

698 

699 

700@set_module('numpy') 

701def source(object, output=sys.stdout): 

702 """ 

703 Print or write to a file the source code for a NumPy object. 

704 

705 The source code is only returned for objects written in Python. Many 

706 functions and classes are defined in C and will therefore not return 

707 useful information. 

708 

709 Parameters 

710 ---------- 

711 object : numpy object 

712 Input object. This can be any object (function, class, module, 

713 ...). 

714 output : file object, optional 

715 If `output` not supplied then source code is printed to screen 

716 (sys.stdout). File object must be created with either write 'w' or 

717 append 'a' modes. 

718 

719 See Also 

720 -------- 

721 lookfor, info 

722 

723 Examples 

724 -------- 

725 >>> np.source(np.interp) #doctest: +SKIP 

726 In file: /usr/lib/python2.6/dist-packages/numpy/lib/function_base.py 

727 def interp(x, xp, fp, left=None, right=None): 

728 \"\"\".... (full docstring printed)\"\"\" 

729 if isinstance(x, (float, int, number)): 

730 return compiled_interp([x], xp, fp, left, right).item() 

731 else: 

732 return compiled_interp(x, xp, fp, left, right) 

733 

734 The source code is only returned for objects written in Python. 

735 

736 >>> np.source(np.array) #doctest: +SKIP 

737 Not available for this object. 

738 

739 """ 

740 # Local import to speed up numpy's import time. 

741 import inspect 

742 try: 

743 print("In file: %s\n" % inspect.getsourcefile(object), file=output) 

744 print(inspect.getsource(object), file=output) 

745 except Exception: 

746 print("Not available for this object.", file=output) 

747 

748 

749# Cache for lookfor: {id(module): {name: (docstring, kind, index), ...}...} 

750# where kind: "func", "class", "module", "object" 

751# and index: index in breadth-first namespace traversal 

752_lookfor_caches = {} 

753 

754# regexp whose match indicates that the string may contain a function 

755# signature 

756_function_signature_re = re.compile(r"[a-z0-9_]+\(.*[,=].*\)", re.I) 

757 

758 

759@set_module('numpy') 

760def lookfor(what, module=None, import_modules=True, regenerate=False, 

761 output=None): 

762 """ 

763 Do a keyword search on docstrings. 

764 

765 A list of objects that matched the search is displayed, 

766 sorted by relevance. All given keywords need to be found in the 

767 docstring for it to be returned as a result, but the order does 

768 not matter. 

769 

770 Parameters 

771 ---------- 

772 what : str 

773 String containing words to look for. 

774 module : str or list, optional 

775 Name of module(s) whose docstrings to go through. 

776 import_modules : bool, optional 

777 Whether to import sub-modules in packages. Default is True. 

778 regenerate : bool, optional 

779 Whether to re-generate the docstring cache. Default is False. 

780 output : file-like, optional 

781 File-like object to write the output to. If omitted, use a pager. 

782 

783 See Also 

784 -------- 

785 source, info 

786 

787 Notes 

788 ----- 

789 Relevance is determined only roughly, by checking if the keywords occur 

790 in the function name, at the start of a docstring, etc. 

791 

792 Examples 

793 -------- 

794 >>> np.lookfor('binary representation') # doctest: +SKIP 

795 Search results for 'binary representation' 

796 ------------------------------------------ 

797 numpy.binary_repr 

798 Return the binary representation of the input number as a string. 

799 numpy.core.setup_common.long_double_representation 

800 Given a binary dump as given by GNU od -b, look for long double 

801 numpy.base_repr 

802 Return a string representation of a number in the given base system. 

803 ... 

804 

805 """ 

806 import pydoc 

807 

808 # Cache 

809 cache = _lookfor_generate_cache(module, import_modules, regenerate) 

810 

811 # Search 

812 # XXX: maybe using a real stemming search engine would be better? 

813 found = [] 

814 whats = str(what).lower().split() 

815 if not whats: 

816 return 

817 

818 for name, (docstring, kind, index) in cache.items(): 

819 if kind in ('module', 'object'): 

820 # don't show modules or objects 

821 continue 

822 doc = docstring.lower() 

823 if all(w in doc for w in whats): 

824 found.append(name) 

825 

826 # Relevance sort 

827 # XXX: this is full Harrison-Stetson heuristics now, 

828 # XXX: it probably could be improved 

829 

830 kind_relevance = {'func': 1000, 'class': 1000, 

831 'module': -1000, 'object': -1000} 

832 

833 def relevance(name, docstr, kind, index): 

834 r = 0 

835 # do the keywords occur within the start of the docstring? 

836 first_doc = "\n".join(docstr.lower().strip().split("\n")[:3]) 

837 r += sum([200 for w in whats if w in first_doc]) 

838 # do the keywords occur in the function name? 

839 r += sum([30 for w in whats if w in name]) 

840 # is the full name long? 

841 r += -len(name) * 5 

842 # is the object of bad type? 

843 r += kind_relevance.get(kind, -1000) 

844 # is the object deep in namespace hierarchy? 

845 r += -name.count('.') * 10 

846 r += max(-index / 100, -100) 

847 return r 

848 

849 def relevance_value(a): 

850 return relevance(a, *cache[a]) 

851 found.sort(key=relevance_value) 

852 

853 # Pretty-print 

854 s = "Search results for '%s'" % (' '.join(whats)) 

855 help_text = [s, "-"*len(s)] 

856 for name in found[::-1]: 

857 doc, kind, ix = cache[name] 

858 

859 doclines = [line.strip() for line in doc.strip().split("\n") 

860 if line.strip()] 

861 

862 # find a suitable short description 

863 try: 

864 first_doc = doclines[0].strip() 

865 if _function_signature_re.search(first_doc): 

866 first_doc = doclines[1].strip() 

867 except IndexError: 

868 first_doc = "" 

869 help_text.append("%s\n %s" % (name, first_doc)) 

870 

871 if not found: 

872 help_text.append("Nothing found.") 

873 

874 # Output 

875 if output is not None: 

876 output.write("\n".join(help_text)) 

877 elif len(help_text) > 10: 

878 pager = pydoc.getpager() 

879 pager("\n".join(help_text)) 

880 else: 

881 print("\n".join(help_text)) 

882 

883def _lookfor_generate_cache(module, import_modules, regenerate): 

884 """ 

885 Generate docstring cache for given module. 

886 

887 Parameters 

888 ---------- 

889 module : str, None, module 

890 Module for which to generate docstring cache 

891 import_modules : bool 

892 Whether to import sub-modules in packages. 

893 regenerate : bool 

894 Re-generate the docstring cache 

895 

896 Returns 

897 ------- 

898 cache : dict {obj_full_name: (docstring, kind, index), ...} 

899 Docstring cache for the module, either cached one (regenerate=False) 

900 or newly generated. 

901 

902 """ 

903 # Local import to speed up numpy's import time. 

904 import inspect 

905 

906 from io import StringIO 

907 

908 if module is None: 

909 module = "numpy" 

910 

911 if isinstance(module, str): 

912 try: 

913 __import__(module) 

914 except ImportError: 

915 return {} 

916 module = sys.modules[module] 

917 elif isinstance(module, list) or isinstance(module, tuple): 

918 cache = {} 

919 for mod in module: 

920 cache.update(_lookfor_generate_cache(mod, import_modules, 

921 regenerate)) 

922 return cache 

923 

924 if id(module) in _lookfor_caches and not regenerate: 

925 return _lookfor_caches[id(module)] 

926 

927 # walk items and collect docstrings 

928 cache = {} 

929 _lookfor_caches[id(module)] = cache 

930 seen = {} 

931 index = 0 

932 stack = [(module.__name__, module)] 

933 while stack: 

934 name, item = stack.pop(0) 

935 if id(item) in seen: 

936 continue 

937 seen[id(item)] = True 

938 

939 index += 1 

940 kind = "object" 

941 

942 if inspect.ismodule(item): 

943 kind = "module" 

944 try: 

945 _all = item.__all__ 

946 except AttributeError: 

947 _all = None 

948 

949 # import sub-packages 

950 if import_modules and hasattr(item, '__path__'): 

951 for pth in item.__path__: 

952 for mod_path in os.listdir(pth): 

953 this_py = os.path.join(pth, mod_path) 

954 init_py = os.path.join(pth, mod_path, '__init__.py') 

955 if (os.path.isfile(this_py) and 

956 mod_path.endswith('.py')): 

957 to_import = mod_path[:-3] 

958 elif os.path.isfile(init_py): 

959 to_import = mod_path 

960 else: 

961 continue 

962 if to_import == '__init__': 

963 continue 

964 

965 try: 

966 old_stdout = sys.stdout 

967 old_stderr = sys.stderr 

968 try: 

969 sys.stdout = StringIO() 

970 sys.stderr = StringIO() 

971 __import__("%s.%s" % (name, to_import)) 

972 finally: 

973 sys.stdout = old_stdout 

974 sys.stderr = old_stderr 

975 except KeyboardInterrupt: 

976 # Assume keyboard interrupt came from a user 

977 raise 

978 except BaseException: 

979 # Ignore also SystemExit and pytests.importorskip 

980 # `Skipped` (these are BaseExceptions; gh-22345) 

981 continue 

982 

983 for n, v in _getmembers(item): 

984 try: 

985 item_name = getattr(v, '__name__', "%s.%s" % (name, n)) 

986 mod_name = getattr(v, '__module__', None) 

987 except NameError: 

988 # ref. SWIG's global cvars 

989 # NameError: Unknown C global variable 

990 item_name = "%s.%s" % (name, n) 

991 mod_name = None 

992 if '.' not in item_name and mod_name: 

993 item_name = "%s.%s" % (mod_name, item_name) 

994 

995 if not item_name.startswith(name + '.'): 

996 # don't crawl "foreign" objects 

997 if isinstance(v, ufunc): 

998 # ... unless they are ufuncs 

999 pass 

1000 else: 

1001 continue 

1002 elif not (inspect.ismodule(v) or _all is None or n in _all): 

1003 continue 

1004 stack.append(("%s.%s" % (name, n), v)) 

1005 elif inspect.isclass(item): 

1006 kind = "class" 

1007 for n, v in _getmembers(item): 

1008 stack.append(("%s.%s" % (name, n), v)) 

1009 elif hasattr(item, "__call__"): 

1010 kind = "func" 

1011 

1012 try: 

1013 doc = inspect.getdoc(item) 

1014 except NameError: 

1015 # ref SWIG's NameError: Unknown C global variable 

1016 doc = None 

1017 if doc is not None: 

1018 cache[name] = (doc, kind, index) 

1019 

1020 return cache 

1021 

1022def _getmembers(item): 

1023 import inspect 

1024 try: 

1025 members = inspect.getmembers(item) 

1026 except Exception: 

1027 members = [(x, getattr(item, x)) for x in dir(item) 

1028 if hasattr(item, x)] 

1029 return members 

1030 

1031 

1032def safe_eval(source): 

1033 """ 

1034 Protected string evaluation. 

1035 

1036 Evaluate a string containing a Python literal expression without 

1037 allowing the execution of arbitrary non-literal code. 

1038 

1039 .. warning:: 

1040 

1041 This function is identical to :py:meth:`ast.literal_eval` and 

1042 has the same security implications. It may not always be safe 

1043 to evaluate large input strings. 

1044 

1045 Parameters 

1046 ---------- 

1047 source : str 

1048 The string to evaluate. 

1049 

1050 Returns 

1051 ------- 

1052 obj : object 

1053 The result of evaluating `source`. 

1054 

1055 Raises 

1056 ------ 

1057 SyntaxError 

1058 If the code has invalid Python syntax, or if it contains 

1059 non-literal code. 

1060 

1061 Examples 

1062 -------- 

1063 >>> np.safe_eval('1') 

1064 1 

1065 >>> np.safe_eval('[1, 2, 3]') 

1066 [1, 2, 3] 

1067 >>> np.safe_eval('{"foo": ("bar", 10.0)}') 

1068 {'foo': ('bar', 10.0)} 

1069 

1070 >>> np.safe_eval('import os') 

1071 Traceback (most recent call last): 

1072 ... 

1073 SyntaxError: invalid syntax 

1074 

1075 >>> np.safe_eval('open("/home/user/.ssh/id_dsa").read()') 

1076 Traceback (most recent call last): 

1077 ... 

1078 ValueError: malformed node or string: <_ast.Call object at 0x...> 

1079 

1080 """ 

1081 # Local import to speed up numpy's import time. 

1082 import ast 

1083 return ast.literal_eval(source) 

1084 

1085 

1086def _median_nancheck(data, result, axis): 

1087 """ 

1088 Utility function to check median result from data for NaN values at the end 

1089 and return NaN in that case. Input result can also be a MaskedArray. 

1090 

1091 Parameters 

1092 ---------- 

1093 data : array 

1094 Sorted input data to median function 

1095 result : Array or MaskedArray 

1096 Result of median function. 

1097 axis : int 

1098 Axis along which the median was computed. 

1099 

1100 Returns 

1101 ------- 

1102 result : scalar or ndarray 

1103 Median or NaN in axes which contained NaN in the input. If the input 

1104 was an array, NaN will be inserted in-place. If a scalar, either the 

1105 input itself or a scalar NaN. 

1106 """ 

1107 if data.size == 0: 

1108 return result 

1109 n = np.isnan(data.take(-1, axis=axis)) 

1110 # masked NaN values are ok 

1111 if np.ma.isMaskedArray(n): 

1112 n = n.filled(False) 

1113 if np.count_nonzero(n.ravel()) > 0: 

1114 # Without given output, it is possible that the current result is a 

1115 # numpy scalar, which is not writeable. If so, just return nan. 

1116 if isinstance(result, np.generic): 

1117 return data.dtype.type(np.nan) 

1118 

1119 result[n] = np.nan 

1120 return result 

1121 

1122def _opt_info(): 

1123 """ 

1124 Returns a string contains the supported CPU features by the current build. 

1125 

1126 The string format can be explained as follows: 

1127 - dispatched features that are supported by the running machine 

1128 end with `*`. 

1129 - dispatched features that are "not" supported by the running machine 

1130 end with `?`. 

1131 - remained features are representing the baseline. 

1132 """ 

1133 from numpy.core._multiarray_umath import ( 

1134 __cpu_features__, __cpu_baseline__, __cpu_dispatch__ 

1135 ) 

1136 

1137 if len(__cpu_baseline__) == 0 and len(__cpu_dispatch__) == 0: 

1138 return '' 

1139 

1140 enabled_features = ' '.join(__cpu_baseline__) 

1141 for feature in __cpu_dispatch__: 

1142 if __cpu_features__[feature]: 

1143 enabled_features += f" {feature}*" 

1144 else: 

1145 enabled_features += f" {feature}?" 

1146 

1147 return enabled_features 

1148#-----------------------------------------------------------------------------