utils.py 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159
  1. from __future__ import division, absolute_import, print_function
  2. import os
  3. import sys
  4. import types
  5. import re
  6. import warnings
  7. from numpy.core.numerictypes import issubclass_, issubsctype, issubdtype
  8. from numpy.core.overrides import set_module
  9. from numpy.core import ndarray, ufunc, asarray
  10. import numpy as np
  11. # getargspec and formatargspec were removed in Python 3.6
  12. from numpy.compat import getargspec, formatargspec
  13. __all__ = [
  14. 'issubclass_', 'issubsctype', 'issubdtype', 'deprecate',
  15. 'deprecate_with_doc', 'get_include', 'info', 'source', 'who',
  16. 'lookfor', 'byte_bounds', 'safe_eval'
  17. ]
  18. def get_include():
  19. """
  20. Return the directory that contains the NumPy \\*.h header files.
  21. Extension modules that need to compile against NumPy should use this
  22. function to locate the appropriate include directory.
  23. Notes
  24. -----
  25. When using ``distutils``, for example in ``setup.py``.
  26. ::
  27. import numpy as np
  28. ...
  29. Extension('extension_name', ...
  30. include_dirs=[np.get_include()])
  31. ...
  32. """
  33. import numpy
  34. if numpy.show_config is None:
  35. # running from numpy source directory
  36. d = os.path.join(os.path.dirname(numpy.__file__), 'core', 'include')
  37. else:
  38. # using installed numpy core headers
  39. import numpy.core as core
  40. d = os.path.join(os.path.dirname(core.__file__), 'include')
  41. return d
  42. def _set_function_name(func, name):
  43. func.__name__ = name
  44. return func
  45. class _Deprecate(object):
  46. """
  47. Decorator class to deprecate old functions.
  48. Refer to `deprecate` for details.
  49. See Also
  50. --------
  51. deprecate
  52. """
  53. def __init__(self, old_name=None, new_name=None, message=None):
  54. self.old_name = old_name
  55. self.new_name = new_name
  56. self.message = message
  57. def __call__(self, func, *args, **kwargs):
  58. """
  59. Decorator call. Refer to ``decorate``.
  60. """
  61. old_name = self.old_name
  62. new_name = self.new_name
  63. message = self.message
  64. if old_name is None:
  65. try:
  66. old_name = func.__name__
  67. except AttributeError:
  68. old_name = func.__name__
  69. if new_name is None:
  70. depdoc = "`%s` is deprecated!" % old_name
  71. else:
  72. depdoc = "`%s` is deprecated, use `%s` instead!" % \
  73. (old_name, new_name)
  74. if message is not None:
  75. depdoc += "\n" + message
  76. def newfunc(*args,**kwds):
  77. """`arrayrange` is deprecated, use `arange` instead!"""
  78. warnings.warn(depdoc, DeprecationWarning, stacklevel=2)
  79. return func(*args, **kwds)
  80. newfunc = _set_function_name(newfunc, old_name)
  81. doc = func.__doc__
  82. if doc is None:
  83. doc = depdoc
  84. else:
  85. doc = '\n\n'.join([depdoc, doc])
  86. newfunc.__doc__ = doc
  87. try:
  88. d = func.__dict__
  89. except AttributeError:
  90. pass
  91. else:
  92. newfunc.__dict__.update(d)
  93. return newfunc
  94. def deprecate(*args, **kwargs):
  95. """
  96. Issues a DeprecationWarning, adds warning to `old_name`'s
  97. docstring, rebinds ``old_name.__name__`` and returns the new
  98. function object.
  99. This function may also be used as a decorator.
  100. Parameters
  101. ----------
  102. func : function
  103. The function to be deprecated.
  104. old_name : str, optional
  105. The name of the function to be deprecated. Default is None, in
  106. which case the name of `func` is used.
  107. new_name : str, optional
  108. The new name for the function. Default is None, in which case the
  109. deprecation message is that `old_name` is deprecated. If given, the
  110. deprecation message is that `old_name` is deprecated and `new_name`
  111. should be used instead.
  112. message : str, optional
  113. Additional explanation of the deprecation. Displayed in the
  114. docstring after the warning.
  115. Returns
  116. -------
  117. old_func : function
  118. The deprecated function.
  119. Examples
  120. --------
  121. Note that ``olduint`` returns a value after printing Deprecation
  122. Warning:
  123. >>> olduint = np.deprecate(np.uint)
  124. >>> olduint(6)
  125. /usr/lib/python2.5/site-packages/numpy/lib/utils.py:114:
  126. DeprecationWarning: uint32 is deprecated
  127. warnings.warn(str1, DeprecationWarning, stacklevel=2)
  128. 6
  129. """
  130. # Deprecate may be run as a function or as a decorator
  131. # If run as a function, we initialise the decorator class
  132. # and execute its __call__ method.
  133. if args:
  134. fn = args[0]
  135. args = args[1:]
  136. return _Deprecate(*args, **kwargs)(fn)
  137. else:
  138. return _Deprecate(*args, **kwargs)
  139. deprecate_with_doc = lambda msg: _Deprecate(message=msg)
  140. #--------------------------------------------
  141. # Determine if two arrays can share memory
  142. #--------------------------------------------
  143. def byte_bounds(a):
  144. """
  145. Returns pointers to the end-points of an array.
  146. Parameters
  147. ----------
  148. a : ndarray
  149. Input array. It must conform to the Python-side of the array
  150. interface.
  151. Returns
  152. -------
  153. (low, high) : tuple of 2 integers
  154. The first integer is the first byte of the array, the second
  155. integer is just past the last byte of the array. If `a` is not
  156. contiguous it will not use every byte between the (`low`, `high`)
  157. values.
  158. Examples
  159. --------
  160. >>> I = np.eye(2, dtype='f'); I.dtype
  161. dtype('float32')
  162. >>> low, high = np.byte_bounds(I)
  163. >>> high - low == I.size*I.itemsize
  164. True
  165. >>> I = np.eye(2, dtype='G'); I.dtype
  166. dtype('complex192')
  167. >>> low, high = np.byte_bounds(I)
  168. >>> high - low == I.size*I.itemsize
  169. True
  170. """
  171. ai = a.__array_interface__
  172. a_data = ai['data'][0]
  173. astrides = ai['strides']
  174. ashape = ai['shape']
  175. bytes_a = asarray(a).dtype.itemsize
  176. a_low = a_high = a_data
  177. if astrides is None:
  178. # contiguous case
  179. a_high += a.size * bytes_a
  180. else:
  181. for shape, stride in zip(ashape, astrides):
  182. if stride < 0:
  183. a_low += (shape-1)*stride
  184. else:
  185. a_high += (shape-1)*stride
  186. a_high += bytes_a
  187. return a_low, a_high
  188. #-----------------------------------------------------------------------------
  189. # Function for output and information on the variables used.
  190. #-----------------------------------------------------------------------------
  191. def who(vardict=None):
  192. """
  193. Print the NumPy arrays in the given dictionary.
  194. If there is no dictionary passed in or `vardict` is None then returns
  195. NumPy arrays in the globals() dictionary (all NumPy arrays in the
  196. namespace).
  197. Parameters
  198. ----------
  199. vardict : dict, optional
  200. A dictionary possibly containing ndarrays. Default is globals().
  201. Returns
  202. -------
  203. out : None
  204. Returns 'None'.
  205. Notes
  206. -----
  207. Prints out the name, shape, bytes and type of all of the ndarrays
  208. present in `vardict`.
  209. Examples
  210. --------
  211. >>> a = np.arange(10)
  212. >>> b = np.ones(20)
  213. >>> np.who()
  214. Name Shape Bytes Type
  215. ===========================================================
  216. a 10 40 int32
  217. b 20 160 float64
  218. Upper bound on total bytes = 200
  219. >>> d = {'x': np.arange(2.0), 'y': np.arange(3.0), 'txt': 'Some str',
  220. ... 'idx':5}
  221. >>> np.who(d)
  222. Name Shape Bytes Type
  223. ===========================================================
  224. y 3 24 float64
  225. x 2 16 float64
  226. Upper bound on total bytes = 40
  227. """
  228. if vardict is None:
  229. frame = sys._getframe().f_back
  230. vardict = frame.f_globals
  231. sta = []
  232. cache = {}
  233. for name in vardict.keys():
  234. if isinstance(vardict[name], ndarray):
  235. var = vardict[name]
  236. idv = id(var)
  237. if idv in cache.keys():
  238. namestr = name + " (%s)" % cache[idv]
  239. original = 0
  240. else:
  241. cache[idv] = name
  242. namestr = name
  243. original = 1
  244. shapestr = " x ".join(map(str, var.shape))
  245. bytestr = str(var.nbytes)
  246. sta.append([namestr, shapestr, bytestr, var.dtype.name,
  247. original])
  248. maxname = 0
  249. maxshape = 0
  250. maxbyte = 0
  251. totalbytes = 0
  252. for k in range(len(sta)):
  253. val = sta[k]
  254. if maxname < len(val[0]):
  255. maxname = len(val[0])
  256. if maxshape < len(val[1]):
  257. maxshape = len(val[1])
  258. if maxbyte < len(val[2]):
  259. maxbyte = len(val[2])
  260. if val[4]:
  261. totalbytes += int(val[2])
  262. if len(sta) > 0:
  263. sp1 = max(10, maxname)
  264. sp2 = max(10, maxshape)
  265. sp3 = max(10, maxbyte)
  266. prval = "Name %s Shape %s Bytes %s Type" % (sp1*' ', sp2*' ', sp3*' ')
  267. print(prval + "\n" + "="*(len(prval)+5) + "\n")
  268. for k in range(len(sta)):
  269. val = sta[k]
  270. print("%s %s %s %s %s %s %s" % (val[0], ' '*(sp1-len(val[0])+4),
  271. val[1], ' '*(sp2-len(val[1])+5),
  272. val[2], ' '*(sp3-len(val[2])+5),
  273. val[3]))
  274. print("\nUpper bound on total bytes = %d" % totalbytes)
  275. return
  276. #-----------------------------------------------------------------------------
  277. # NOTE: pydoc defines a help function which works similarly to this
  278. # except it uses a pager to take over the screen.
  279. # combine name and arguments and split to multiple lines of width
  280. # characters. End lines on a comma and begin argument list indented with
  281. # the rest of the arguments.
  282. def _split_line(name, arguments, width):
  283. firstwidth = len(name)
  284. k = firstwidth
  285. newstr = name
  286. sepstr = ", "
  287. arglist = arguments.split(sepstr)
  288. for argument in arglist:
  289. if k == firstwidth:
  290. addstr = ""
  291. else:
  292. addstr = sepstr
  293. k = k + len(argument) + len(addstr)
  294. if k > width:
  295. k = firstwidth + 1 + len(argument)
  296. newstr = newstr + ",\n" + " "*(firstwidth+2) + argument
  297. else:
  298. newstr = newstr + addstr + argument
  299. return newstr
  300. _namedict = None
  301. _dictlist = None
  302. # Traverse all module directories underneath globals
  303. # to see if something is defined
  304. def _makenamedict(module='numpy'):
  305. module = __import__(module, globals(), locals(), [])
  306. thedict = {module.__name__:module.__dict__}
  307. dictlist = [module.__name__]
  308. totraverse = [module.__dict__]
  309. while True:
  310. if len(totraverse) == 0:
  311. break
  312. thisdict = totraverse.pop(0)
  313. for x in thisdict.keys():
  314. if isinstance(thisdict[x], types.ModuleType):
  315. modname = thisdict[x].__name__
  316. if modname not in dictlist:
  317. moddict = thisdict[x].__dict__
  318. dictlist.append(modname)
  319. totraverse.append(moddict)
  320. thedict[modname] = moddict
  321. return thedict, dictlist
  322. def _info(obj, output=sys.stdout):
  323. """Provide information about ndarray obj.
  324. Parameters
  325. ----------
  326. obj : ndarray
  327. Must be ndarray, not checked.
  328. output
  329. Where printed output goes.
  330. Notes
  331. -----
  332. Copied over from the numarray module prior to its removal.
  333. Adapted somewhat as only numpy is an option now.
  334. Called by info.
  335. """
  336. extra = ""
  337. tic = ""
  338. bp = lambda x: x
  339. cls = getattr(obj, '__class__', type(obj))
  340. nm = getattr(cls, '__name__', cls)
  341. strides = obj.strides
  342. endian = obj.dtype.byteorder
  343. print("class: ", nm, file=output)
  344. print("shape: ", obj.shape, file=output)
  345. print("strides: ", strides, file=output)
  346. print("itemsize: ", obj.itemsize, file=output)
  347. print("aligned: ", bp(obj.flags.aligned), file=output)
  348. print("contiguous: ", bp(obj.flags.contiguous), file=output)
  349. print("fortran: ", obj.flags.fortran, file=output)
  350. print(
  351. "data pointer: %s%s" % (hex(obj.ctypes._as_parameter_.value), extra),
  352. file=output
  353. )
  354. print("byteorder: ", end=' ', file=output)
  355. if endian in ['|', '=']:
  356. print("%s%s%s" % (tic, sys.byteorder, tic), file=output)
  357. byteswap = False
  358. elif endian == '>':
  359. print("%sbig%s" % (tic, tic), file=output)
  360. byteswap = sys.byteorder != "big"
  361. else:
  362. print("%slittle%s" % (tic, tic), file=output)
  363. byteswap = sys.byteorder != "little"
  364. print("byteswap: ", bp(byteswap), file=output)
  365. print("type: %s" % obj.dtype, file=output)
  366. @set_module('numpy')
  367. def info(object=None, maxwidth=76, output=sys.stdout, toplevel='numpy'):
  368. """
  369. Get help information for a function, class, or module.
  370. Parameters
  371. ----------
  372. object : object or str, optional
  373. Input object or name to get information about. If `object` is a
  374. numpy object, its docstring is given. If it is a string, available
  375. modules are searched for matching objects. If None, information
  376. about `info` itself is returned.
  377. maxwidth : int, optional
  378. Printing width.
  379. output : file like object, optional
  380. File like object that the output is written to, default is
  381. ``stdout``. The object has to be opened in 'w' or 'a' mode.
  382. toplevel : str, optional
  383. Start search at this level.
  384. See Also
  385. --------
  386. source, lookfor
  387. Notes
  388. -----
  389. When used interactively with an object, ``np.info(obj)`` is equivalent
  390. to ``help(obj)`` on the Python prompt or ``obj?`` on the IPython
  391. prompt.
  392. Examples
  393. --------
  394. >>> np.info(np.polyval) # doctest: +SKIP
  395. polyval(p, x)
  396. Evaluate the polynomial p at x.
  397. ...
  398. When using a string for `object` it is possible to get multiple results.
  399. >>> np.info('fft') # doctest: +SKIP
  400. *** Found in numpy ***
  401. Core FFT routines
  402. ...
  403. *** Found in numpy.fft ***
  404. fft(a, n=None, axis=-1)
  405. ...
  406. *** Repeat reference found in numpy.fft.fftpack ***
  407. *** Total of 3 references found. ***
  408. """
  409. global _namedict, _dictlist
  410. # Local import to speed up numpy's import time.
  411. import pydoc
  412. import inspect
  413. if (hasattr(object, '_ppimport_importer') or
  414. hasattr(object, '_ppimport_module')):
  415. object = object._ppimport_module
  416. elif hasattr(object, '_ppimport_attr'):
  417. object = object._ppimport_attr
  418. if object is None:
  419. info(info)
  420. elif isinstance(object, ndarray):
  421. _info(object, output=output)
  422. elif isinstance(object, str):
  423. if _namedict is None:
  424. _namedict, _dictlist = _makenamedict(toplevel)
  425. numfound = 0
  426. objlist = []
  427. for namestr in _dictlist:
  428. try:
  429. obj = _namedict[namestr][object]
  430. if id(obj) in objlist:
  431. print("\n "
  432. "*** Repeat reference found in %s *** " % namestr,
  433. file=output
  434. )
  435. else:
  436. objlist.append(id(obj))
  437. print(" *** Found in %s ***" % namestr, file=output)
  438. info(obj)
  439. print("-"*maxwidth, file=output)
  440. numfound += 1
  441. except KeyError:
  442. pass
  443. if numfound == 0:
  444. print("Help for %s not found." % object, file=output)
  445. else:
  446. print("\n "
  447. "*** Total of %d references found. ***" % numfound,
  448. file=output
  449. )
  450. elif inspect.isfunction(object):
  451. name = object.__name__
  452. arguments = formatargspec(*getargspec(object))
  453. if len(name+arguments) > maxwidth:
  454. argstr = _split_line(name, arguments, maxwidth)
  455. else:
  456. argstr = name + arguments
  457. print(" " + argstr + "\n", file=output)
  458. print(inspect.getdoc(object), file=output)
  459. elif inspect.isclass(object):
  460. name = object.__name__
  461. arguments = "()"
  462. try:
  463. if hasattr(object, '__init__'):
  464. arguments = formatargspec(
  465. *getargspec(object.__init__.__func__)
  466. )
  467. arglist = arguments.split(', ')
  468. if len(arglist) > 1:
  469. arglist[1] = "("+arglist[1]
  470. arguments = ", ".join(arglist[1:])
  471. except Exception:
  472. pass
  473. if len(name+arguments) > maxwidth:
  474. argstr = _split_line(name, arguments, maxwidth)
  475. else:
  476. argstr = name + arguments
  477. print(" " + argstr + "\n", file=output)
  478. doc1 = inspect.getdoc(object)
  479. if doc1 is None:
  480. if hasattr(object, '__init__'):
  481. print(inspect.getdoc(object.__init__), file=output)
  482. else:
  483. print(inspect.getdoc(object), file=output)
  484. methods = pydoc.allmethods(object)
  485. if methods != []:
  486. print("\n\nMethods:\n", file=output)
  487. for meth in methods:
  488. if meth[0] == '_':
  489. continue
  490. thisobj = getattr(object, meth, None)
  491. if thisobj is not None:
  492. methstr, other = pydoc.splitdoc(
  493. inspect.getdoc(thisobj) or "None"
  494. )
  495. print(" %s -- %s" % (meth, methstr), file=output)
  496. elif (sys.version_info[0] < 3
  497. and isinstance(object, types.InstanceType)):
  498. # check for __call__ method
  499. # types.InstanceType is the type of the instances of oldstyle classes
  500. print("Instance of class: ", object.__class__.__name__, file=output)
  501. print(file=output)
  502. if hasattr(object, '__call__'):
  503. arguments = formatargspec(
  504. *getargspec(object.__call__.__func__)
  505. )
  506. arglist = arguments.split(', ')
  507. if len(arglist) > 1:
  508. arglist[1] = "("+arglist[1]
  509. arguments = ", ".join(arglist[1:])
  510. else:
  511. arguments = "()"
  512. if hasattr(object, 'name'):
  513. name = "%s" % object.name
  514. else:
  515. name = "<name>"
  516. if len(name+arguments) > maxwidth:
  517. argstr = _split_line(name, arguments, maxwidth)
  518. else:
  519. argstr = name + arguments
  520. print(" " + argstr + "\n", file=output)
  521. doc = inspect.getdoc(object.__call__)
  522. if doc is not None:
  523. print(inspect.getdoc(object.__call__), file=output)
  524. print(inspect.getdoc(object), file=output)
  525. else:
  526. print(inspect.getdoc(object), file=output)
  527. elif inspect.ismethod(object):
  528. name = object.__name__
  529. arguments = formatargspec(
  530. *getargspec(object.__func__)
  531. )
  532. arglist = arguments.split(', ')
  533. if len(arglist) > 1:
  534. arglist[1] = "("+arglist[1]
  535. arguments = ", ".join(arglist[1:])
  536. else:
  537. arguments = "()"
  538. if len(name+arguments) > maxwidth:
  539. argstr = _split_line(name, arguments, maxwidth)
  540. else:
  541. argstr = name + arguments
  542. print(" " + argstr + "\n", file=output)
  543. print(inspect.getdoc(object), file=output)
  544. elif hasattr(object, '__doc__'):
  545. print(inspect.getdoc(object), file=output)
  546. @set_module('numpy')
  547. def source(object, output=sys.stdout):
  548. """
  549. Print or write to a file the source code for a NumPy object.
  550. The source code is only returned for objects written in Python. Many
  551. functions and classes are defined in C and will therefore not return
  552. useful information.
  553. Parameters
  554. ----------
  555. object : numpy object
  556. Input object. This can be any object (function, class, module,
  557. ...).
  558. output : file object, optional
  559. If `output` not supplied then source code is printed to screen
  560. (sys.stdout). File object must be created with either write 'w' or
  561. append 'a' modes.
  562. See Also
  563. --------
  564. lookfor, info
  565. Examples
  566. --------
  567. >>> np.source(np.interp) #doctest: +SKIP
  568. In file: /usr/lib/python2.6/dist-packages/numpy/lib/function_base.py
  569. def interp(x, xp, fp, left=None, right=None):
  570. \"\"\".... (full docstring printed)\"\"\"
  571. if isinstance(x, (float, int, number)):
  572. return compiled_interp([x], xp, fp, left, right).item()
  573. else:
  574. return compiled_interp(x, xp, fp, left, right)
  575. The source code is only returned for objects written in Python.
  576. >>> np.source(np.array) #doctest: +SKIP
  577. Not available for this object.
  578. """
  579. # Local import to speed up numpy's import time.
  580. import inspect
  581. try:
  582. print("In file: %s\n" % inspect.getsourcefile(object), file=output)
  583. print(inspect.getsource(object), file=output)
  584. except Exception:
  585. print("Not available for this object.", file=output)
  586. # Cache for lookfor: {id(module): {name: (docstring, kind, index), ...}...}
  587. # where kind: "func", "class", "module", "object"
  588. # and index: index in breadth-first namespace traversal
  589. _lookfor_caches = {}
  590. # regexp whose match indicates that the string may contain a function
  591. # signature
  592. _function_signature_re = re.compile(r"[a-z0-9_]+\(.*[,=].*\)", re.I)
  593. @set_module('numpy')
  594. def lookfor(what, module=None, import_modules=True, regenerate=False,
  595. output=None):
  596. """
  597. Do a keyword search on docstrings.
  598. A list of objects that matched the search is displayed,
  599. sorted by relevance. All given keywords need to be found in the
  600. docstring for it to be returned as a result, but the order does
  601. not matter.
  602. Parameters
  603. ----------
  604. what : str
  605. String containing words to look for.
  606. module : str or list, optional
  607. Name of module(s) whose docstrings to go through.
  608. import_modules : bool, optional
  609. Whether to import sub-modules in packages. Default is True.
  610. regenerate : bool, optional
  611. Whether to re-generate the docstring cache. Default is False.
  612. output : file-like, optional
  613. File-like object to write the output to. If omitted, use a pager.
  614. See Also
  615. --------
  616. source, info
  617. Notes
  618. -----
  619. Relevance is determined only roughly, by checking if the keywords occur
  620. in the function name, at the start of a docstring, etc.
  621. Examples
  622. --------
  623. >>> np.lookfor('binary representation')
  624. Search results for 'binary representation'
  625. ------------------------------------------
  626. numpy.binary_repr
  627. Return the binary representation of the input number as a string.
  628. numpy.core.setup_common.long_double_representation
  629. Given a binary dump as given by GNU od -b, look for long double
  630. numpy.base_repr
  631. Return a string representation of a number in the given base system.
  632. ...
  633. """
  634. import pydoc
  635. # Cache
  636. cache = _lookfor_generate_cache(module, import_modules, regenerate)
  637. # Search
  638. # XXX: maybe using a real stemming search engine would be better?
  639. found = []
  640. whats = str(what).lower().split()
  641. if not whats:
  642. return
  643. for name, (docstring, kind, index) in cache.items():
  644. if kind in ('module', 'object'):
  645. # don't show modules or objects
  646. continue
  647. ok = True
  648. doc = docstring.lower()
  649. for w in whats:
  650. if w not in doc:
  651. ok = False
  652. break
  653. if ok:
  654. found.append(name)
  655. # Relevance sort
  656. # XXX: this is full Harrison-Stetson heuristics now,
  657. # XXX: it probably could be improved
  658. kind_relevance = {'func': 1000, 'class': 1000,
  659. 'module': -1000, 'object': -1000}
  660. def relevance(name, docstr, kind, index):
  661. r = 0
  662. # do the keywords occur within the start of the docstring?
  663. first_doc = "\n".join(docstr.lower().strip().split("\n")[:3])
  664. r += sum([200 for w in whats if w in first_doc])
  665. # do the keywords occur in the function name?
  666. r += sum([30 for w in whats if w in name])
  667. # is the full name long?
  668. r += -len(name) * 5
  669. # is the object of bad type?
  670. r += kind_relevance.get(kind, -1000)
  671. # is the object deep in namespace hierarchy?
  672. r += -name.count('.') * 10
  673. r += max(-index / 100, -100)
  674. return r
  675. def relevance_value(a):
  676. return relevance(a, *cache[a])
  677. found.sort(key=relevance_value)
  678. # Pretty-print
  679. s = "Search results for '%s'" % (' '.join(whats))
  680. help_text = [s, "-"*len(s)]
  681. for name in found[::-1]:
  682. doc, kind, ix = cache[name]
  683. doclines = [line.strip() for line in doc.strip().split("\n")
  684. if line.strip()]
  685. # find a suitable short description
  686. try:
  687. first_doc = doclines[0].strip()
  688. if _function_signature_re.search(first_doc):
  689. first_doc = doclines[1].strip()
  690. except IndexError:
  691. first_doc = ""
  692. help_text.append("%s\n %s" % (name, first_doc))
  693. if not found:
  694. help_text.append("Nothing found.")
  695. # Output
  696. if output is not None:
  697. output.write("\n".join(help_text))
  698. elif len(help_text) > 10:
  699. pager = pydoc.getpager()
  700. pager("\n".join(help_text))
  701. else:
  702. print("\n".join(help_text))
  703. def _lookfor_generate_cache(module, import_modules, regenerate):
  704. """
  705. Generate docstring cache for given module.
  706. Parameters
  707. ----------
  708. module : str, None, module
  709. Module for which to generate docstring cache
  710. import_modules : bool
  711. Whether to import sub-modules in packages.
  712. regenerate : bool
  713. Re-generate the docstring cache
  714. Returns
  715. -------
  716. cache : dict {obj_full_name: (docstring, kind, index), ...}
  717. Docstring cache for the module, either cached one (regenerate=False)
  718. or newly generated.
  719. """
  720. global _lookfor_caches
  721. # Local import to speed up numpy's import time.
  722. import inspect
  723. if sys.version_info[0] >= 3:
  724. # In Python3 stderr, stdout are text files.
  725. from io import StringIO
  726. else:
  727. from StringIO import StringIO
  728. if module is None:
  729. module = "numpy"
  730. if isinstance(module, str):
  731. try:
  732. __import__(module)
  733. except ImportError:
  734. return {}
  735. module = sys.modules[module]
  736. elif isinstance(module, list) or isinstance(module, tuple):
  737. cache = {}
  738. for mod in module:
  739. cache.update(_lookfor_generate_cache(mod, import_modules,
  740. regenerate))
  741. return cache
  742. if id(module) in _lookfor_caches and not regenerate:
  743. return _lookfor_caches[id(module)]
  744. # walk items and collect docstrings
  745. cache = {}
  746. _lookfor_caches[id(module)] = cache
  747. seen = {}
  748. index = 0
  749. stack = [(module.__name__, module)]
  750. while stack:
  751. name, item = stack.pop(0)
  752. if id(item) in seen:
  753. continue
  754. seen[id(item)] = True
  755. index += 1
  756. kind = "object"
  757. if inspect.ismodule(item):
  758. kind = "module"
  759. try:
  760. _all = item.__all__
  761. except AttributeError:
  762. _all = None
  763. # import sub-packages
  764. if import_modules and hasattr(item, '__path__'):
  765. for pth in item.__path__:
  766. for mod_path in os.listdir(pth):
  767. this_py = os.path.join(pth, mod_path)
  768. init_py = os.path.join(pth, mod_path, '__init__.py')
  769. if (os.path.isfile(this_py) and
  770. mod_path.endswith('.py')):
  771. to_import = mod_path[:-3]
  772. elif os.path.isfile(init_py):
  773. to_import = mod_path
  774. else:
  775. continue
  776. if to_import == '__init__':
  777. continue
  778. try:
  779. old_stdout = sys.stdout
  780. old_stderr = sys.stderr
  781. try:
  782. sys.stdout = StringIO()
  783. sys.stderr = StringIO()
  784. __import__("%s.%s" % (name, to_import))
  785. finally:
  786. sys.stdout = old_stdout
  787. sys.stderr = old_stderr
  788. # Catch SystemExit, too
  789. except BaseException:
  790. continue
  791. for n, v in _getmembers(item):
  792. try:
  793. item_name = getattr(v, '__name__', "%s.%s" % (name, n))
  794. mod_name = getattr(v, '__module__', None)
  795. except NameError:
  796. # ref. SWIG's global cvars
  797. # NameError: Unknown C global variable
  798. item_name = "%s.%s" % (name, n)
  799. mod_name = None
  800. if '.' not in item_name and mod_name:
  801. item_name = "%s.%s" % (mod_name, item_name)
  802. if not item_name.startswith(name + '.'):
  803. # don't crawl "foreign" objects
  804. if isinstance(v, ufunc):
  805. # ... unless they are ufuncs
  806. pass
  807. else:
  808. continue
  809. elif not (inspect.ismodule(v) or _all is None or n in _all):
  810. continue
  811. stack.append(("%s.%s" % (name, n), v))
  812. elif inspect.isclass(item):
  813. kind = "class"
  814. for n, v in _getmembers(item):
  815. stack.append(("%s.%s" % (name, n), v))
  816. elif hasattr(item, "__call__"):
  817. kind = "func"
  818. try:
  819. doc = inspect.getdoc(item)
  820. except NameError:
  821. # ref SWIG's NameError: Unknown C global variable
  822. doc = None
  823. if doc is not None:
  824. cache[name] = (doc, kind, index)
  825. return cache
  826. def _getmembers(item):
  827. import inspect
  828. try:
  829. members = inspect.getmembers(item)
  830. except Exception:
  831. members = [(x, getattr(item, x)) for x in dir(item)
  832. if hasattr(item, x)]
  833. return members
  834. #-----------------------------------------------------------------------------
  835. # The following SafeEval class and company are adapted from Michael Spencer's
  836. # ASPN Python Cookbook recipe: https://code.activestate.com/recipes/364469/
  837. #
  838. # Accordingly it is mostly Copyright 2006 by Michael Spencer.
  839. # The recipe, like most of the other ASPN Python Cookbook recipes was made
  840. # available under the Python license.
  841. # https://en.wikipedia.org/wiki/Python_License
  842. # It has been modified to:
  843. # * handle unary -/+
  844. # * support True/False/None
  845. # * raise SyntaxError instead of a custom exception.
  846. class SafeEval(object):
  847. """
  848. Object to evaluate constant string expressions.
  849. This includes strings with lists, dicts and tuples using the abstract
  850. syntax tree created by ``compiler.parse``.
  851. .. deprecated:: 1.10.0
  852. See Also
  853. --------
  854. safe_eval
  855. """
  856. def __init__(self):
  857. # 2014-10-15, 1.10
  858. warnings.warn("SafeEval is deprecated in 1.10 and will be removed.",
  859. DeprecationWarning, stacklevel=2)
  860. def visit(self, node):
  861. cls = node.__class__
  862. meth = getattr(self, 'visit' + cls.__name__, self.default)
  863. return meth(node)
  864. def default(self, node):
  865. raise SyntaxError("Unsupported source construct: %s"
  866. % node.__class__)
  867. def visitExpression(self, node):
  868. return self.visit(node.body)
  869. def visitNum(self, node):
  870. return node.n
  871. def visitStr(self, node):
  872. return node.s
  873. def visitBytes(self, node):
  874. return node.s
  875. def visitDict(self, node,**kw):
  876. return dict([(self.visit(k), self.visit(v))
  877. for k, v in zip(node.keys, node.values)])
  878. def visitTuple(self, node):
  879. return tuple([self.visit(i) for i in node.elts])
  880. def visitList(self, node):
  881. return [self.visit(i) for i in node.elts]
  882. def visitUnaryOp(self, node):
  883. import ast
  884. if isinstance(node.op, ast.UAdd):
  885. return +self.visit(node.operand)
  886. elif isinstance(node.op, ast.USub):
  887. return -self.visit(node.operand)
  888. else:
  889. raise SyntaxError("Unknown unary op: %r" % node.op)
  890. def visitName(self, node):
  891. if node.id == 'False':
  892. return False
  893. elif node.id == 'True':
  894. return True
  895. elif node.id == 'None':
  896. return None
  897. else:
  898. raise SyntaxError("Unknown name: %s" % node.id)
  899. def visitNameConstant(self, node):
  900. return node.value
  901. def safe_eval(source):
  902. """
  903. Protected string evaluation.
  904. Evaluate a string containing a Python literal expression without
  905. allowing the execution of arbitrary non-literal code.
  906. Parameters
  907. ----------
  908. source : str
  909. The string to evaluate.
  910. Returns
  911. -------
  912. obj : object
  913. The result of evaluating `source`.
  914. Raises
  915. ------
  916. SyntaxError
  917. If the code has invalid Python syntax, or if it contains
  918. non-literal code.
  919. Examples
  920. --------
  921. >>> np.safe_eval('1')
  922. 1
  923. >>> np.safe_eval('[1, 2, 3]')
  924. [1, 2, 3]
  925. >>> np.safe_eval('{"foo": ("bar", 10.0)}')
  926. {'foo': ('bar', 10.0)}
  927. >>> np.safe_eval('import os')
  928. Traceback (most recent call last):
  929. ...
  930. SyntaxError: invalid syntax
  931. >>> np.safe_eval('open("/home/user/.ssh/id_dsa").read()')
  932. Traceback (most recent call last):
  933. ...
  934. SyntaxError: Unsupported source construct: compiler.ast.CallFunc
  935. """
  936. # Local import to speed up numpy's import time.
  937. import ast
  938. return ast.literal_eval(source)
  939. def _median_nancheck(data, result, axis, out):
  940. """
  941. Utility function to check median result from data for NaN values at the end
  942. and return NaN in that case. Input result can also be a MaskedArray.
  943. Parameters
  944. ----------
  945. data : array
  946. Input data to median function
  947. result : Array or MaskedArray
  948. Result of median function
  949. axis : {int, sequence of int, None}, optional
  950. Axis or axes along which the median was computed.
  951. out : ndarray, optional
  952. Output array in which to place the result.
  953. Returns
  954. -------
  955. median : scalar or ndarray
  956. Median or NaN in axes which contained NaN in the input.
  957. """
  958. if data.size == 0:
  959. return result
  960. data = np.moveaxis(data, axis, -1)
  961. n = np.isnan(data[..., -1])
  962. # masked NaN values are ok
  963. if np.ma.isMaskedArray(n):
  964. n = n.filled(False)
  965. if result.ndim == 0:
  966. if n == True:
  967. warnings.warn("Invalid value encountered in median",
  968. RuntimeWarning, stacklevel=3)
  969. if out is not None:
  970. out[...] = data.dtype.type(np.nan)
  971. result = out
  972. else:
  973. result = data.dtype.type(np.nan)
  974. elif np.count_nonzero(n.ravel()) > 0:
  975. warnings.warn("Invalid value encountered in median for" +
  976. " %d results" % np.count_nonzero(n.ravel()),
  977. RuntimeWarning, stacklevel=3)
  978. result[n] = np.nan
  979. return result
  980. #-----------------------------------------------------------------------------