Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/numpy/lib/utils.py: 9%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import os
2import sys
3import textwrap
4import types
5import re
6import warnings
7import functools
9from numpy.core.numerictypes import issubclass_, issubsctype, issubdtype
10from numpy.core.overrides import set_module
11from numpy.core import ndarray, ufunc, asarray
12import numpy as np
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 ]
21def show_runtime():
22 """
23 Print information about various resources in the system
24 including available intrinsic support and BLAS/LAPACK library
25 in use
27 See Also
28 --------
29 show_config : Show libraries in the system on which NumPy was built.
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__``
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)
97def get_include():
98 """
99 Return the directory that contains the NumPy \\*.h header files.
101 Extension modules that need to compile against NumPy should use this
102 function to locate the appropriate include directory.
104 Notes
105 -----
106 When using ``distutils``, for example in ``setup.py``::
108 import numpy as np
109 ...
110 Extension('extension_name', ...
111 include_dirs=[np.get_include()])
112 ...
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
126class _Deprecate:
127 """
128 Decorator class to deprecate old functions.
130 Refer to `deprecate` for details.
132 See Also
133 --------
134 deprecate
136 """
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
143 def __call__(self, func, *args, **kwargs):
144 """
145 Decorator call. Refer to ``decorate``.
147 """
148 old_name = self.old_name
149 new_name = self.new_name
150 message = self.message
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)
160 if message is not None:
161 depdoc += "\n" + message
163 @functools.wraps(func)
164 def newfunc(*args, **kwds):
165 warnings.warn(depdoc, DeprecationWarning, stacklevel=2)
166 return func(*args, **kwds)
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
191 return newfunc
194def _get_indent(lines):
195 """
196 Determines the leading whitespace that could be removed from all the lines.
197 """
198 indent = sys.maxsize
199 for line in lines:
200 content = len(line.lstrip())
201 if content:
202 indent = min(indent, len(line) - content)
203 if indent == sys.maxsize:
204 indent = 0
205 return indent
208def deprecate(*args, **kwargs):
209 """
210 Issues a DeprecationWarning, adds warning to `old_name`'s
211 docstring, rebinds ``old_name.__name__`` and returns the new
212 function object.
214 This function may also be used as a decorator.
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.
232 Returns
233 -------
234 old_func : function
235 The deprecated function.
237 Examples
238 --------
239 Note that ``olduint`` returns a value after printing Deprecation
240 Warning:
242 >>> olduint = np.deprecate(np.uint)
243 DeprecationWarning: `uint64` is deprecated! # may vary
244 >>> olduint(6)
245 6
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.
252 if args:
253 fn = args[0]
254 args = args[1:]
256 return _Deprecate(*args, **kwargs)(fn)
257 else:
258 return _Deprecate(*args, **kwargs)
261def deprecate_with_doc(msg):
262 """
263 Deprecates a function and includes the deprecation in its docstring.
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.
270 See Also
271 --------
272 deprecate : Decorate a function such that it issues a `DeprecationWarning`
274 Parameters
275 ----------
276 msg : str
277 Additional explanation of the deprecation. Displayed in the
278 docstring after the warning.
280 Returns
281 -------
282 obj : object
284 """
285 return _Deprecate(message=msg)
288#--------------------------------------------
289# Determine if two arrays can share memory
290#--------------------------------------------
292def byte_bounds(a):
293 """
294 Returns pointers to the end-points of an array.
296 Parameters
297 ----------
298 a : ndarray
299 Input array. It must conform to the Python-side of the array
300 interface.
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.
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
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
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
344#-----------------------------------------------------------------------------
345# Function for output and information on the variables used.
346#-----------------------------------------------------------------------------
349def who(vardict=None):
350 """
351 Print the NumPy arrays in the given dictionary.
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).
357 Parameters
358 ----------
359 vardict : dict, optional
360 A dictionary possibly containing ndarrays. Default is globals().
362 Returns
363 -------
364 out : None
365 Returns 'None'.
367 Notes
368 -----
369 Prints out the name, shape, bytes and type of all of the ndarrays
370 present in `vardict`.
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
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
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])
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])
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")
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
443#-----------------------------------------------------------------------------
446# NOTE: pydoc defines a help function which works similarly to this
447# except it uses a pager to take over the screen.
449# combine name and arguments and split to multiple lines of width
450# characters. End lines on a comma and begin argument list indented with
451# the rest of the arguments.
452def _split_line(name, arguments, width):
453 firstwidth = len(name)
454 k = firstwidth
455 newstr = name
456 sepstr = ", "
457 arglist = arguments.split(sepstr)
458 for argument in arglist:
459 if k == firstwidth:
460 addstr = ""
461 else:
462 addstr = sepstr
463 k = k + len(argument) + len(addstr)
464 if k > width:
465 k = firstwidth + 1 + len(argument)
466 newstr = newstr + ",\n" + " "*(firstwidth+2) + argument
467 else:
468 newstr = newstr + addstr + argument
469 return newstr
471_namedict = None
472_dictlist = None
474# Traverse all module directories underneath globals
475# to see if something is defined
476def _makenamedict(module='numpy'):
477 module = __import__(module, globals(), locals(), [])
478 thedict = {module.__name__:module.__dict__}
479 dictlist = [module.__name__]
480 totraverse = [module.__dict__]
481 while True:
482 if len(totraverse) == 0:
483 break
484 thisdict = totraverse.pop(0)
485 for x in thisdict.keys():
486 if isinstance(thisdict[x], types.ModuleType):
487 modname = thisdict[x].__name__
488 if modname not in dictlist:
489 moddict = thisdict[x].__dict__
490 dictlist.append(modname)
491 totraverse.append(moddict)
492 thedict[modname] = moddict
493 return thedict, dictlist
496def _info(obj, output=None):
497 """Provide information about ndarray obj.
499 Parameters
500 ----------
501 obj : ndarray
502 Must be ndarray, not checked.
503 output
504 Where printed output goes.
506 Notes
507 -----
508 Copied over from the numarray module prior to its removal.
509 Adapted somewhat as only numpy is an option now.
511 Called by info.
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
522 if output is None:
523 output = sys.stdout
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)
550@set_module('numpy')
551def info(object=None, maxwidth=76, output=None, toplevel='numpy'):
552 """
553 Get help information for a function, class, or module.
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.
571 See Also
572 --------
573 source, lookfor
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.
581 Examples
582 --------
583 >>> np.info(np.polyval) # doctest: +SKIP
584 polyval(p, x)
585 Evaluate the polynomial p at x.
586 ...
588 When using a string for `object` it is possible to get multiple results.
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. ***
600 """
601 global _namedict, _dictlist
602 # Local import to speed up numpy's import time.
603 import pydoc
604 import inspect
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
612 if output is None:
613 output = sys.stdout
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 )
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 = "()"
655 if len(name+arguments) > maxwidth:
656 argstr = _split_line(name, arguments, maxwidth)
657 else:
658 argstr = name + arguments
660 print(" " + argstr + "\n", file=output)
661 print(inspect.getdoc(object), file=output)
663 elif inspect.isclass(object):
664 name = object.__name__
665 try:
666 arguments = str(inspect.signature(object))
667 except Exception:
668 arguments = "()"
670 if len(name+arguments) > maxwidth:
671 argstr = _split_line(name, arguments, maxwidth)
672 else:
673 argstr = name + arguments
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)
683 methods = pydoc.allmethods(object)
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)
696 elif hasattr(object, '__doc__'):
697 print(inspect.getdoc(object), file=output)
700@set_module('numpy')
701def source(object, output=sys.stdout):
702 """
703 Print or write to a file the source code for a NumPy object.
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.
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.
719 See Also
720 --------
721 lookfor, info
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)
734 The source code is only returned for objects written in Python.
736 >>> np.source(np.array) #doctest: +SKIP
737 Not available for this object.
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)
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 = {}
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)
759@set_module('numpy')
760def lookfor(what, module=None, import_modules=True, regenerate=False,
761 output=None):
762 """
763 Do a keyword search on docstrings.
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.
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.
783 See Also
784 --------
785 source, info
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.
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 ...
805 """
806 import pydoc
808 # Cache
809 cache = _lookfor_generate_cache(module, import_modules, regenerate)
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
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)
826 # Relevance sort
827 # XXX: this is full Harrison-Stetson heuristics now,
828 # XXX: it probably could be improved
830 kind_relevance = {'func': 1000, 'class': 1000,
831 'module': -1000, 'object': -1000}
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
849 def relevance_value(a):
850 return relevance(a, *cache[a])
851 found.sort(key=relevance_value)
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]
859 doclines = [line.strip() for line in doc.strip().split("\n")
860 if line.strip()]
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))
871 if not found:
872 help_text.append("Nothing found.")
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))
883def _lookfor_generate_cache(module, import_modules, regenerate):
884 """
885 Generate docstring cache for given module.
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
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.
902 """
903 # Local import to speed up numpy's import time.
904 import inspect
906 from io import StringIO
908 if module is None:
909 module = "numpy"
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
924 if id(module) in _lookfor_caches and not regenerate:
925 return _lookfor_caches[id(module)]
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
939 index += 1
940 kind = "object"
942 if inspect.ismodule(item):
943 kind = "module"
944 try:
945 _all = item.__all__
946 except AttributeError:
947 _all = None
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
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
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)
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"
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)
1020 return cache
1022def _getmembers(item):
1023 import inspect
1024 try:
1025 members = inspect.getmembers(item)
1026 except Exception:
1027 members = [(x, getattr(item, x)) for x in dir(item)
1028 if hasattr(item, x)]
1029 return members
1032def safe_eval(source):
1033 """
1034 Protected string evaluation.
1036 Evaluate a string containing a Python literal expression without
1037 allowing the execution of arbitrary non-literal code.
1039 .. warning::
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.
1045 Parameters
1046 ----------
1047 source : str
1048 The string to evaluate.
1050 Returns
1051 -------
1052 obj : object
1053 The result of evaluating `source`.
1055 Raises
1056 ------
1057 SyntaxError
1058 If the code has invalid Python syntax, or if it contains
1059 non-literal code.
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)}
1070 >>> np.safe_eval('import os')
1071 Traceback (most recent call last):
1072 ...
1073 SyntaxError: invalid syntax
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...>
1080 """
1081 # Local import to speed up numpy's import time.
1082 import ast
1083 return ast.literal_eval(source)
1086def _median_nancheck(data, result, axis):
1087 """
1088 Utility function to check median result from data for NaN values at the end
1089 and return NaN in that case. Input result can also be a MaskedArray.
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.
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)
1119 result[n] = np.nan
1120 return result
1122def _opt_info():
1123 """
1124 Returns a string contains the supported CPU features by the current build.
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 )
1137 if len(__cpu_baseline__) == 0 and len(__cpu_dispatch__) == 0:
1138 return ''
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}?"
1147 return enabled_features
1148#-----------------------------------------------------------------------------