Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/numpy/lib/utils.py: 6%
454 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1import os
2import sys
3import textwrap
4import types
5import re
6import warnings
8from numpy.core.numerictypes import issubclass_, issubsctype, issubdtype
9from numpy.core.overrides import set_module
10from numpy.core import ndarray, ufunc, asarray
11import numpy as np
13__all__ = [
14 'issubclass_', 'issubsctype', 'issubdtype', 'deprecate',
15 'deprecate_with_doc', 'get_include', 'info', 'source', 'who',
16 'lookfor', 'byte_bounds', 'safe_eval'
17 ]
19def get_include():
20 """
21 Return the directory that contains the NumPy \\*.h header files.
23 Extension modules that need to compile against NumPy should use this
24 function to locate the appropriate include directory.
26 Notes
27 -----
28 When using ``distutils``, for example in ``setup.py``::
30 import numpy as np
31 ...
32 Extension('extension_name', ...
33 include_dirs=[np.get_include()])
34 ...
36 """
37 import numpy
38 if numpy.show_config is None:
39 # running from numpy source directory
40 d = os.path.join(os.path.dirname(numpy.__file__), 'core', 'include')
41 else:
42 # using installed numpy core headers
43 import numpy.core as core
44 d = os.path.join(os.path.dirname(core.__file__), 'include')
45 return d
48def _set_function_name(func, name):
49 func.__name__ = name
50 return func
53class _Deprecate:
54 """
55 Decorator class to deprecate old functions.
57 Refer to `deprecate` for details.
59 See Also
60 --------
61 deprecate
63 """
65 def __init__(self, old_name=None, new_name=None, message=None):
66 self.old_name = old_name
67 self.new_name = new_name
68 self.message = message
70 def __call__(self, func, *args, **kwargs):
71 """
72 Decorator call. Refer to ``decorate``.
74 """
75 old_name = self.old_name
76 new_name = self.new_name
77 message = self.message
79 if old_name is None:
80 try:
81 old_name = func.__name__
82 except AttributeError:
83 old_name = func.__name__
84 if new_name is None:
85 depdoc = "`%s` is deprecated!" % old_name
86 else:
87 depdoc = "`%s` is deprecated, use `%s` instead!" % \
88 (old_name, new_name)
90 if message is not None:
91 depdoc += "\n" + message
93 def newfunc(*args,**kwds):
94 """`arrayrange` is deprecated, use `arange` instead!"""
95 warnings.warn(depdoc, DeprecationWarning, stacklevel=2)
96 return func(*args, **kwds)
98 newfunc = _set_function_name(newfunc, old_name)
99 doc = func.__doc__
100 if doc is None:
101 doc = depdoc
102 else:
103 lines = doc.expandtabs().split('\n')
104 indent = _get_indent(lines[1:])
105 if lines[0].lstrip():
106 # Indent the original first line to let inspect.cleandoc()
107 # dedent the docstring despite the deprecation notice.
108 doc = indent * ' ' + doc
109 else:
110 # Remove the same leading blank lines as cleandoc() would.
111 skip = len(lines[0]) + 1
112 for line in lines[1:]:
113 if len(line) > indent:
114 break
115 skip += len(line) + 1
116 doc = doc[skip:]
117 depdoc = textwrap.indent(depdoc, ' ' * indent)
118 doc = '\n\n'.join([depdoc, doc])
119 newfunc.__doc__ = doc
120 try:
121 d = func.__dict__
122 except AttributeError:
123 pass
124 else:
125 newfunc.__dict__.update(d)
126 return newfunc
129def _get_indent(lines):
130 """
131 Determines the leading whitespace that could be removed from all the lines.
132 """
133 indent = sys.maxsize
134 for line in lines:
135 content = len(line.lstrip())
136 if content:
137 indent = min(indent, len(line) - content)
138 if indent == sys.maxsize:
139 indent = 0
140 return indent
143def deprecate(*args, **kwargs):
144 """
145 Issues a DeprecationWarning, adds warning to `old_name`'s
146 docstring, rebinds ``old_name.__name__`` and returns the new
147 function object.
149 This function may also be used as a decorator.
151 Parameters
152 ----------
153 func : function
154 The function to be deprecated.
155 old_name : str, optional
156 The name of the function to be deprecated. Default is None, in
157 which case the name of `func` is used.
158 new_name : str, optional
159 The new name for the function. Default is None, in which case the
160 deprecation message is that `old_name` is deprecated. If given, the
161 deprecation message is that `old_name` is deprecated and `new_name`
162 should be used instead.
163 message : str, optional
164 Additional explanation of the deprecation. Displayed in the
165 docstring after the warning.
167 Returns
168 -------
169 old_func : function
170 The deprecated function.
172 Examples
173 --------
174 Note that ``olduint`` returns a value after printing Deprecation
175 Warning:
177 >>> olduint = np.deprecate(np.uint)
178 DeprecationWarning: `uint64` is deprecated! # may vary
179 >>> olduint(6)
180 6
182 """
183 # Deprecate may be run as a function or as a decorator
184 # If run as a function, we initialise the decorator class
185 # and execute its __call__ method.
187 if args:
188 fn = args[0]
189 args = args[1:]
191 return _Deprecate(*args, **kwargs)(fn)
192 else:
193 return _Deprecate(*args, **kwargs)
196def deprecate_with_doc(msg):
197 """
198 Deprecates a function and includes the deprecation in its docstring.
200 This function is used as a decorator. It returns an object that can be
201 used to issue a DeprecationWarning, by passing the to-be decorated
202 function as argument, this adds warning to the to-be decorated function's
203 docstring and returns the new function object.
205 See Also
206 --------
207 deprecate : Decorate a function such that it issues a `DeprecationWarning`
209 Parameters
210 ----------
211 msg : str
212 Additional explanation of the deprecation. Displayed in the
213 docstring after the warning.
215 Returns
216 -------
217 obj : object
219 """
220 return _Deprecate(message=msg)
223#--------------------------------------------
224# Determine if two arrays can share memory
225#--------------------------------------------
227def byte_bounds(a):
228 """
229 Returns pointers to the end-points of an array.
231 Parameters
232 ----------
233 a : ndarray
234 Input array. It must conform to the Python-side of the array
235 interface.
237 Returns
238 -------
239 (low, high) : tuple of 2 integers
240 The first integer is the first byte of the array, the second
241 integer is just past the last byte of the array. If `a` is not
242 contiguous it will not use every byte between the (`low`, `high`)
243 values.
245 Examples
246 --------
247 >>> I = np.eye(2, dtype='f'); I.dtype
248 dtype('float32')
249 >>> low, high = np.byte_bounds(I)
250 >>> high - low == I.size*I.itemsize
251 True
252 >>> I = np.eye(2); I.dtype
253 dtype('float64')
254 >>> low, high = np.byte_bounds(I)
255 >>> high - low == I.size*I.itemsize
256 True
258 """
259 ai = a.__array_interface__
260 a_data = ai['data'][0]
261 astrides = ai['strides']
262 ashape = ai['shape']
263 bytes_a = asarray(a).dtype.itemsize
265 a_low = a_high = a_data
266 if astrides is None:
267 # contiguous case
268 a_high += a.size * bytes_a
269 else:
270 for shape, stride in zip(ashape, astrides):
271 if stride < 0:
272 a_low += (shape-1)*stride
273 else:
274 a_high += (shape-1)*stride
275 a_high += bytes_a
276 return a_low, a_high
279#-----------------------------------------------------------------------------
280# Function for output and information on the variables used.
281#-----------------------------------------------------------------------------
284def who(vardict=None):
285 """
286 Print the NumPy arrays in the given dictionary.
288 If there is no dictionary passed in or `vardict` is None then returns
289 NumPy arrays in the globals() dictionary (all NumPy arrays in the
290 namespace).
292 Parameters
293 ----------
294 vardict : dict, optional
295 A dictionary possibly containing ndarrays. Default is globals().
297 Returns
298 -------
299 out : None
300 Returns 'None'.
302 Notes
303 -----
304 Prints out the name, shape, bytes and type of all of the ndarrays
305 present in `vardict`.
307 Examples
308 --------
309 >>> a = np.arange(10)
310 >>> b = np.ones(20)
311 >>> np.who()
312 Name Shape Bytes Type
313 ===========================================================
314 a 10 80 int64
315 b 20 160 float64
316 Upper bound on total bytes = 240
318 >>> d = {'x': np.arange(2.0), 'y': np.arange(3.0), 'txt': 'Some str',
319 ... 'idx':5}
320 >>> np.who(d)
321 Name Shape Bytes Type
322 ===========================================================
323 x 2 16 float64
324 y 3 24 float64
325 Upper bound on total bytes = 40
327 """
328 if vardict is None:
329 frame = sys._getframe().f_back
330 vardict = frame.f_globals
331 sta = []
332 cache = {}
333 for name in vardict.keys():
334 if isinstance(vardict[name], ndarray):
335 var = vardict[name]
336 idv = id(var)
337 if idv in cache.keys():
338 namestr = name + " (%s)" % cache[idv]
339 original = 0
340 else:
341 cache[idv] = name
342 namestr = name
343 original = 1
344 shapestr = " x ".join(map(str, var.shape))
345 bytestr = str(var.nbytes)
346 sta.append([namestr, shapestr, bytestr, var.dtype.name,
347 original])
349 maxname = 0
350 maxshape = 0
351 maxbyte = 0
352 totalbytes = 0
353 for val in sta:
354 if maxname < len(val[0]):
355 maxname = len(val[0])
356 if maxshape < len(val[1]):
357 maxshape = len(val[1])
358 if maxbyte < len(val[2]):
359 maxbyte = len(val[2])
360 if val[4]:
361 totalbytes += int(val[2])
363 if len(sta) > 0:
364 sp1 = max(10, maxname)
365 sp2 = max(10, maxshape)
366 sp3 = max(10, maxbyte)
367 prval = "Name %s Shape %s Bytes %s Type" % (sp1*' ', sp2*' ', sp3*' ')
368 print(prval + "\n" + "="*(len(prval)+5) + "\n")
370 for val in sta:
371 print("%s %s %s %s %s %s %s" % (val[0], ' '*(sp1-len(val[0])+4),
372 val[1], ' '*(sp2-len(val[1])+5),
373 val[2], ' '*(sp3-len(val[2])+5),
374 val[3]))
375 print("\nUpper bound on total bytes = %d" % totalbytes)
376 return
378#-----------------------------------------------------------------------------
381# NOTE: pydoc defines a help function which works similarly to this
382# except it uses a pager to take over the screen.
384# combine name and arguments and split to multiple lines of width
385# characters. End lines on a comma and begin argument list indented with
386# the rest of the arguments.
387def _split_line(name, arguments, width):
388 firstwidth = len(name)
389 k = firstwidth
390 newstr = name
391 sepstr = ", "
392 arglist = arguments.split(sepstr)
393 for argument in arglist:
394 if k == firstwidth:
395 addstr = ""
396 else:
397 addstr = sepstr
398 k = k + len(argument) + len(addstr)
399 if k > width:
400 k = firstwidth + 1 + len(argument)
401 newstr = newstr + ",\n" + " "*(firstwidth+2) + argument
402 else:
403 newstr = newstr + addstr + argument
404 return newstr
406_namedict = None
407_dictlist = None
409# Traverse all module directories underneath globals
410# to see if something is defined
411def _makenamedict(module='numpy'):
412 module = __import__(module, globals(), locals(), [])
413 thedict = {module.__name__:module.__dict__}
414 dictlist = [module.__name__]
415 totraverse = [module.__dict__]
416 while True:
417 if len(totraverse) == 0:
418 break
419 thisdict = totraverse.pop(0)
420 for x in thisdict.keys():
421 if isinstance(thisdict[x], types.ModuleType):
422 modname = thisdict[x].__name__
423 if modname not in dictlist:
424 moddict = thisdict[x].__dict__
425 dictlist.append(modname)
426 totraverse.append(moddict)
427 thedict[modname] = moddict
428 return thedict, dictlist
431def _info(obj, output=None):
432 """Provide information about ndarray obj.
434 Parameters
435 ----------
436 obj : ndarray
437 Must be ndarray, not checked.
438 output
439 Where printed output goes.
441 Notes
442 -----
443 Copied over from the numarray module prior to its removal.
444 Adapted somewhat as only numpy is an option now.
446 Called by info.
448 """
449 extra = ""
450 tic = ""
451 bp = lambda x: x
452 cls = getattr(obj, '__class__', type(obj))
453 nm = getattr(cls, '__name__', cls)
454 strides = obj.strides
455 endian = obj.dtype.byteorder
457 if output is None:
458 output = sys.stdout
460 print("class: ", nm, file=output)
461 print("shape: ", obj.shape, file=output)
462 print("strides: ", strides, file=output)
463 print("itemsize: ", obj.itemsize, file=output)
464 print("aligned: ", bp(obj.flags.aligned), file=output)
465 print("contiguous: ", bp(obj.flags.contiguous), file=output)
466 print("fortran: ", obj.flags.fortran, file=output)
467 print(
468 "data pointer: %s%s" % (hex(obj.ctypes._as_parameter_.value), extra),
469 file=output
470 )
471 print("byteorder: ", end=' ', file=output)
472 if endian in ['|', '=']:
473 print("%s%s%s" % (tic, sys.byteorder, tic), file=output)
474 byteswap = False
475 elif endian == '>':
476 print("%sbig%s" % (tic, tic), file=output)
477 byteswap = sys.byteorder != "big"
478 else:
479 print("%slittle%s" % (tic, tic), file=output)
480 byteswap = sys.byteorder != "little"
481 print("byteswap: ", bp(byteswap), file=output)
482 print("type: %s" % obj.dtype, file=output)
485@set_module('numpy')
486def info(object=None, maxwidth=76, output=None, toplevel='numpy'):
487 """
488 Get help information for a function, class, or module.
490 Parameters
491 ----------
492 object : object or str, optional
493 Input object or name to get information about. If `object` is a
494 numpy object, its docstring is given. If it is a string, available
495 modules are searched for matching objects. If None, information
496 about `info` itself is returned.
497 maxwidth : int, optional
498 Printing width.
499 output : file like object, optional
500 File like object that the output is written to, default is
501 ``None``, in which case ``sys.stdout`` will be used.
502 The object has to be opened in 'w' or 'a' mode.
503 toplevel : str, optional
504 Start search at this level.
506 See Also
507 --------
508 source, lookfor
510 Notes
511 -----
512 When used interactively with an object, ``np.info(obj)`` is equivalent
513 to ``help(obj)`` on the Python prompt or ``obj?`` on the IPython
514 prompt.
516 Examples
517 --------
518 >>> np.info(np.polyval) # doctest: +SKIP
519 polyval(p, x)
520 Evaluate the polynomial p at x.
521 ...
523 When using a string for `object` it is possible to get multiple results.
525 >>> np.info('fft') # doctest: +SKIP
526 *** Found in numpy ***
527 Core FFT routines
528 ...
529 *** Found in numpy.fft ***
530 fft(a, n=None, axis=-1)
531 ...
532 *** Repeat reference found in numpy.fft.fftpack ***
533 *** Total of 3 references found. ***
535 """
536 global _namedict, _dictlist
537 # Local import to speed up numpy's import time.
538 import pydoc
539 import inspect
541 if (hasattr(object, '_ppimport_importer') or
542 hasattr(object, '_ppimport_module')):
543 object = object._ppimport_module
544 elif hasattr(object, '_ppimport_attr'):
545 object = object._ppimport_attr
547 if output is None:
548 output = sys.stdout
550 if object is None:
551 info(info)
552 elif isinstance(object, ndarray):
553 _info(object, output=output)
554 elif isinstance(object, str):
555 if _namedict is None:
556 _namedict, _dictlist = _makenamedict(toplevel)
557 numfound = 0
558 objlist = []
559 for namestr in _dictlist:
560 try:
561 obj = _namedict[namestr][object]
562 if id(obj) in objlist:
563 print("\n "
564 "*** Repeat reference found in %s *** " % namestr,
565 file=output
566 )
567 else:
568 objlist.append(id(obj))
569 print(" *** Found in %s ***" % namestr, file=output)
570 info(obj)
571 print("-"*maxwidth, file=output)
572 numfound += 1
573 except KeyError:
574 pass
575 if numfound == 0:
576 print("Help for %s not found." % object, file=output)
577 else:
578 print("\n "
579 "*** Total of %d references found. ***" % numfound,
580 file=output
581 )
583 elif inspect.isfunction(object) or inspect.ismethod(object):
584 name = object.__name__
585 try:
586 arguments = str(inspect.signature(object))
587 except Exception:
588 arguments = "()"
590 if len(name+arguments) > maxwidth:
591 argstr = _split_line(name, arguments, maxwidth)
592 else:
593 argstr = name + arguments
595 print(" " + argstr + "\n", file=output)
596 print(inspect.getdoc(object), file=output)
598 elif inspect.isclass(object):
599 name = object.__name__
600 try:
601 arguments = str(inspect.signature(object))
602 except Exception:
603 arguments = "()"
605 if len(name+arguments) > maxwidth:
606 argstr = _split_line(name, arguments, maxwidth)
607 else:
608 argstr = name + arguments
610 print(" " + argstr + "\n", file=output)
611 doc1 = inspect.getdoc(object)
612 if doc1 is None:
613 if hasattr(object, '__init__'):
614 print(inspect.getdoc(object.__init__), file=output)
615 else:
616 print(inspect.getdoc(object), file=output)
618 methods = pydoc.allmethods(object)
620 public_methods = [meth for meth in methods if meth[0] != '_']
621 if public_methods:
622 print("\n\nMethods:\n", file=output)
623 for meth in public_methods:
624 thisobj = getattr(object, meth, None)
625 if thisobj is not None:
626 methstr, other = pydoc.splitdoc(
627 inspect.getdoc(thisobj) or "None"
628 )
629 print(" %s -- %s" % (meth, methstr), file=output)
631 elif hasattr(object, '__doc__'):
632 print(inspect.getdoc(object), file=output)
635@set_module('numpy')
636def source(object, output=sys.stdout):
637 """
638 Print or write to a file the source code for a NumPy object.
640 The source code is only returned for objects written in Python. Many
641 functions and classes are defined in C and will therefore not return
642 useful information.
644 Parameters
645 ----------
646 object : numpy object
647 Input object. This can be any object (function, class, module,
648 ...).
649 output : file object, optional
650 If `output` not supplied then source code is printed to screen
651 (sys.stdout). File object must be created with either write 'w' or
652 append 'a' modes.
654 See Also
655 --------
656 lookfor, info
658 Examples
659 --------
660 >>> np.source(np.interp) #doctest: +SKIP
661 In file: /usr/lib/python2.6/dist-packages/numpy/lib/function_base.py
662 def interp(x, xp, fp, left=None, right=None):
663 \"\"\".... (full docstring printed)\"\"\"
664 if isinstance(x, (float, int, number)):
665 return compiled_interp([x], xp, fp, left, right).item()
666 else:
667 return compiled_interp(x, xp, fp, left, right)
669 The source code is only returned for objects written in Python.
671 >>> np.source(np.array) #doctest: +SKIP
672 Not available for this object.
674 """
675 # Local import to speed up numpy's import time.
676 import inspect
677 try:
678 print("In file: %s\n" % inspect.getsourcefile(object), file=output)
679 print(inspect.getsource(object), file=output)
680 except Exception:
681 print("Not available for this object.", file=output)
684# Cache for lookfor: {id(module): {name: (docstring, kind, index), ...}...}
685# where kind: "func", "class", "module", "object"
686# and index: index in breadth-first namespace traversal
687_lookfor_caches = {}
689# regexp whose match indicates that the string may contain a function
690# signature
691_function_signature_re = re.compile(r"[a-z0-9_]+\(.*[,=].*\)", re.I)
694@set_module('numpy')
695def lookfor(what, module=None, import_modules=True, regenerate=False,
696 output=None):
697 """
698 Do a keyword search on docstrings.
700 A list of objects that matched the search is displayed,
701 sorted by relevance. All given keywords need to be found in the
702 docstring for it to be returned as a result, but the order does
703 not matter.
705 Parameters
706 ----------
707 what : str
708 String containing words to look for.
709 module : str or list, optional
710 Name of module(s) whose docstrings to go through.
711 import_modules : bool, optional
712 Whether to import sub-modules in packages. Default is True.
713 regenerate : bool, optional
714 Whether to re-generate the docstring cache. Default is False.
715 output : file-like, optional
716 File-like object to write the output to. If omitted, use a pager.
718 See Also
719 --------
720 source, info
722 Notes
723 -----
724 Relevance is determined only roughly, by checking if the keywords occur
725 in the function name, at the start of a docstring, etc.
727 Examples
728 --------
729 >>> np.lookfor('binary representation') # doctest: +SKIP
730 Search results for 'binary representation'
731 ------------------------------------------
732 numpy.binary_repr
733 Return the binary representation of the input number as a string.
734 numpy.core.setup_common.long_double_representation
735 Given a binary dump as given by GNU od -b, look for long double
736 numpy.base_repr
737 Return a string representation of a number in the given base system.
738 ...
740 """
741 import pydoc
743 # Cache
744 cache = _lookfor_generate_cache(module, import_modules, regenerate)
746 # Search
747 # XXX: maybe using a real stemming search engine would be better?
748 found = []
749 whats = str(what).lower().split()
750 if not whats:
751 return
753 for name, (docstring, kind, index) in cache.items():
754 if kind in ('module', 'object'):
755 # don't show modules or objects
756 continue
757 doc = docstring.lower()
758 if all(w in doc for w in whats):
759 found.append(name)
761 # Relevance sort
762 # XXX: this is full Harrison-Stetson heuristics now,
763 # XXX: it probably could be improved
765 kind_relevance = {'func': 1000, 'class': 1000,
766 'module': -1000, 'object': -1000}
768 def relevance(name, docstr, kind, index):
769 r = 0
770 # do the keywords occur within the start of the docstring?
771 first_doc = "\n".join(docstr.lower().strip().split("\n")[:3])
772 r += sum([200 for w in whats if w in first_doc])
773 # do the keywords occur in the function name?
774 r += sum([30 for w in whats if w in name])
775 # is the full name long?
776 r += -len(name) * 5
777 # is the object of bad type?
778 r += kind_relevance.get(kind, -1000)
779 # is the object deep in namespace hierarchy?
780 r += -name.count('.') * 10
781 r += max(-index / 100, -100)
782 return r
784 def relevance_value(a):
785 return relevance(a, *cache[a])
786 found.sort(key=relevance_value)
788 # Pretty-print
789 s = "Search results for '%s'" % (' '.join(whats))
790 help_text = [s, "-"*len(s)]
791 for name in found[::-1]:
792 doc, kind, ix = cache[name]
794 doclines = [line.strip() for line in doc.strip().split("\n")
795 if line.strip()]
797 # find a suitable short description
798 try:
799 first_doc = doclines[0].strip()
800 if _function_signature_re.search(first_doc):
801 first_doc = doclines[1].strip()
802 except IndexError:
803 first_doc = ""
804 help_text.append("%s\n %s" % (name, first_doc))
806 if not found:
807 help_text.append("Nothing found.")
809 # Output
810 if output is not None:
811 output.write("\n".join(help_text))
812 elif len(help_text) > 10:
813 pager = pydoc.getpager()
814 pager("\n".join(help_text))
815 else:
816 print("\n".join(help_text))
818def _lookfor_generate_cache(module, import_modules, regenerate):
819 """
820 Generate docstring cache for given module.
822 Parameters
823 ----------
824 module : str, None, module
825 Module for which to generate docstring cache
826 import_modules : bool
827 Whether to import sub-modules in packages.
828 regenerate : bool
829 Re-generate the docstring cache
831 Returns
832 -------
833 cache : dict {obj_full_name: (docstring, kind, index), ...}
834 Docstring cache for the module, either cached one (regenerate=False)
835 or newly generated.
837 """
838 # Local import to speed up numpy's import time.
839 import inspect
841 from io import StringIO
843 if module is None:
844 module = "numpy"
846 if isinstance(module, str):
847 try:
848 __import__(module)
849 except ImportError:
850 return {}
851 module = sys.modules[module]
852 elif isinstance(module, list) or isinstance(module, tuple):
853 cache = {}
854 for mod in module:
855 cache.update(_lookfor_generate_cache(mod, import_modules,
856 regenerate))
857 return cache
859 if id(module) in _lookfor_caches and not regenerate:
860 return _lookfor_caches[id(module)]
862 # walk items and collect docstrings
863 cache = {}
864 _lookfor_caches[id(module)] = cache
865 seen = {}
866 index = 0
867 stack = [(module.__name__, module)]
868 while stack:
869 name, item = stack.pop(0)
870 if id(item) in seen:
871 continue
872 seen[id(item)] = True
874 index += 1
875 kind = "object"
877 if inspect.ismodule(item):
878 kind = "module"
879 try:
880 _all = item.__all__
881 except AttributeError:
882 _all = None
884 # import sub-packages
885 if import_modules and hasattr(item, '__path__'):
886 for pth in item.__path__:
887 for mod_path in os.listdir(pth):
888 this_py = os.path.join(pth, mod_path)
889 init_py = os.path.join(pth, mod_path, '__init__.py')
890 if (os.path.isfile(this_py) and
891 mod_path.endswith('.py')):
892 to_import = mod_path[:-3]
893 elif os.path.isfile(init_py):
894 to_import = mod_path
895 else:
896 continue
897 if to_import == '__init__':
898 continue
900 try:
901 old_stdout = sys.stdout
902 old_stderr = sys.stderr
903 try:
904 sys.stdout = StringIO()
905 sys.stderr = StringIO()
906 __import__("%s.%s" % (name, to_import))
907 finally:
908 sys.stdout = old_stdout
909 sys.stderr = old_stderr
910 except KeyboardInterrupt:
911 # Assume keyboard interrupt came from a user
912 raise
913 except BaseException:
914 # Ignore also SystemExit and pytests.importorskip
915 # `Skipped` (these are BaseExceptions; gh-22345)
916 continue
918 for n, v in _getmembers(item):
919 try:
920 item_name = getattr(v, '__name__', "%s.%s" % (name, n))
921 mod_name = getattr(v, '__module__', None)
922 except NameError:
923 # ref. SWIG's global cvars
924 # NameError: Unknown C global variable
925 item_name = "%s.%s" % (name, n)
926 mod_name = None
927 if '.' not in item_name and mod_name:
928 item_name = "%s.%s" % (mod_name, item_name)
930 if not item_name.startswith(name + '.'):
931 # don't crawl "foreign" objects
932 if isinstance(v, ufunc):
933 # ... unless they are ufuncs
934 pass
935 else:
936 continue
937 elif not (inspect.ismodule(v) or _all is None or n in _all):
938 continue
939 stack.append(("%s.%s" % (name, n), v))
940 elif inspect.isclass(item):
941 kind = "class"
942 for n, v in _getmembers(item):
943 stack.append(("%s.%s" % (name, n), v))
944 elif hasattr(item, "__call__"):
945 kind = "func"
947 try:
948 doc = inspect.getdoc(item)
949 except NameError:
950 # ref SWIG's NameError: Unknown C global variable
951 doc = None
952 if doc is not None:
953 cache[name] = (doc, kind, index)
955 return cache
957def _getmembers(item):
958 import inspect
959 try:
960 members = inspect.getmembers(item)
961 except Exception:
962 members = [(x, getattr(item, x)) for x in dir(item)
963 if hasattr(item, x)]
964 return members
967def safe_eval(source):
968 """
969 Protected string evaluation.
971 Evaluate a string containing a Python literal expression without
972 allowing the execution of arbitrary non-literal code.
974 .. warning::
976 This function is identical to :py:meth:`ast.literal_eval` and
977 has the same security implications. It may not always be safe
978 to evaluate large input strings.
980 Parameters
981 ----------
982 source : str
983 The string to evaluate.
985 Returns
986 -------
987 obj : object
988 The result of evaluating `source`.
990 Raises
991 ------
992 SyntaxError
993 If the code has invalid Python syntax, or if it contains
994 non-literal code.
996 Examples
997 --------
998 >>> np.safe_eval('1')
999 1
1000 >>> np.safe_eval('[1, 2, 3]')
1001 [1, 2, 3]
1002 >>> np.safe_eval('{"foo": ("bar", 10.0)}')
1003 {'foo': ('bar', 10.0)}
1005 >>> np.safe_eval('import os')
1006 Traceback (most recent call last):
1007 ...
1008 SyntaxError: invalid syntax
1010 >>> np.safe_eval('open("/home/user/.ssh/id_dsa").read()')
1011 Traceback (most recent call last):
1012 ...
1013 ValueError: malformed node or string: <_ast.Call object at 0x...>
1015 """
1016 # Local import to speed up numpy's import time.
1017 import ast
1018 return ast.literal_eval(source)
1021def _median_nancheck(data, result, axis):
1022 """
1023 Utility function to check median result from data for NaN values at the end
1024 and return NaN in that case. Input result can also be a MaskedArray.
1026 Parameters
1027 ----------
1028 data : array
1029 Sorted input data to median function
1030 result : Array or MaskedArray
1031 Result of median function.
1032 axis : int
1033 Axis along which the median was computed.
1035 Returns
1036 -------
1037 result : scalar or ndarray
1038 Median or NaN in axes which contained NaN in the input. If the input
1039 was an array, NaN will be inserted in-place. If a scalar, either the
1040 input itself or a scalar NaN.
1041 """
1042 if data.size == 0:
1043 return result
1044 n = np.isnan(data.take(-1, axis=axis))
1045 # masked NaN values are ok
1046 if np.ma.isMaskedArray(n):
1047 n = n.filled(False)
1048 if np.count_nonzero(n.ravel()) > 0:
1049 # Without given output, it is possible that the current result is a
1050 # numpy scalar, which is not writeable. If so, just return nan.
1051 if isinstance(result, np.generic):
1052 return data.dtype.type(np.nan)
1054 result[n] = np.nan
1055 return result
1057def _opt_info():
1058 """
1059 Returns a string contains the supported CPU features by the current build.
1061 The string format can be explained as follows:
1062 - dispatched features that are supported by the running machine
1063 end with `*`.
1064 - dispatched features that are "not" supported by the running machine
1065 end with `?`.
1066 - remained features are representing the baseline.
1067 """
1068 from numpy.core._multiarray_umath import (
1069 __cpu_features__, __cpu_baseline__, __cpu_dispatch__
1070 )
1072 if len(__cpu_baseline__) == 0 and len(__cpu_dispatch__) == 0:
1073 return ''
1075 enabled_features = ' '.join(__cpu_baseline__)
1076 for feature in __cpu_dispatch__:
1077 if __cpu_features__[feature]:
1078 enabled_features += f" {feature}*"
1079 else:
1080 enabled_features += f" {feature}?"
1082 return enabled_features
1083#-----------------------------------------------------------------------------