1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159 |
- from __future__ import division, absolute_import, print_function
- import os
- import sys
- import types
- import re
- import warnings
- from numpy.core.numerictypes import issubclass_, issubsctype, issubdtype
- from numpy.core.overrides import set_module
- from numpy.core import ndarray, ufunc, asarray
- import numpy as np
- # getargspec and formatargspec were removed in Python 3.6
- from numpy.compat import getargspec, formatargspec
- __all__ = [
- 'issubclass_', 'issubsctype', 'issubdtype', 'deprecate',
- 'deprecate_with_doc', 'get_include', 'info', 'source', 'who',
- 'lookfor', 'byte_bounds', 'safe_eval'
- ]
- def get_include():
- """
- Return the directory that contains the NumPy \\*.h header files.
- Extension modules that need to compile against NumPy should use this
- function to locate the appropriate include directory.
- Notes
- -----
- When using ``distutils``, for example in ``setup.py``.
- ::
- import numpy as np
- ...
- Extension('extension_name', ...
- include_dirs=[np.get_include()])
- ...
- """
- import numpy
- if numpy.show_config is None:
- # running from numpy source directory
- d = os.path.join(os.path.dirname(numpy.__file__), 'core', 'include')
- else:
- # using installed numpy core headers
- import numpy.core as core
- d = os.path.join(os.path.dirname(core.__file__), 'include')
- return d
- def _set_function_name(func, name):
- func.__name__ = name
- return func
- class _Deprecate(object):
- """
- Decorator class to deprecate old functions.
- Refer to `deprecate` for details.
- See Also
- --------
- deprecate
- """
- def __init__(self, old_name=None, new_name=None, message=None):
- self.old_name = old_name
- self.new_name = new_name
- self.message = message
- def __call__(self, func, *args, **kwargs):
- """
- Decorator call. Refer to ``decorate``.
- """
- old_name = self.old_name
- new_name = self.new_name
- message = self.message
- if old_name is None:
- try:
- old_name = func.__name__
- except AttributeError:
- old_name = func.__name__
- if new_name is None:
- depdoc = "`%s` is deprecated!" % old_name
- else:
- depdoc = "`%s` is deprecated, use `%s` instead!" % \
- (old_name, new_name)
- if message is not None:
- depdoc += "\n" + message
- def newfunc(*args,**kwds):
- """`arrayrange` is deprecated, use `arange` instead!"""
- warnings.warn(depdoc, DeprecationWarning, stacklevel=2)
- return func(*args, **kwds)
- newfunc = _set_function_name(newfunc, old_name)
- doc = func.__doc__
- if doc is None:
- doc = depdoc
- else:
- doc = '\n\n'.join([depdoc, doc])
- newfunc.__doc__ = doc
- try:
- d = func.__dict__
- except AttributeError:
- pass
- else:
- newfunc.__dict__.update(d)
- return newfunc
- def deprecate(*args, **kwargs):
- """
- Issues a DeprecationWarning, adds warning to `old_name`'s
- docstring, rebinds ``old_name.__name__`` and returns the new
- function object.
- This function may also be used as a decorator.
- Parameters
- ----------
- func : function
- The function to be deprecated.
- old_name : str, optional
- The name of the function to be deprecated. Default is None, in
- which case the name of `func` is used.
- new_name : str, optional
- The new name for the function. Default is None, in which case the
- deprecation message is that `old_name` is deprecated. If given, the
- deprecation message is that `old_name` is deprecated and `new_name`
- should be used instead.
- message : str, optional
- Additional explanation of the deprecation. Displayed in the
- docstring after the warning.
- Returns
- -------
- old_func : function
- The deprecated function.
- Examples
- --------
- Note that ``olduint`` returns a value after printing Deprecation
- Warning:
- >>> olduint = np.deprecate(np.uint)
- >>> olduint(6)
- /usr/lib/python2.5/site-packages/numpy/lib/utils.py:114:
- DeprecationWarning: uint32 is deprecated
- warnings.warn(str1, DeprecationWarning, stacklevel=2)
- 6
- """
- # Deprecate may be run as a function or as a decorator
- # If run as a function, we initialise the decorator class
- # and execute its __call__ method.
- if args:
- fn = args[0]
- args = args[1:]
- return _Deprecate(*args, **kwargs)(fn)
- else:
- return _Deprecate(*args, **kwargs)
- deprecate_with_doc = lambda msg: _Deprecate(message=msg)
- #--------------------------------------------
- # Determine if two arrays can share memory
- #--------------------------------------------
- def byte_bounds(a):
- """
- Returns pointers to the end-points of an array.
- Parameters
- ----------
- a : ndarray
- Input array. It must conform to the Python-side of the array
- interface.
- Returns
- -------
- (low, high) : tuple of 2 integers
- The first integer is the first byte of the array, the second
- integer is just past the last byte of the array. If `a` is not
- contiguous it will not use every byte between the (`low`, `high`)
- values.
- Examples
- --------
- >>> I = np.eye(2, dtype='f'); I.dtype
- dtype('float32')
- >>> low, high = np.byte_bounds(I)
- >>> high - low == I.size*I.itemsize
- True
- >>> I = np.eye(2, dtype='G'); I.dtype
- dtype('complex192')
- >>> low, high = np.byte_bounds(I)
- >>> high - low == I.size*I.itemsize
- True
- """
- ai = a.__array_interface__
- a_data = ai['data'][0]
- astrides = ai['strides']
- ashape = ai['shape']
- bytes_a = asarray(a).dtype.itemsize
- a_low = a_high = a_data
- if astrides is None:
- # contiguous case
- a_high += a.size * bytes_a
- else:
- for shape, stride in zip(ashape, astrides):
- if stride < 0:
- a_low += (shape-1)*stride
- else:
- a_high += (shape-1)*stride
- a_high += bytes_a
- return a_low, a_high
- #-----------------------------------------------------------------------------
- # Function for output and information on the variables used.
- #-----------------------------------------------------------------------------
- def who(vardict=None):
- """
- Print the NumPy arrays in the given dictionary.
- If there is no dictionary passed in or `vardict` is None then returns
- NumPy arrays in the globals() dictionary (all NumPy arrays in the
- namespace).
- Parameters
- ----------
- vardict : dict, optional
- A dictionary possibly containing ndarrays. Default is globals().
- Returns
- -------
- out : None
- Returns 'None'.
- Notes
- -----
- Prints out the name, shape, bytes and type of all of the ndarrays
- present in `vardict`.
- Examples
- --------
- >>> a = np.arange(10)
- >>> b = np.ones(20)
- >>> np.who()
- Name Shape Bytes Type
- ===========================================================
- a 10 40 int32
- b 20 160 float64
- Upper bound on total bytes = 200
- >>> d = {'x': np.arange(2.0), 'y': np.arange(3.0), 'txt': 'Some str',
- ... 'idx':5}
- >>> np.who(d)
- Name Shape Bytes Type
- ===========================================================
- y 3 24 float64
- x 2 16 float64
- Upper bound on total bytes = 40
- """
- if vardict is None:
- frame = sys._getframe().f_back
- vardict = frame.f_globals
- sta = []
- cache = {}
- for name in vardict.keys():
- if isinstance(vardict[name], ndarray):
- var = vardict[name]
- idv = id(var)
- if idv in cache.keys():
- namestr = name + " (%s)" % cache[idv]
- original = 0
- else:
- cache[idv] = name
- namestr = name
- original = 1
- shapestr = " x ".join(map(str, var.shape))
- bytestr = str(var.nbytes)
- sta.append([namestr, shapestr, bytestr, var.dtype.name,
- original])
- maxname = 0
- maxshape = 0
- maxbyte = 0
- totalbytes = 0
- for k in range(len(sta)):
- val = sta[k]
- if maxname < len(val[0]):
- maxname = len(val[0])
- if maxshape < len(val[1]):
- maxshape = len(val[1])
- if maxbyte < len(val[2]):
- maxbyte = len(val[2])
- if val[4]:
- totalbytes += int(val[2])
- if len(sta) > 0:
- sp1 = max(10, maxname)
- sp2 = max(10, maxshape)
- sp3 = max(10, maxbyte)
- prval = "Name %s Shape %s Bytes %s Type" % (sp1*' ', sp2*' ', sp3*' ')
- print(prval + "\n" + "="*(len(prval)+5) + "\n")
- for k in range(len(sta)):
- val = sta[k]
- print("%s %s %s %s %s %s %s" % (val[0], ' '*(sp1-len(val[0])+4),
- val[1], ' '*(sp2-len(val[1])+5),
- val[2], ' '*(sp3-len(val[2])+5),
- val[3]))
- print("\nUpper bound on total bytes = %d" % totalbytes)
- return
- #-----------------------------------------------------------------------------
- # NOTE: pydoc defines a help function which works similarly to this
- # except it uses a pager to take over the screen.
- # combine name and arguments and split to multiple lines of width
- # characters. End lines on a comma and begin argument list indented with
- # the rest of the arguments.
- def _split_line(name, arguments, width):
- firstwidth = len(name)
- k = firstwidth
- newstr = name
- sepstr = ", "
- arglist = arguments.split(sepstr)
- for argument in arglist:
- if k == firstwidth:
- addstr = ""
- else:
- addstr = sepstr
- k = k + len(argument) + len(addstr)
- if k > width:
- k = firstwidth + 1 + len(argument)
- newstr = newstr + ",\n" + " "*(firstwidth+2) + argument
- else:
- newstr = newstr + addstr + argument
- return newstr
- _namedict = None
- _dictlist = None
- # Traverse all module directories underneath globals
- # to see if something is defined
- def _makenamedict(module='numpy'):
- module = __import__(module, globals(), locals(), [])
- thedict = {module.__name__:module.__dict__}
- dictlist = [module.__name__]
- totraverse = [module.__dict__]
- while True:
- if len(totraverse) == 0:
- break
- thisdict = totraverse.pop(0)
- for x in thisdict.keys():
- if isinstance(thisdict[x], types.ModuleType):
- modname = thisdict[x].__name__
- if modname not in dictlist:
- moddict = thisdict[x].__dict__
- dictlist.append(modname)
- totraverse.append(moddict)
- thedict[modname] = moddict
- return thedict, dictlist
- def _info(obj, output=sys.stdout):
- """Provide information about ndarray obj.
- Parameters
- ----------
- obj : ndarray
- Must be ndarray, not checked.
- output
- Where printed output goes.
- Notes
- -----
- Copied over from the numarray module prior to its removal.
- Adapted somewhat as only numpy is an option now.
- Called by info.
- """
- extra = ""
- tic = ""
- bp = lambda x: x
- cls = getattr(obj, '__class__', type(obj))
- nm = getattr(cls, '__name__', cls)
- strides = obj.strides
- endian = obj.dtype.byteorder
- print("class: ", nm, file=output)
- print("shape: ", obj.shape, file=output)
- print("strides: ", strides, file=output)
- print("itemsize: ", obj.itemsize, file=output)
- print("aligned: ", bp(obj.flags.aligned), file=output)
- print("contiguous: ", bp(obj.flags.contiguous), file=output)
- print("fortran: ", obj.flags.fortran, file=output)
- print(
- "data pointer: %s%s" % (hex(obj.ctypes._as_parameter_.value), extra),
- file=output
- )
- print("byteorder: ", end=' ', file=output)
- if endian in ['|', '=']:
- print("%s%s%s" % (tic, sys.byteorder, tic), file=output)
- byteswap = False
- elif endian == '>':
- print("%sbig%s" % (tic, tic), file=output)
- byteswap = sys.byteorder != "big"
- else:
- print("%slittle%s" % (tic, tic), file=output)
- byteswap = sys.byteorder != "little"
- print("byteswap: ", bp(byteswap), file=output)
- print("type: %s" % obj.dtype, file=output)
- @set_module('numpy')
- def info(object=None, maxwidth=76, output=sys.stdout, toplevel='numpy'):
- """
- Get help information for a function, class, or module.
- Parameters
- ----------
- object : object or str, optional
- Input object or name to get information about. If `object` is a
- numpy object, its docstring is given. If it is a string, available
- modules are searched for matching objects. If None, information
- about `info` itself is returned.
- maxwidth : int, optional
- Printing width.
- output : file like object, optional
- File like object that the output is written to, default is
- ``stdout``. The object has to be opened in 'w' or 'a' mode.
- toplevel : str, optional
- Start search at this level.
- See Also
- --------
- source, lookfor
- Notes
- -----
- When used interactively with an object, ``np.info(obj)`` is equivalent
- to ``help(obj)`` on the Python prompt or ``obj?`` on the IPython
- prompt.
- Examples
- --------
- >>> np.info(np.polyval) # doctest: +SKIP
- polyval(p, x)
- Evaluate the polynomial p at x.
- ...
- When using a string for `object` it is possible to get multiple results.
- >>> np.info('fft') # doctest: +SKIP
- *** Found in numpy ***
- Core FFT routines
- ...
- *** Found in numpy.fft ***
- fft(a, n=None, axis=-1)
- ...
- *** Repeat reference found in numpy.fft.fftpack ***
- *** Total of 3 references found. ***
- """
- global _namedict, _dictlist
- # Local import to speed up numpy's import time.
- import pydoc
- import inspect
- if (hasattr(object, '_ppimport_importer') or
- hasattr(object, '_ppimport_module')):
- object = object._ppimport_module
- elif hasattr(object, '_ppimport_attr'):
- object = object._ppimport_attr
- if object is None:
- info(info)
- elif isinstance(object, ndarray):
- _info(object, output=output)
- elif isinstance(object, str):
- if _namedict is None:
- _namedict, _dictlist = _makenamedict(toplevel)
- numfound = 0
- objlist = []
- for namestr in _dictlist:
- try:
- obj = _namedict[namestr][object]
- if id(obj) in objlist:
- print("\n "
- "*** Repeat reference found in %s *** " % namestr,
- file=output
- )
- else:
- objlist.append(id(obj))
- print(" *** Found in %s ***" % namestr, file=output)
- info(obj)
- print("-"*maxwidth, file=output)
- numfound += 1
- except KeyError:
- pass
- if numfound == 0:
- print("Help for %s not found." % object, file=output)
- else:
- print("\n "
- "*** Total of %d references found. ***" % numfound,
- file=output
- )
- elif inspect.isfunction(object):
- name = object.__name__
- arguments = formatargspec(*getargspec(object))
- if len(name+arguments) > maxwidth:
- argstr = _split_line(name, arguments, maxwidth)
- else:
- argstr = name + arguments
- print(" " + argstr + "\n", file=output)
- print(inspect.getdoc(object), file=output)
- elif inspect.isclass(object):
- name = object.__name__
- arguments = "()"
- try:
- if hasattr(object, '__init__'):
- arguments = formatargspec(
- *getargspec(object.__init__.__func__)
- )
- arglist = arguments.split(', ')
- if len(arglist) > 1:
- arglist[1] = "("+arglist[1]
- arguments = ", ".join(arglist[1:])
- except Exception:
- pass
- if len(name+arguments) > maxwidth:
- argstr = _split_line(name, arguments, maxwidth)
- else:
- argstr = name + arguments
- print(" " + argstr + "\n", file=output)
- doc1 = inspect.getdoc(object)
- if doc1 is None:
- if hasattr(object, '__init__'):
- print(inspect.getdoc(object.__init__), file=output)
- else:
- print(inspect.getdoc(object), file=output)
- methods = pydoc.allmethods(object)
- if methods != []:
- print("\n\nMethods:\n", file=output)
- for meth in methods:
- if meth[0] == '_':
- continue
- thisobj = getattr(object, meth, None)
- if thisobj is not None:
- methstr, other = pydoc.splitdoc(
- inspect.getdoc(thisobj) or "None"
- )
- print(" %s -- %s" % (meth, methstr), file=output)
- elif (sys.version_info[0] < 3
- and isinstance(object, types.InstanceType)):
- # check for __call__ method
- # types.InstanceType is the type of the instances of oldstyle classes
- print("Instance of class: ", object.__class__.__name__, file=output)
- print(file=output)
- if hasattr(object, '__call__'):
- arguments = formatargspec(
- *getargspec(object.__call__.__func__)
- )
- arglist = arguments.split(', ')
- if len(arglist) > 1:
- arglist[1] = "("+arglist[1]
- arguments = ", ".join(arglist[1:])
- else:
- arguments = "()"
- if hasattr(object, 'name'):
- name = "%s" % object.name
- else:
- name = "<name>"
- if len(name+arguments) > maxwidth:
- argstr = _split_line(name, arguments, maxwidth)
- else:
- argstr = name + arguments
- print(" " + argstr + "\n", file=output)
- doc = inspect.getdoc(object.__call__)
- if doc is not None:
- print(inspect.getdoc(object.__call__), file=output)
- print(inspect.getdoc(object), file=output)
- else:
- print(inspect.getdoc(object), file=output)
- elif inspect.ismethod(object):
- name = object.__name__
- arguments = formatargspec(
- *getargspec(object.__func__)
- )
- arglist = arguments.split(', ')
- if len(arglist) > 1:
- arglist[1] = "("+arglist[1]
- arguments = ", ".join(arglist[1:])
- else:
- arguments = "()"
- if len(name+arguments) > maxwidth:
- argstr = _split_line(name, arguments, maxwidth)
- else:
- argstr = name + arguments
- print(" " + argstr + "\n", file=output)
- print(inspect.getdoc(object), file=output)
- elif hasattr(object, '__doc__'):
- print(inspect.getdoc(object), file=output)
- @set_module('numpy')
- def source(object, output=sys.stdout):
- """
- Print or write to a file the source code for a NumPy object.
- The source code is only returned for objects written in Python. Many
- functions and classes are defined in C and will therefore not return
- useful information.
- Parameters
- ----------
- object : numpy object
- Input object. This can be any object (function, class, module,
- ...).
- output : file object, optional
- If `output` not supplied then source code is printed to screen
- (sys.stdout). File object must be created with either write 'w' or
- append 'a' modes.
- See Also
- --------
- lookfor, info
- Examples
- --------
- >>> np.source(np.interp) #doctest: +SKIP
- In file: /usr/lib/python2.6/dist-packages/numpy/lib/function_base.py
- def interp(x, xp, fp, left=None, right=None):
- \"\"\".... (full docstring printed)\"\"\"
- if isinstance(x, (float, int, number)):
- return compiled_interp([x], xp, fp, left, right).item()
- else:
- return compiled_interp(x, xp, fp, left, right)
- The source code is only returned for objects written in Python.
- >>> np.source(np.array) #doctest: +SKIP
- Not available for this object.
- """
- # Local import to speed up numpy's import time.
- import inspect
- try:
- print("In file: %s\n" % inspect.getsourcefile(object), file=output)
- print(inspect.getsource(object), file=output)
- except Exception:
- print("Not available for this object.", file=output)
- # Cache for lookfor: {id(module): {name: (docstring, kind, index), ...}...}
- # where kind: "func", "class", "module", "object"
- # and index: index in breadth-first namespace traversal
- _lookfor_caches = {}
- # regexp whose match indicates that the string may contain a function
- # signature
- _function_signature_re = re.compile(r"[a-z0-9_]+\(.*[,=].*\)", re.I)
- @set_module('numpy')
- def lookfor(what, module=None, import_modules=True, regenerate=False,
- output=None):
- """
- Do a keyword search on docstrings.
- A list of objects that matched the search is displayed,
- sorted by relevance. All given keywords need to be found in the
- docstring for it to be returned as a result, but the order does
- not matter.
- Parameters
- ----------
- what : str
- String containing words to look for.
- module : str or list, optional
- Name of module(s) whose docstrings to go through.
- import_modules : bool, optional
- Whether to import sub-modules in packages. Default is True.
- regenerate : bool, optional
- Whether to re-generate the docstring cache. Default is False.
- output : file-like, optional
- File-like object to write the output to. If omitted, use a pager.
- See Also
- --------
- source, info
- Notes
- -----
- Relevance is determined only roughly, by checking if the keywords occur
- in the function name, at the start of a docstring, etc.
- Examples
- --------
- >>> np.lookfor('binary representation')
- Search results for 'binary representation'
- ------------------------------------------
- numpy.binary_repr
- Return the binary representation of the input number as a string.
- numpy.core.setup_common.long_double_representation
- Given a binary dump as given by GNU od -b, look for long double
- numpy.base_repr
- Return a string representation of a number in the given base system.
- ...
- """
- import pydoc
- # Cache
- cache = _lookfor_generate_cache(module, import_modules, regenerate)
- # Search
- # XXX: maybe using a real stemming search engine would be better?
- found = []
- whats = str(what).lower().split()
- if not whats:
- return
- for name, (docstring, kind, index) in cache.items():
- if kind in ('module', 'object'):
- # don't show modules or objects
- continue
- ok = True
- doc = docstring.lower()
- for w in whats:
- if w not in doc:
- ok = False
- break
- if ok:
- found.append(name)
- # Relevance sort
- # XXX: this is full Harrison-Stetson heuristics now,
- # XXX: it probably could be improved
- kind_relevance = {'func': 1000, 'class': 1000,
- 'module': -1000, 'object': -1000}
- def relevance(name, docstr, kind, index):
- r = 0
- # do the keywords occur within the start of the docstring?
- first_doc = "\n".join(docstr.lower().strip().split("\n")[:3])
- r += sum([200 for w in whats if w in first_doc])
- # do the keywords occur in the function name?
- r += sum([30 for w in whats if w in name])
- # is the full name long?
- r += -len(name) * 5
- # is the object of bad type?
- r += kind_relevance.get(kind, -1000)
- # is the object deep in namespace hierarchy?
- r += -name.count('.') * 10
- r += max(-index / 100, -100)
- return r
- def relevance_value(a):
- return relevance(a, *cache[a])
- found.sort(key=relevance_value)
- # Pretty-print
- s = "Search results for '%s'" % (' '.join(whats))
- help_text = [s, "-"*len(s)]
- for name in found[::-1]:
- doc, kind, ix = cache[name]
- doclines = [line.strip() for line in doc.strip().split("\n")
- if line.strip()]
- # find a suitable short description
- try:
- first_doc = doclines[0].strip()
- if _function_signature_re.search(first_doc):
- first_doc = doclines[1].strip()
- except IndexError:
- first_doc = ""
- help_text.append("%s\n %s" % (name, first_doc))
- if not found:
- help_text.append("Nothing found.")
- # Output
- if output is not None:
- output.write("\n".join(help_text))
- elif len(help_text) > 10:
- pager = pydoc.getpager()
- pager("\n".join(help_text))
- else:
- print("\n".join(help_text))
- def _lookfor_generate_cache(module, import_modules, regenerate):
- """
- Generate docstring cache for given module.
- Parameters
- ----------
- module : str, None, module
- Module for which to generate docstring cache
- import_modules : bool
- Whether to import sub-modules in packages.
- regenerate : bool
- Re-generate the docstring cache
- Returns
- -------
- cache : dict {obj_full_name: (docstring, kind, index), ...}
- Docstring cache for the module, either cached one (regenerate=False)
- or newly generated.
- """
- global _lookfor_caches
- # Local import to speed up numpy's import time.
- import inspect
- if sys.version_info[0] >= 3:
- # In Python3 stderr, stdout are text files.
- from io import StringIO
- else:
- from StringIO import StringIO
- if module is None:
- module = "numpy"
- if isinstance(module, str):
- try:
- __import__(module)
- except ImportError:
- return {}
- module = sys.modules[module]
- elif isinstance(module, list) or isinstance(module, tuple):
- cache = {}
- for mod in module:
- cache.update(_lookfor_generate_cache(mod, import_modules,
- regenerate))
- return cache
- if id(module) in _lookfor_caches and not regenerate:
- return _lookfor_caches[id(module)]
- # walk items and collect docstrings
- cache = {}
- _lookfor_caches[id(module)] = cache
- seen = {}
- index = 0
- stack = [(module.__name__, module)]
- while stack:
- name, item = stack.pop(0)
- if id(item) in seen:
- continue
- seen[id(item)] = True
- index += 1
- kind = "object"
- if inspect.ismodule(item):
- kind = "module"
- try:
- _all = item.__all__
- except AttributeError:
- _all = None
- # import sub-packages
- if import_modules and hasattr(item, '__path__'):
- for pth in item.__path__:
- for mod_path in os.listdir(pth):
- this_py = os.path.join(pth, mod_path)
- init_py = os.path.join(pth, mod_path, '__init__.py')
- if (os.path.isfile(this_py) and
- mod_path.endswith('.py')):
- to_import = mod_path[:-3]
- elif os.path.isfile(init_py):
- to_import = mod_path
- else:
- continue
- if to_import == '__init__':
- continue
- try:
- old_stdout = sys.stdout
- old_stderr = sys.stderr
- try:
- sys.stdout = StringIO()
- sys.stderr = StringIO()
- __import__("%s.%s" % (name, to_import))
- finally:
- sys.stdout = old_stdout
- sys.stderr = old_stderr
- # Catch SystemExit, too
- except BaseException:
- continue
- for n, v in _getmembers(item):
- try:
- item_name = getattr(v, '__name__', "%s.%s" % (name, n))
- mod_name = getattr(v, '__module__', None)
- except NameError:
- # ref. SWIG's global cvars
- # NameError: Unknown C global variable
- item_name = "%s.%s" % (name, n)
- mod_name = None
- if '.' not in item_name and mod_name:
- item_name = "%s.%s" % (mod_name, item_name)
- if not item_name.startswith(name + '.'):
- # don't crawl "foreign" objects
- if isinstance(v, ufunc):
- # ... unless they are ufuncs
- pass
- else:
- continue
- elif not (inspect.ismodule(v) or _all is None or n in _all):
- continue
- stack.append(("%s.%s" % (name, n), v))
- elif inspect.isclass(item):
- kind = "class"
- for n, v in _getmembers(item):
- stack.append(("%s.%s" % (name, n), v))
- elif hasattr(item, "__call__"):
- kind = "func"
- try:
- doc = inspect.getdoc(item)
- except NameError:
- # ref SWIG's NameError: Unknown C global variable
- doc = None
- if doc is not None:
- cache[name] = (doc, kind, index)
- return cache
- def _getmembers(item):
- import inspect
- try:
- members = inspect.getmembers(item)
- except Exception:
- members = [(x, getattr(item, x)) for x in dir(item)
- if hasattr(item, x)]
- return members
- #-----------------------------------------------------------------------------
- # The following SafeEval class and company are adapted from Michael Spencer's
- # ASPN Python Cookbook recipe: https://code.activestate.com/recipes/364469/
- #
- # Accordingly it is mostly Copyright 2006 by Michael Spencer.
- # The recipe, like most of the other ASPN Python Cookbook recipes was made
- # available under the Python license.
- # https://en.wikipedia.org/wiki/Python_License
- # It has been modified to:
- # * handle unary -/+
- # * support True/False/None
- # * raise SyntaxError instead of a custom exception.
- class SafeEval(object):
- """
- Object to evaluate constant string expressions.
- This includes strings with lists, dicts and tuples using the abstract
- syntax tree created by ``compiler.parse``.
- .. deprecated:: 1.10.0
- See Also
- --------
- safe_eval
- """
- def __init__(self):
- # 2014-10-15, 1.10
- warnings.warn("SafeEval is deprecated in 1.10 and will be removed.",
- DeprecationWarning, stacklevel=2)
- def visit(self, node):
- cls = node.__class__
- meth = getattr(self, 'visit' + cls.__name__, self.default)
- return meth(node)
- def default(self, node):
- raise SyntaxError("Unsupported source construct: %s"
- % node.__class__)
- def visitExpression(self, node):
- return self.visit(node.body)
- def visitNum(self, node):
- return node.n
- def visitStr(self, node):
- return node.s
- def visitBytes(self, node):
- return node.s
- def visitDict(self, node,**kw):
- return dict([(self.visit(k), self.visit(v))
- for k, v in zip(node.keys, node.values)])
- def visitTuple(self, node):
- return tuple([self.visit(i) for i in node.elts])
- def visitList(self, node):
- return [self.visit(i) for i in node.elts]
- def visitUnaryOp(self, node):
- import ast
- if isinstance(node.op, ast.UAdd):
- return +self.visit(node.operand)
- elif isinstance(node.op, ast.USub):
- return -self.visit(node.operand)
- else:
- raise SyntaxError("Unknown unary op: %r" % node.op)
- def visitName(self, node):
- if node.id == 'False':
- return False
- elif node.id == 'True':
- return True
- elif node.id == 'None':
- return None
- else:
- raise SyntaxError("Unknown name: %s" % node.id)
- def visitNameConstant(self, node):
- return node.value
- def safe_eval(source):
- """
- Protected string evaluation.
- Evaluate a string containing a Python literal expression without
- allowing the execution of arbitrary non-literal code.
- Parameters
- ----------
- source : str
- The string to evaluate.
- Returns
- -------
- obj : object
- The result of evaluating `source`.
- Raises
- ------
- SyntaxError
- If the code has invalid Python syntax, or if it contains
- non-literal code.
- Examples
- --------
- >>> np.safe_eval('1')
- 1
- >>> np.safe_eval('[1, 2, 3]')
- [1, 2, 3]
- >>> np.safe_eval('{"foo": ("bar", 10.0)}')
- {'foo': ('bar', 10.0)}
- >>> np.safe_eval('import os')
- Traceback (most recent call last):
- ...
- SyntaxError: invalid syntax
- >>> np.safe_eval('open("/home/user/.ssh/id_dsa").read()')
- Traceback (most recent call last):
- ...
- SyntaxError: Unsupported source construct: compiler.ast.CallFunc
- """
- # Local import to speed up numpy's import time.
- import ast
- return ast.literal_eval(source)
- def _median_nancheck(data, result, axis, out):
- """
- Utility function to check median result from data for NaN values at the end
- and return NaN in that case. Input result can also be a MaskedArray.
- Parameters
- ----------
- data : array
- Input data to median function
- result : Array or MaskedArray
- Result of median function
- axis : {int, sequence of int, None}, optional
- Axis or axes along which the median was computed.
- out : ndarray, optional
- Output array in which to place the result.
- Returns
- -------
- median : scalar or ndarray
- Median or NaN in axes which contained NaN in the input.
- """
- if data.size == 0:
- return result
- data = np.moveaxis(data, axis, -1)
- n = np.isnan(data[..., -1])
- # masked NaN values are ok
- if np.ma.isMaskedArray(n):
- n = n.filled(False)
- if result.ndim == 0:
- if n == True:
- warnings.warn("Invalid value encountered in median",
- RuntimeWarning, stacklevel=3)
- if out is not None:
- out[...] = data.dtype.type(np.nan)
- result = out
- else:
- result = data.dtype.type(np.nan)
- elif np.count_nonzero(n.ravel()) > 0:
- warnings.warn("Invalid value encountered in median for" +
- " %d results" % np.count_nonzero(n.ravel()),
- RuntimeWarning, stacklevel=3)
- result[n] = np.nan
- return result
- #-----------------------------------------------------------------------------
|