diff options
Diffstat (limited to 'Lib/pydoc.py')
-rwxr-xr-x | Lib/pydoc.py | 83 |
1 files changed, 29 insertions, 54 deletions
diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 9dce079..bc64407 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -44,16 +44,16 @@ Richard Chamberlain, for the first implementation of textdoc. """ # Known bugs that can't be fixed here: -# - imp.load_module() cannot be prevented from clobbering existing -# loaded modules, so calling synopsis() on a binary module file -# changes the contents of any existing module with the same name. +# - synopsis() cannot be prevented from clobbering existing +# loaded modules. # - If the __file__ attribute on a module is a relative path and # the current directory is changed with os.chdir(), an incorrect # path will be displayed. import builtins -import imp +import importlib._bootstrap import importlib.machinery +import importlib.util import inspect import io import os @@ -226,7 +226,7 @@ def synopsis(filename, cache={}): if lastupdate is None or lastupdate < mtime: try: file = tokenize.open(filename) - except IOError: + except OSError: # module can't be opened, so skip it return None binary_suffixes = importlib.machinery.BYTECODE_SUFFIXES[:] @@ -267,20 +267,19 @@ class ErrorDuringImport(Exception): def importfile(path): """Import a Python source file or compiled file given its path.""" - magic = imp.get_magic() + magic = importlib.util.MAGIC_NUMBER with open(path, 'rb') as file: - if file.read(len(magic)) == magic: - kind = imp.PY_COMPILED - else: - kind = imp.PY_SOURCE - file.seek(0) - filename = os.path.basename(path) - name, ext = os.path.splitext(filename) - try: - module = imp.load_module(name, file, path, (ext, 'r', kind)) - except: - raise ErrorDuringImport(path, sys.exc_info()) - return module + is_bytecode = magic == file.read(len(magic)) + filename = os.path.basename(path) + name, ext = os.path.splitext(filename) + if is_bytecode: + loader = importlib._bootstrap.SourcelessFileLoader(name, path) + else: + loader = importlib._bootstrap.SourceFileLoader(name, path) + try: + return loader.load_module(name) + except: + raise ErrorDuringImport(path, sys.exc_info()) def safeimport(path, forceload=0, cache={}): """Import a module; handle errors; return None if the module isn't found. @@ -1396,7 +1395,7 @@ def getpager(): return lambda text: pipepager(text, os.environ['PAGER']) if os.environ.get('TERM') in ('dumb', 'emacs'): return plainpager - if sys.platform == 'win32' or sys.platform.startswith('os2'): + if sys.platform == 'win32': return lambda text: tempfilepager(plain(text), 'more <') if hasattr(os, 'system') and os.system('(less) 2>/dev/null') == 0: return lambda text: pipepager(text, 'less') @@ -1422,16 +1421,15 @@ def pipepager(text, cmd): try: pipe.write(text) pipe.close() - except IOError: + except OSError: pass # Ignore broken pipes caused by quitting the pager program. def tempfilepager(text, cmd): """Page through text by invoking a program on a temporary file.""" import tempfile filename = tempfile.mktemp() - file = open(filename, 'w') - file.write(text) - file.close() + with open(filename, 'w') as file: + file.write(text) try: os.system(cmd + ' "' + filename + '"') finally: @@ -1850,10 +1848,10 @@ Enter the name of any module, keyword, or topic to get help on writing Python programs and using Python modules. To quit this help utility and return to the interpreter, just type "quit". -To get a list of available modules, keywords, or topics, type "modules", -"keywords", or "topics". Each module also comes with a one-line summary -of what it does; to list the modules whose summaries contain a given word -such as "spam", type "modules spam". +To get a list of available modules, keywords, symbols, or topics, type +"modules", "keywords", "symbols", or "topics". Each module also comes +with a one-line summary of what it does; to list the modules whose name +or summary contain a given string such as "spam", type "modules spam". ''' % tuple([sys.version[:3]]*2)) def list(self, items, columns=4, width=80): @@ -1958,9 +1956,10 @@ module "pydoc_data.topics" could not be found. def listmodules(self, key=''): if key: self.output.write(''' -Here is a list of matching modules. Enter any module name to get more help. +Here is a list of modules whose name or summary contains '{}'. +If there are any, enter a module name to get more help. -''') +'''.format(key)) apropos(key) else: self.output.write(''' @@ -1979,35 +1978,11 @@ Please wait a moment while I gather a list of all available modules... self.list(modules.keys()) self.output.write(''' Enter any module name to get more help. Or, type "modules spam" to search -for modules whose descriptions contain the word "spam". +for modules whose name or summary contain the string "spam". ''') help = Helper() -class Scanner: - """A generic tree iterator.""" - def __init__(self, roots, children, descendp): - self.roots = roots[:] - self.state = [] - self.children = children - self.descendp = descendp - - def next(self): - if not self.state: - if not self.roots: - return None - root = self.roots.pop(0) - self.state = [(root, self.children(root))] - node, children = self.state[-1] - if not children: - self.state.pop() - return self.next() - child = children.pop(0) - if self.descendp(child): - self.state.append((child, self.children(child))) - return child - - class ModuleScanner: """An interruptible scanner that searches module synopses.""" |