Edit File by line
/home/barbar84/www/wp-conte.../plugins/sujqvwi/AnonR/anonr.TX.../usr/lib64/python3....
File: pydoc.py
"""Generate Python documentation in HTML or text for interactive use.
[0] Fix | Delete
[1] Fix | Delete
At the Python interactive prompt, calling help(thing) on a Python object
[2] Fix | Delete
documents the object, and calling help() starts up an interactive
[3] Fix | Delete
help session.
[4] Fix | Delete
[5] Fix | Delete
Or, at the shell command line outside of Python:
[6] Fix | Delete
[7] Fix | Delete
Run "pydoc <name>" to show documentation on something. <name> may be
[8] Fix | Delete
the name of a function, module, package, or a dotted reference to a
[9] Fix | Delete
class or function within a module or module in a package. If the
[10] Fix | Delete
argument contains a path segment delimiter (e.g. slash on Unix,
[11] Fix | Delete
backslash on Windows) it is treated as the path to a Python source file.
[12] Fix | Delete
[13] Fix | Delete
Run "pydoc -k <keyword>" to search for a keyword in the synopsis lines
[14] Fix | Delete
of all available modules.
[15] Fix | Delete
[16] Fix | Delete
Run "pydoc -n <hostname>" to start an HTTP server with the given
[17] Fix | Delete
hostname (default: localhost) on the local machine.
[18] Fix | Delete
[19] Fix | Delete
Run "pydoc -p <port>" to start an HTTP server on the given port on the
[20] Fix | Delete
local machine. Port number 0 can be used to get an arbitrary unused port.
[21] Fix | Delete
[22] Fix | Delete
Run "pydoc -b" to start an HTTP server on an arbitrary unused port and
[23] Fix | Delete
open a Web browser to interactively browse documentation. Combine with
[24] Fix | Delete
the -n and -p options to control the hostname and port used.
[25] Fix | Delete
[26] Fix | Delete
Run "pydoc -w <name>" to write out the HTML documentation for a module
[27] Fix | Delete
to a file named "<name>.html".
[28] Fix | Delete
[29] Fix | Delete
Module docs for core modules are assumed to be in
[30] Fix | Delete
[31] Fix | Delete
https://docs.python.org/X.Y/library/
[32] Fix | Delete
[33] Fix | Delete
This can be overridden by setting the PYTHONDOCS environment variable
[34] Fix | Delete
to a different URL or to a local directory containing the Library
[35] Fix | Delete
Reference Manual pages.
[36] Fix | Delete
"""
[37] Fix | Delete
__all__ = ['help']
[38] Fix | Delete
__author__ = "Ka-Ping Yee <ping@lfw.org>"
[39] Fix | Delete
__date__ = "26 February 2001"
[40] Fix | Delete
[41] Fix | Delete
__credits__ = """Guido van Rossum, for an excellent programming language.
[42] Fix | Delete
Tommy Burnette, the original creator of manpy.
[43] Fix | Delete
Paul Prescod, for all his work on onlinehelp.
[44] Fix | Delete
Richard Chamberlain, for the first implementation of textdoc.
[45] Fix | Delete
"""
[46] Fix | Delete
[47] Fix | Delete
# Known bugs that can't be fixed here:
[48] Fix | Delete
# - synopsis() cannot be prevented from clobbering existing
[49] Fix | Delete
# loaded modules.
[50] Fix | Delete
# - If the __file__ attribute on a module is a relative path and
[51] Fix | Delete
# the current directory is changed with os.chdir(), an incorrect
[52] Fix | Delete
# path will be displayed.
[53] Fix | Delete
[54] Fix | Delete
import builtins
[55] Fix | Delete
import importlib._bootstrap
[56] Fix | Delete
import importlib._bootstrap_external
[57] Fix | Delete
import importlib.machinery
[58] Fix | Delete
import importlib.util
[59] Fix | Delete
import inspect
[60] Fix | Delete
import io
[61] Fix | Delete
import os
[62] Fix | Delete
import pkgutil
[63] Fix | Delete
import platform
[64] Fix | Delete
import re
[65] Fix | Delete
import sys
[66] Fix | Delete
import sysconfig
[67] Fix | Delete
import time
[68] Fix | Delete
import tokenize
[69] Fix | Delete
import urllib.parse
[70] Fix | Delete
import warnings
[71] Fix | Delete
from collections import deque
[72] Fix | Delete
from reprlib import Repr
[73] Fix | Delete
from traceback import format_exception_only
[74] Fix | Delete
[75] Fix | Delete
[76] Fix | Delete
# --------------------------------------------------------- common routines
[77] Fix | Delete
[78] Fix | Delete
def pathdirs():
[79] Fix | Delete
"""Convert sys.path into a list of absolute, existing, unique paths."""
[80] Fix | Delete
dirs = []
[81] Fix | Delete
normdirs = []
[82] Fix | Delete
for dir in sys.path:
[83] Fix | Delete
dir = os.path.abspath(dir or '.')
[84] Fix | Delete
normdir = os.path.normcase(dir)
[85] Fix | Delete
if normdir not in normdirs and os.path.isdir(dir):
[86] Fix | Delete
dirs.append(dir)
[87] Fix | Delete
normdirs.append(normdir)
[88] Fix | Delete
return dirs
[89] Fix | Delete
[90] Fix | Delete
def getdoc(object):
[91] Fix | Delete
"""Get the doc string or comments for an object."""
[92] Fix | Delete
result = inspect.getdoc(object) or inspect.getcomments(object)
[93] Fix | Delete
return result and re.sub('^ *\n', '', result.rstrip()) or ''
[94] Fix | Delete
[95] Fix | Delete
def splitdoc(doc):
[96] Fix | Delete
"""Split a doc string into a synopsis line (if any) and the rest."""
[97] Fix | Delete
lines = doc.strip().split('\n')
[98] Fix | Delete
if len(lines) == 1:
[99] Fix | Delete
return lines[0], ''
[100] Fix | Delete
elif len(lines) >= 2 and not lines[1].rstrip():
[101] Fix | Delete
return lines[0], '\n'.join(lines[2:])
[102] Fix | Delete
return '', '\n'.join(lines)
[103] Fix | Delete
[104] Fix | Delete
def classname(object, modname):
[105] Fix | Delete
"""Get a class name and qualify it with a module name if necessary."""
[106] Fix | Delete
name = object.__name__
[107] Fix | Delete
if object.__module__ != modname:
[108] Fix | Delete
name = object.__module__ + '.' + name
[109] Fix | Delete
return name
[110] Fix | Delete
[111] Fix | Delete
def isdata(object):
[112] Fix | Delete
"""Check if an object is of a type that probably means it's data."""
[113] Fix | Delete
return not (inspect.ismodule(object) or inspect.isclass(object) or
[114] Fix | Delete
inspect.isroutine(object) or inspect.isframe(object) or
[115] Fix | Delete
inspect.istraceback(object) or inspect.iscode(object))
[116] Fix | Delete
[117] Fix | Delete
def replace(text, *pairs):
[118] Fix | Delete
"""Do a series of global replacements on a string."""
[119] Fix | Delete
while pairs:
[120] Fix | Delete
text = pairs[1].join(text.split(pairs[0]))
[121] Fix | Delete
pairs = pairs[2:]
[122] Fix | Delete
return text
[123] Fix | Delete
[124] Fix | Delete
def cram(text, maxlen):
[125] Fix | Delete
"""Omit part of a string if needed to make it fit in a maximum length."""
[126] Fix | Delete
if len(text) > maxlen:
[127] Fix | Delete
pre = max(0, (maxlen-3)//2)
[128] Fix | Delete
post = max(0, maxlen-3-pre)
[129] Fix | Delete
return text[:pre] + '...' + text[len(text)-post:]
[130] Fix | Delete
return text
[131] Fix | Delete
[132] Fix | Delete
_re_stripid = re.compile(r' at 0x[0-9a-f]{6,16}(>+)$', re.IGNORECASE)
[133] Fix | Delete
def stripid(text):
[134] Fix | Delete
"""Remove the hexadecimal id from a Python object representation."""
[135] Fix | Delete
# The behaviour of %p is implementation-dependent in terms of case.
[136] Fix | Delete
return _re_stripid.sub(r'\1', text)
[137] Fix | Delete
[138] Fix | Delete
def _is_bound_method(fn):
[139] Fix | Delete
"""
[140] Fix | Delete
Returns True if fn is a bound method, regardless of whether
[141] Fix | Delete
fn was implemented in Python or in C.
[142] Fix | Delete
"""
[143] Fix | Delete
if inspect.ismethod(fn):
[144] Fix | Delete
return True
[145] Fix | Delete
if inspect.isbuiltin(fn):
[146] Fix | Delete
self = getattr(fn, '__self__', None)
[147] Fix | Delete
return not (inspect.ismodule(self) or (self is None))
[148] Fix | Delete
return False
[149] Fix | Delete
[150] Fix | Delete
[151] Fix | Delete
def allmethods(cl):
[152] Fix | Delete
methods = {}
[153] Fix | Delete
for key, value in inspect.getmembers(cl, inspect.isroutine):
[154] Fix | Delete
methods[key] = 1
[155] Fix | Delete
for base in cl.__bases__:
[156] Fix | Delete
methods.update(allmethods(base)) # all your base are belong to us
[157] Fix | Delete
for key in methods.keys():
[158] Fix | Delete
methods[key] = getattr(cl, key)
[159] Fix | Delete
return methods
[160] Fix | Delete
[161] Fix | Delete
def _split_list(s, predicate):
[162] Fix | Delete
"""Split sequence s via predicate, and return pair ([true], [false]).
[163] Fix | Delete
[164] Fix | Delete
The return value is a 2-tuple of lists,
[165] Fix | Delete
([x for x in s if predicate(x)],
[166] Fix | Delete
[x for x in s if not predicate(x)])
[167] Fix | Delete
"""
[168] Fix | Delete
[169] Fix | Delete
yes = []
[170] Fix | Delete
no = []
[171] Fix | Delete
for x in s:
[172] Fix | Delete
if predicate(x):
[173] Fix | Delete
yes.append(x)
[174] Fix | Delete
else:
[175] Fix | Delete
no.append(x)
[176] Fix | Delete
return yes, no
[177] Fix | Delete
[178] Fix | Delete
def visiblename(name, all=None, obj=None):
[179] Fix | Delete
"""Decide whether to show documentation on a variable."""
[180] Fix | Delete
# Certain special names are redundant or internal.
[181] Fix | Delete
# XXX Remove __initializing__?
[182] Fix | Delete
if name in {'__author__', '__builtins__', '__cached__', '__credits__',
[183] Fix | Delete
'__date__', '__doc__', '__file__', '__spec__',
[184] Fix | Delete
'__loader__', '__module__', '__name__', '__package__',
[185] Fix | Delete
'__path__', '__qualname__', '__slots__', '__version__'}:
[186] Fix | Delete
return 0
[187] Fix | Delete
# Private names are hidden, but special names are displayed.
[188] Fix | Delete
if name.startswith('__') and name.endswith('__'): return 1
[189] Fix | Delete
# Namedtuples have public fields and methods with a single leading underscore
[190] Fix | Delete
if name.startswith('_') and hasattr(obj, '_fields'):
[191] Fix | Delete
return True
[192] Fix | Delete
if all is not None:
[193] Fix | Delete
# only document that which the programmer exported in __all__
[194] Fix | Delete
return name in all
[195] Fix | Delete
else:
[196] Fix | Delete
return not name.startswith('_')
[197] Fix | Delete
[198] Fix | Delete
def classify_class_attrs(object):
[199] Fix | Delete
"""Wrap inspect.classify_class_attrs, with fixup for data descriptors."""
[200] Fix | Delete
results = []
[201] Fix | Delete
for (name, kind, cls, value) in inspect.classify_class_attrs(object):
[202] Fix | Delete
if inspect.isdatadescriptor(value):
[203] Fix | Delete
kind = 'data descriptor'
[204] Fix | Delete
if isinstance(value, property) and value.fset is None:
[205] Fix | Delete
kind = 'readonly property'
[206] Fix | Delete
results.append((name, kind, cls, value))
[207] Fix | Delete
return results
[208] Fix | Delete
[209] Fix | Delete
def sort_attributes(attrs, object):
[210] Fix | Delete
'Sort the attrs list in-place by _fields and then alphabetically by name'
[211] Fix | Delete
# This allows data descriptors to be ordered according
[212] Fix | Delete
# to a _fields attribute if present.
[213] Fix | Delete
fields = getattr(object, '_fields', [])
[214] Fix | Delete
try:
[215] Fix | Delete
field_order = {name : i-len(fields) for (i, name) in enumerate(fields)}
[216] Fix | Delete
except TypeError:
[217] Fix | Delete
field_order = {}
[218] Fix | Delete
keyfunc = lambda attr: (field_order.get(attr[0], 0), attr[0])
[219] Fix | Delete
attrs.sort(key=keyfunc)
[220] Fix | Delete
[221] Fix | Delete
# ----------------------------------------------------- module manipulation
[222] Fix | Delete
[223] Fix | Delete
def ispackage(path):
[224] Fix | Delete
"""Guess whether a path refers to a package directory."""
[225] Fix | Delete
if os.path.isdir(path):
[226] Fix | Delete
for ext in ('.py', '.pyc'):
[227] Fix | Delete
if os.path.isfile(os.path.join(path, '__init__' + ext)):
[228] Fix | Delete
return True
[229] Fix | Delete
return False
[230] Fix | Delete
[231] Fix | Delete
def source_synopsis(file):
[232] Fix | Delete
line = file.readline()
[233] Fix | Delete
while line[:1] == '#' or not line.strip():
[234] Fix | Delete
line = file.readline()
[235] Fix | Delete
if not line: break
[236] Fix | Delete
line = line.strip()
[237] Fix | Delete
if line[:4] == 'r"""': line = line[1:]
[238] Fix | Delete
if line[:3] == '"""':
[239] Fix | Delete
line = line[3:]
[240] Fix | Delete
if line[-1:] == '\\': line = line[:-1]
[241] Fix | Delete
while not line.strip():
[242] Fix | Delete
line = file.readline()
[243] Fix | Delete
if not line: break
[244] Fix | Delete
result = line.split('"""')[0].strip()
[245] Fix | Delete
else: result = None
[246] Fix | Delete
return result
[247] Fix | Delete
[248] Fix | Delete
def synopsis(filename, cache={}):
[249] Fix | Delete
"""Get the one-line summary out of a module file."""
[250] Fix | Delete
mtime = os.stat(filename).st_mtime
[251] Fix | Delete
lastupdate, result = cache.get(filename, (None, None))
[252] Fix | Delete
if lastupdate is None or lastupdate < mtime:
[253] Fix | Delete
# Look for binary suffixes first, falling back to source.
[254] Fix | Delete
if filename.endswith(tuple(importlib.machinery.BYTECODE_SUFFIXES)):
[255] Fix | Delete
loader_cls = importlib.machinery.SourcelessFileLoader
[256] Fix | Delete
elif filename.endswith(tuple(importlib.machinery.EXTENSION_SUFFIXES)):
[257] Fix | Delete
loader_cls = importlib.machinery.ExtensionFileLoader
[258] Fix | Delete
else:
[259] Fix | Delete
loader_cls = None
[260] Fix | Delete
# Now handle the choice.
[261] Fix | Delete
if loader_cls is None:
[262] Fix | Delete
# Must be a source file.
[263] Fix | Delete
try:
[264] Fix | Delete
file = tokenize.open(filename)
[265] Fix | Delete
except OSError:
[266] Fix | Delete
# module can't be opened, so skip it
[267] Fix | Delete
return None
[268] Fix | Delete
# text modules can be directly examined
[269] Fix | Delete
with file:
[270] Fix | Delete
result = source_synopsis(file)
[271] Fix | Delete
else:
[272] Fix | Delete
# Must be a binary module, which has to be imported.
[273] Fix | Delete
loader = loader_cls('__temp__', filename)
[274] Fix | Delete
# XXX We probably don't need to pass in the loader here.
[275] Fix | Delete
spec = importlib.util.spec_from_file_location('__temp__', filename,
[276] Fix | Delete
loader=loader)
[277] Fix | Delete
try:
[278] Fix | Delete
module = importlib._bootstrap._load(spec)
[279] Fix | Delete
except:
[280] Fix | Delete
return None
[281] Fix | Delete
del sys.modules['__temp__']
[282] Fix | Delete
result = module.__doc__.splitlines()[0] if module.__doc__ else None
[283] Fix | Delete
# Cache the result.
[284] Fix | Delete
cache[filename] = (mtime, result)
[285] Fix | Delete
return result
[286] Fix | Delete
[287] Fix | Delete
class ErrorDuringImport(Exception):
[288] Fix | Delete
"""Errors that occurred while trying to import something to document it."""
[289] Fix | Delete
def __init__(self, filename, exc_info):
[290] Fix | Delete
self.filename = filename
[291] Fix | Delete
self.exc, self.value, self.tb = exc_info
[292] Fix | Delete
[293] Fix | Delete
def __str__(self):
[294] Fix | Delete
exc = self.exc.__name__
[295] Fix | Delete
return 'problem in %s - %s: %s' % (self.filename, exc, self.value)
[296] Fix | Delete
[297] Fix | Delete
def importfile(path):
[298] Fix | Delete
"""Import a Python source file or compiled file given its path."""
[299] Fix | Delete
magic = importlib.util.MAGIC_NUMBER
[300] Fix | Delete
with open(path, 'rb') as file:
[301] Fix | Delete
is_bytecode = magic == file.read(len(magic))
[302] Fix | Delete
filename = os.path.basename(path)
[303] Fix | Delete
name, ext = os.path.splitext(filename)
[304] Fix | Delete
if is_bytecode:
[305] Fix | Delete
loader = importlib._bootstrap_external.SourcelessFileLoader(name, path)
[306] Fix | Delete
else:
[307] Fix | Delete
loader = importlib._bootstrap_external.SourceFileLoader(name, path)
[308] Fix | Delete
# XXX We probably don't need to pass in the loader here.
[309] Fix | Delete
spec = importlib.util.spec_from_file_location(name, path, loader=loader)
[310] Fix | Delete
try:
[311] Fix | Delete
return importlib._bootstrap._load(spec)
[312] Fix | Delete
except:
[313] Fix | Delete
raise ErrorDuringImport(path, sys.exc_info())
[314] Fix | Delete
[315] Fix | Delete
def safeimport(path, forceload=0, cache={}):
[316] Fix | Delete
"""Import a module; handle errors; return None if the module isn't found.
[317] Fix | Delete
[318] Fix | Delete
If the module *is* found but an exception occurs, it's wrapped in an
[319] Fix | Delete
ErrorDuringImport exception and reraised. Unlike __import__, if a
[320] Fix | Delete
package path is specified, the module at the end of the path is returned,
[321] Fix | Delete
not the package at the beginning. If the optional 'forceload' argument
[322] Fix | Delete
is 1, we reload the module from disk (unless it's a dynamic extension)."""
[323] Fix | Delete
try:
[324] Fix | Delete
# If forceload is 1 and the module has been previously loaded from
[325] Fix | Delete
# disk, we always have to reload the module. Checking the file's
[326] Fix | Delete
# mtime isn't good enough (e.g. the module could contain a class
[327] Fix | Delete
# that inherits from another module that has changed).
[328] Fix | Delete
if forceload and path in sys.modules:
[329] Fix | Delete
if path not in sys.builtin_module_names:
[330] Fix | Delete
# Remove the module from sys.modules and re-import to try
[331] Fix | Delete
# and avoid problems with partially loaded modules.
[332] Fix | Delete
# Also remove any submodules because they won't appear
[333] Fix | Delete
# in the newly loaded module's namespace if they're already
[334] Fix | Delete
# in sys.modules.
[335] Fix | Delete
subs = [m for m in sys.modules if m.startswith(path + '.')]
[336] Fix | Delete
for key in [path] + subs:
[337] Fix | Delete
# Prevent garbage collection.
[338] Fix | Delete
cache[key] = sys.modules[key]
[339] Fix | Delete
del sys.modules[key]
[340] Fix | Delete
module = __import__(path)
[341] Fix | Delete
except:
[342] Fix | Delete
# Did the error occur before or after the module was found?
[343] Fix | Delete
(exc, value, tb) = info = sys.exc_info()
[344] Fix | Delete
if path in sys.modules:
[345] Fix | Delete
# An error occurred while executing the imported module.
[346] Fix | Delete
raise ErrorDuringImport(sys.modules[path].__file__, info)
[347] Fix | Delete
elif exc is SyntaxError:
[348] Fix | Delete
# A SyntaxError occurred before we could execute the module.
[349] Fix | Delete
raise ErrorDuringImport(value.filename, info)
[350] Fix | Delete
elif issubclass(exc, ImportError) and value.name == path:
[351] Fix | Delete
# No such module in the path.
[352] Fix | Delete
return None
[353] Fix | Delete
else:
[354] Fix | Delete
# Some other error occurred during the importing process.
[355] Fix | Delete
raise ErrorDuringImport(path, sys.exc_info())
[356] Fix | Delete
for part in path.split('.')[1:]:
[357] Fix | Delete
try: module = getattr(module, part)
[358] Fix | Delete
except AttributeError: return None
[359] Fix | Delete
return module
[360] Fix | Delete
[361] Fix | Delete
# ---------------------------------------------------- formatter base class
[362] Fix | Delete
[363] Fix | Delete
class Doc:
[364] Fix | Delete
[365] Fix | Delete
PYTHONDOCS = os.environ.get("PYTHONDOCS",
[366] Fix | Delete
"https://docs.python.org/%d.%d/library"
[367] Fix | Delete
% sys.version_info[:2])
[368] Fix | Delete
[369] Fix | Delete
def document(self, object, name=None, *args):
[370] Fix | Delete
"""Generate documentation for an object."""
[371] Fix | Delete
args = (object, name) + args
[372] Fix | Delete
# 'try' clause is to attempt to handle the possibility that inspect
[373] Fix | Delete
# identifies something in a way that pydoc itself has issues handling;
[374] Fix | Delete
# think 'super' and how it is a descriptor (which raises the exception
[375] Fix | Delete
# by lacking a __name__ attribute) and an instance.
[376] Fix | Delete
try:
[377] Fix | Delete
if inspect.ismodule(object): return self.docmodule(*args)
[378] Fix | Delete
if inspect.isclass(object): return self.docclass(*args)
[379] Fix | Delete
if inspect.isroutine(object): return self.docroutine(*args)
[380] Fix | Delete
except AttributeError:
[381] Fix | Delete
pass
[382] Fix | Delete
if inspect.isdatadescriptor(object): return self.docdata(*args)
[383] Fix | Delete
return self.docother(*args)
[384] Fix | Delete
[385] Fix | Delete
def fail(self, object, name=None, *args):
[386] Fix | Delete
"""Raise an exception for unimplemented types."""
[387] Fix | Delete
message = "don't know how to document object%s of type %s" % (
[388] Fix | Delete
name and ' ' + repr(name), type(object).__name__)
[389] Fix | Delete
raise TypeError(message)
[390] Fix | Delete
[391] Fix | Delete
docmodule = docclass = docroutine = docother = docproperty = docdata = fail
[392] Fix | Delete
[393] Fix | Delete
def getdocloc(self, object, basedir=sysconfig.get_path('stdlib')):
[394] Fix | Delete
"""Return the location of module docs or None"""
[395] Fix | Delete
[396] Fix | Delete
try:
[397] Fix | Delete
file = inspect.getabsfile(object)
[398] Fix | Delete
except TypeError:
[399] Fix | Delete
file = '(built-in)'
[400] Fix | Delete
[401] Fix | Delete
docloc = os.environ.get("PYTHONDOCS", self.PYTHONDOCS)
[402] Fix | Delete
[403] Fix | Delete
basedir = os.path.normcase(basedir)
[404] Fix | Delete
if (isinstance(object, type(os)) and
[405] Fix | Delete
(object.__name__ in ('errno', 'exceptions', 'gc', 'imp',
[406] Fix | Delete
'marshal', 'posix', 'signal', 'sys',
[407] Fix | Delete
'_thread', 'zipimport') or
[408] Fix | Delete
(file.startswith(basedir) and
[409] Fix | Delete
not file.startswith(os.path.join(basedir, 'site-packages')))) and
[410] Fix | Delete
object.__name__ not in ('xml.etree', 'test.pydoc_mod')):
[411] Fix | Delete
if docloc.startswith(("http://", "https://")):
[412] Fix | Delete
docloc = "%s/%s" % (docloc.rstrip("/"), object.__name__.lower())
[413] Fix | Delete
else:
[414] Fix | Delete
docloc = os.path.join(docloc, object.__name__.lower() + ".html")
[415] Fix | Delete
else:
[416] Fix | Delete
docloc = None
[417] Fix | Delete
return docloc
[418] Fix | Delete
[419] Fix | Delete
# -------------------------------------------- HTML documentation generator
[420] Fix | Delete
[421] Fix | Delete
class HTMLRepr(Repr):
[422] Fix | Delete
"""Class for safely making an HTML representation of a Python object."""
[423] Fix | Delete
def __init__(self):
[424] Fix | Delete
Repr.__init__(self)
[425] Fix | Delete
self.maxlist = self.maxtuple = 20
[426] Fix | Delete
self.maxdict = 10
[427] Fix | Delete
self.maxstring = self.maxother = 100
[428] Fix | Delete
[429] Fix | Delete
def escape(self, text):
[430] Fix | Delete
return replace(text, '&', '&amp;', '<', '&lt;', '>', '&gt;')
[431] Fix | Delete
[432] Fix | Delete
def repr(self, object):
[433] Fix | Delete
return Repr.repr(self, object)
[434] Fix | Delete
[435] Fix | Delete
def repr1(self, x, level):
[436] Fix | Delete
if hasattr(type(x), '__name__'):
[437] Fix | Delete
methodname = 'repr_' + '_'.join(type(x).__name__.split())
[438] Fix | Delete
if hasattr(self, methodname):
[439] Fix | Delete
return getattr(self, methodname)(x, level)
[440] Fix | Delete
return self.escape(cram(stripid(repr(x)), self.maxother))
[441] Fix | Delete
[442] Fix | Delete
def repr_string(self, x, level):
[443] Fix | Delete
test = cram(x, self.maxstring)
[444] Fix | Delete
testrepr = repr(test)
[445] Fix | Delete
if '\\' in test and '\\' not in replace(testrepr, r'\\', ''):
[446] Fix | Delete
# Backslashes are only literal in the string and are never
[447] Fix | Delete
# needed to make any special characters, so show a raw string.
[448] Fix | Delete
return 'r' + testrepr[0] + self.escape(test) + testrepr[0]
[449] Fix | Delete
return re.sub(r'((\\[\\abfnrtv\'"]|\\[0-9]..|\\x..|\\u....)+)',
[450] Fix | Delete
r'<font color="#c040c0">\1</font>',
[451] Fix | Delete
self.escape(testrepr))
[452] Fix | Delete
[453] Fix | Delete
repr_str = repr_string
[454] Fix | Delete
[455] Fix | Delete
def repr_instance(self, x, level):
[456] Fix | Delete
try:
[457] Fix | Delete
return self.escape(cram(stripid(repr(x)), self.maxstring))
[458] Fix | Delete
except:
[459] Fix | Delete
return self.escape('<%s instance>' % x.__class__.__name__)
[460] Fix | Delete
[461] Fix | Delete
repr_unicode = repr_string
[462] Fix | Delete
[463] Fix | Delete
class HTMLDoc(Doc):
[464] Fix | Delete
"""Formatter class for HTML documentation."""
[465] Fix | Delete
[466] Fix | Delete
# ------------------------------------------- HTML formatting utilities
[467] Fix | Delete
[468] Fix | Delete
_repr_instance = HTMLRepr()
[469] Fix | Delete
repr = _repr_instance.repr
[470] Fix | Delete
escape = _repr_instance.escape
[471] Fix | Delete
[472] Fix | Delete
def page(self, title, contents):
[473] Fix | Delete
"""Format an HTML page."""
[474] Fix | Delete
return '''\
[475] Fix | Delete
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
[476] Fix | Delete
<html><head><title>Python: %s</title>
[477] Fix | Delete
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
[478] Fix | Delete
</head><body bgcolor="#f0f0f8">
[479] Fix | Delete
%s
[480] Fix | Delete
</body></html>''' % (title, contents)
[481] Fix | Delete
[482] Fix | Delete
def heading(self, title, fgcol, bgcol, extras=''):
[483] Fix | Delete
"""Format a page heading."""
[484] Fix | Delete
return '''
[485] Fix | Delete
<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="heading">
[486] Fix | Delete
<tr bgcolor="%s">
[487] Fix | Delete
<td valign=bottom>&nbsp;<br>
[488] Fix | Delete
<font color="%s" face="helvetica, arial">&nbsp;<br>%s</font></td
[489] Fix | Delete
><td align=right valign=bottom
[490] Fix | Delete
><font color="%s" face="helvetica, arial">%s</font></td></tr></table>
[491] Fix | Delete
''' % (bgcol, fgcol, title, fgcol, extras or '&nbsp;')
[492] Fix | Delete
[493] Fix | Delete
def section(self, title, fgcol, bgcol, contents, width=6,
[494] Fix | Delete
prelude='', marginalia=None, gap='&nbsp;'):
[495] Fix | Delete
"""Format a section with a heading."""
[496] Fix | Delete
if marginalia is None:
[497] Fix | Delete
marginalia = '<tt>' + '&nbsp;' * width + '</tt>'
[498] Fix | Delete
result = '''<p>
[499] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function