utils.py 31 KB

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