1 import os

2 import sys

3 import textwrap

4 import types

5 import re

6 import warnings

7 import functools

8

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

10 from numpy.core.overrides import set_module

11 from numpy.core import ndarray, ufunc, asarray

12 import 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

21 def 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

97 def 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

126 class _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

194 def _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

208 def 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

261 def 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

292 def 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

349 def 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.

452 def _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

476 def _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

496 def _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')

551 def 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')

701 def 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')

760 def 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

883 def _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

1022 def _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

1032 def 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

1086 def _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

1122 def _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#-----------------------------------------------------------------------------