diff options
author | Jason Madden <jason+github@nextthought.com> | 2017-11-03 08:35:28 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-03 08:35:28 -0500 |
commit | 8269f2c7d418d19bba90a67bd88aa64b8ed5acdc (patch) | |
tree | c8b1cb2f945857e075546584ab719db93583f7a0 /src | |
parent | 5a2101c0c088bca3f0b50e34166e33451ca73dac (diff) | |
parent | d052e523e766b38c6ba058b7630a99fa36c35719 (diff) | |
download | zope-tal-8269f2c7d418d19bba90a67bd88aa64b8ed5acdc.tar.gz |
Merge pull request #8 from zopefoundation/rtd-docs
Documentation for RTD
Diffstat (limited to 'src')
-rw-r--r-- | src/zope/tal/htmltalparser.py | 56 | ||||
-rw-r--r-- | src/zope/tal/interfaces.py | 55 | ||||
-rw-r--r-- | src/zope/tal/taldefs.py | 47 | ||||
-rw-r--r-- | src/zope/tal/talgenerator.py | 21 | ||||
-rw-r--r-- | src/zope/tal/talinterpreter.py | 65 | ||||
-rw-r--r-- | src/zope/tal/talparser.py | 19 | ||||
-rw-r--r-- | src/zope/tal/xmlparser.py | 8 |
7 files changed, 172 insertions, 99 deletions
diff --git a/src/zope/tal/htmltalparser.py b/src/zope/tal/htmltalparser.py index c79bbea..1761bc7 100644 --- a/src/zope/tal/htmltalparser.py +++ b/src/zope/tal/htmltalparser.py @@ -11,7 +11,9 @@ # FOR A PARTICULAR PURPOSE. # ############################################################################## -"""Parse HTML and compile to TALInterpreter intermediate code. +""" +Parse HTML and compile to :class:`~.TALInterpreter` intermediate code, using +a :class:`~.TALGenerator`. """ # When Python 3 becomes mainstream please swap the try and except parts. @@ -28,6 +30,7 @@ except ImportError: # so here's a copy taken from Python 3.4: class HTMLParseError(Exception): def __init__(self, msg, position=(None, None)): + Exception.__init__(self) assert msg self.msg = msg self.lineno = position[0] @@ -50,30 +53,30 @@ _html_parser_extras = {} if 'convert_charrefs' in HTMLParser.__init__.__code__.co_names: _html_parser_extras['convert_charrefs'] = False # pragma: NO COVER py34 - +#: List of Boolean attributes in HTML that may be given in +#: minimized form (e.g. ``<img ismap>`` rather than ``<img ismap="">``) +#: From http://www.w3.org/TR/xhtml1/#guidelines (C.10) BOOLEAN_HTML_ATTRS = frozenset([ - # List of Boolean attributes in HTML that may be given in - # minimized form (e.g. <img ismap> rather than <img ismap="">) - # From http://www.w3.org/TR/xhtml1/#guidelines (C.10) "compact", "nowrap", "ismap", "declare", "noshade", "checked", "disabled", "readonly", "multiple", "selected", "noresize", "defer" ]) +#: List of HTML tags with an empty content model; these are +#: rendered in minimized form, e.g. ``<img />``. +#: From http://www.w3.org/TR/xhtml1/#dtds EMPTY_HTML_TAGS = frozenset([ - # List of HTML tags with an empty content model; these are - # rendered in minimized form, e.g. <img />. - # From http://www.w3.org/TR/xhtml1/#dtds "base", "meta", "link", "hr", "br", "param", "img", "area", "input", "col", "basefont", "isindex", "frame", ]) +#: List of HTML elements that close open paragraph-level elements +#: and are themselves paragraph-level. PARA_LEVEL_HTML_TAGS = frozenset([ - # List of HTML elements that close open paragraph-level elements - # and are themselves paragraph-level. "h1", "h2", "h3", "h4", "h5", "h6", "p", ]) +#: Tags that automatically close other tags. BLOCK_CLOSING_TAG_MAP = { "tr": frozenset(["tr", "td", "th"]), "td": frozenset(["td", "th"]), @@ -83,12 +86,13 @@ BLOCK_CLOSING_TAG_MAP = { "dt": frozenset(["dd", "dt"]), } +#: List of HTML tags that denote larger sections than paragraphs. BLOCK_LEVEL_HTML_TAGS = frozenset([ - # List of HTML tags that denote larger sections than paragraphs. "blockquote", "table", "tr", "th", "td", "thead", "tfoot", "tbody", "noframe", "ul", "ol", "li", "dl", "dt", "dd", "div", ]) +#: Section level HTML tags SECTION_LEVEL_HTML_TAGS = PARA_LEVEL_HTML_TAGS.union(BLOCK_LEVEL_HTML_TAGS) TIGHTEN_IMPLICIT_CLOSE_TAGS = PARA_LEVEL_HTML_TAGS.union(BLOCK_CLOSING_TAG_MAP) @@ -127,25 +131,37 @@ class OpenTagError(NestingError): HTMLParseError.__init__(self, msg, position) class HTMLTALParser(HTMLParser): + """ + Parser for HTML. + + After you call either :meth:`parseFile` and :meth:`parseString` + you can retrieve the compiled program using :meth:`getCode`. + """ # External API def __init__(self, gen=None): + """ + :keyword TALGenerator gen: The configured (with an expression compiler) + code generator to use. If one is not given, a default will be used. + """ HTMLParser.__init__(self, **_html_parser_extras) if gen is None: gen = TALGenerator(xml=0) self.gen = gen self.tagstack = [] self.nsstack = [] - self.nsdict = {'tal': ZOPE_TAL_NS, - 'metal': ZOPE_METAL_NS, - 'i18n': ZOPE_I18N_NS, - } + self.nsdict = { + 'tal': ZOPE_TAL_NS, + 'metal': ZOPE_METAL_NS, + 'i18n': ZOPE_I18N_NS, + } def parseFile(self, file): - f = open(file) - data = f.read() - f.close() + """Parse data in the given file.""" + with open(file) as f: + data = f.read() + try: self.parseString(data) except TALError as e: @@ -153,6 +169,7 @@ class HTMLTALParser(HTMLParser): raise def parseString(self, data): + """Parse data in the given string.""" self.feed(data) self.close() while self.tagstack: @@ -160,6 +177,9 @@ class HTMLTALParser(HTMLParser): assert self.nsstack == [], self.nsstack def getCode(self): + """ + After parsing, this returns ``(program, macros)``. + """ return self.gen.getCode() # Overriding HTMLParser methods diff --git a/src/zope/tal/interfaces.py b/src/zope/tal/interfaces.py index 8de3819..f6c1aec 100644 --- a/src/zope/tal/interfaces.py +++ b/src/zope/tal/interfaces.py @@ -11,8 +11,16 @@ # FOR A PARTICULAR PURPOSE. # ############################################################################## -"""Interface that a TAL expression implementation provides to the METAL/TAL -implementation. +""" +Interface that a TAL expression implementation provides to the +METAL/TAL implementation. + +This package does not provide an implementation of +:class:`ITALExpressionCompiler`, :class:`ITALExpressionEngine` or +:class:`ITALIterator`. An external package must provide those. The +most commonly used are :class:`zope.tales.tales.ExpressionEngine`, +:class:`zope.tales.tales.Context`, and +:class:`zope.tales.tales.Iterator`, respectively. """ from zope.interface import Attribute, Interface @@ -30,20 +38,20 @@ class ITALExpressionCompiler(Interface): """ def compile(expression): - """Return a compiled form of 'expression' for later evaluation. + """Return a compiled form of *expression* for later evaluation. - 'expression' is the source text of the expression. + *expression* is the source text of the expression. - The return value may be passed to the various evaluate*() - methods of the ITALExpressionEngine interface. No compatibility is + The return value may be passed to the various ``evaluate*()`` + methods of the :class:`ITALExpressionEngine` interface. No compatibility is required for the values of the compiled expression between - different ITALExpressionEngine implementations. + different :class:`ITALExpressionEngine` implementations. """ def getContext(namespace): """Create an expression execution context - The given namespace provides the initial top-level names. + The given *namespace* provides the initial top-level names. """ class ITALExpressionEngine(Interface): @@ -51,20 +59,20 @@ class ITALExpressionEngine(Interface): The TAL interpreter uses this interface to TAL expression to support evaluation of the compiled expressions returned by - ITALExpressionCompiler.compile(). + :meth:`ITALExpressionCompiler.compile`. """ def getDefault(): - """Return the value of the 'default' TAL expression. + """Return the value of the ``default`` TAL expression. - Checking a value for a match with 'default' should be done - using the 'is' operator in Python. + Checking a value for a match with ``default`` should be done + using the ``is`` operator in Python. """ def setPosition(position): """Inform the engine of the current position in the source file. - ``position`` is a tuple (lineno, offset). + *position* is a tuple (lineno, offset). This is used to allow the evaluation engine to report execution errors so that site developers can more easily @@ -105,7 +113,7 @@ class ITALExpressionEngine(Interface): """Evaluate an expression that must return a structured document fragment. - The result of evaluating 'compiled_expression' must be a + The result of evaluating *compiled_expression* must be a string containing a parsable HTML or XML fragment. Any TAL markup contained in the result string will be interpreted. """ @@ -118,10 +126,10 @@ class ITALExpressionEngine(Interface): responsibility of the expression itself. If the expression evaluates to None, then that is returned. It - represents 'nothing' in TALES. - If the expression evaluates to what getDefault() of this interface - returns, by comparison using 'is', then that is returned. It - represents 'default' in TALES. + represents ``nothing`` in TALES. + If the expression evaluates to what :meth:`getDefault()` + returns, by comparison using ``is``, then that is returned. It + represents ``default`` in TALES. """ def evaluateValue(compiled_expression): @@ -131,9 +139,9 @@ class ITALExpressionEngine(Interface): """ def createErrorInfo(exception, position): - """Returns an ITALExpressionErrorInfo object. + """Returns an :class:`ITALExpressionErrorInfo` object. - ``position`` is a tuple (lineno, offset). + *position* is a tuple (lineno, offset). The returned object is used to provide information about the error condition for the on-error handler. @@ -142,13 +150,13 @@ class ITALExpressionEngine(Interface): def setGlobal(name, value): """Set a global variable. - The variable will be named 'name' and have the value 'value'. + The variable will be named *name* and have the value *value*. """ def setLocal(name, value): """Set a local variable in the current scope. - The variable will be named 'name' and have the value 'value'. + The variable will be named *name* and have the value *value*. """ def getValue(name, default=None): @@ -158,7 +166,7 @@ class ITALExpressionEngine(Interface): """ def setRepeat(name, compiled_expression): - """Start a repetition, returning an ITALIterator. + """Start a repetition, returning an :class:`ITALIterator`. The engine is expected to add the a value (typically the returned iterator) for the name to the variable namespace. @@ -195,6 +203,7 @@ class ITALIterator(Interface): class ITALExpressionErrorInfo(Interface): + """Information about an error.""" type = Attribute("type", "The exception class.") diff --git a/src/zope/tal/taldefs.py b/src/zope/tal/taldefs.py index a4aaf61..539e541 100644 --- a/src/zope/tal/taldefs.py +++ b/src/zope/tal/taldefs.py @@ -17,20 +17,26 @@ import re from zope.tal.interfaces import ITALExpressionErrorInfo from zope.interface import implementer - +#: Version of the specification we implement. TAL_VERSION = "1.6" -XML_NS = "http://www.w3.org/XML/1998/namespace" # URI for XML namespace -XMLNS_NS = "http://www.w3.org/2000/xmlns/" # URI for XML NS declarations +#: URI for XML namespace +XML_NS = "http://www.w3.org/XML/1998/namespace" +#: URI for XML NS declarations +XMLNS_NS = "http://www.w3.org/2000/xmlns/" +#: TAL namespace URI ZOPE_TAL_NS = "http://xml.zope.org/namespaces/tal" +#: METAL namespace URI ZOPE_METAL_NS = "http://xml.zope.org/namespaces/metal" +#: I18N namespace URI ZOPE_I18N_NS = "http://xml.zope.org/namespaces/i18n" # This RE must exactly match the expression of the same name in the # zope.i18n.simpletranslationservice module: NAME_RE = "[a-zA-Z_][-a-zA-Z0-9_]*" +#: Known METAL attributes KNOWN_METAL_ATTRIBUTES = frozenset([ "define-macro", "extend-macro", @@ -39,6 +45,7 @@ KNOWN_METAL_ATTRIBUTES = frozenset([ "fill-slot", ]) +#: Known TAL attributes KNOWN_TAL_ATTRIBUTES = frozenset([ "define", "condition", @@ -53,6 +60,7 @@ KNOWN_TAL_ATTRIBUTES = frozenset([ # like <tal:x>, <metal:y>, <i18n:z> ]) +#: Known I18N attributes KNOWN_I18N_ATTRIBUTES = frozenset([ "translate", "domain", @@ -66,8 +74,12 @@ KNOWN_I18N_ATTRIBUTES = frozenset([ ]) class TALError(Exception): + """ + A base exception for errors raised by this implementation. + """ def __init__(self, msg, position=(None, None)): + Exception.__init__(self) assert msg != "" self.msg = msg self.lineno = position[0] @@ -88,17 +100,20 @@ class TALError(Exception): return result class METALError(TALError): - pass + """An error parsing on running METAL macros.""" class TALExpressionError(TALError): - pass + """An error parsing or running a TAL expression.""" class I18NError(TALError): - pass + """An error parsing a I18N expression.""" @implementer(ITALExpressionErrorInfo) class ErrorInfo(object): + """ + Default implementation of :class:`zope.tal.interfaces.ITALExpressionErrorInfo`. + """ def __init__(self, err, position=(None, None)): if isinstance(err, Exception): @@ -115,7 +130,7 @@ _attr_re = re.compile(r"\s*([^\s]+)\s+([^\s].*)\Z", re.S) _subst_re = re.compile(r"\s*(?:(text|structure)\s+)?(.*)\Z", re.S) def parseAttributeReplacements(arg, xml): - dict = {} + attr_dict = {} for part in splitParts(arg): m = _attr_re.match(part) if not m: @@ -123,10 +138,10 @@ def parseAttributeReplacements(arg, xml): name, expr = m.groups() if not xml: name = name.lower() - if name in dict: + if name in attr_dict: raise TALError("Duplicate attribute name in attributes: %r" % part) - dict[name] = expr - return dict + attr_dict[name] = expr + return attr_dict def parseSubstitution(arg, position=(None, None)): m = _subst_re.match(arg) @@ -151,26 +166,26 @@ def isCurrentVersion(program): version = getProgramVersion(program) return version == TAL_VERSION -def isinstance_(ob, type): +def isinstance_(ob, kind): # Proxy-friendly and faster isinstance_ check for new-style objects try: - return type in ob.__class__.__mro__ + return kind in ob.__class__.__mro__ except AttributeError: return False def getProgramMode(program): version = getProgramVersion(program) - if (version == TAL_VERSION and isinstance_(program[1], tuple) and - len(program[1]) == 2): + if (version == TAL_VERSION and isinstance_(program[1], tuple) + and len(program[1]) == 2): opcode, mode = program[1] if opcode == "mode": return mode return None def getProgramVersion(program): - if (len(program) >= 2 and - isinstance_(program[0], tuple) and len(program[0]) == 2): + if (len(program) >= 2 + and isinstance_(program[0], tuple) and len(program[0]) == 2): opcode, version = program[0] if opcode == "version": return version diff --git a/src/zope/tal/talgenerator.py b/src/zope/tal/talgenerator.py index ac77c18..ce7470c 100644 --- a/src/zope/tal/talgenerator.py +++ b/src/zope/tal/talgenerator.py @@ -11,7 +11,8 @@ # FOR A PARTICULAR PURPOSE. # ############################################################################## -"""Code generator for TALInterpreter intermediate code. +""" +Code generator for :class:`~.TALInterpreter` intermediate code. """ import re @@ -37,12 +38,20 @@ except NameError: _name_rx = re.compile(NAME_RE) class TALGenerator(object): + """ + Generate intermediate code. + """ inMacroUse = 0 inMacroDef = 0 source_file = None def __init__(self, expressionCompiler=None, xml=1, source_file=None): + """ + :keyword expressionCompiler: The implementation of + :class:`zope.tal.interfaces.ITALExpressionCompiler` to use. + If not given, we'll use a simple, undocumented, compiler. + """ if not expressionCompiler: from zope.tal.dummyengine import DummyEngine expressionCompiler = DummyEngine() @@ -96,7 +105,7 @@ class TALGenerator(object): if self.optimizeStartTag(collect, item[1], item[2], ">"): continue if opcode == "startEndTag": - endsep = self.xml and "/>" or " />" + endsep = "/>" if self.xml else " />" if self.optimizeStartTag(collect, item[1], item[2], endsep): continue if opcode in ("beginScope", "endScope"): @@ -182,9 +191,9 @@ class TALGenerator(object): output = program[:2] prev2, prev1 = output for item in program[2:]: - if ( item[0] == "beginScope" - and prev1[0] == "setPosition" - and prev2[0] == "rawtextColumn"): + if (item[0] == "beginScope" + and prev1[0] == "setPosition" + and prev2[0] == "rawtextColumn"): position = output.pop()[1] text, column = output.pop()[1] prev1 = None, None @@ -302,7 +311,7 @@ class TALGenerator(object): self.emit("condition", cexpr, program) def emitRepeat(self, arg): - m = re.match("(?s)\s*(%s)\s+(.*)\Z" % NAME_RE, arg) + m = re.match(r"(?s)\s*(%s)\s+(.*)\Z" % NAME_RE, arg) if not m: raise TALError("invalid repeat syntax: " + repr(arg), self.position) diff --git a/src/zope/tal/talinterpreter.py b/src/zope/tal/talinterpreter.py index c2ad97b..82154db 100644 --- a/src/zope/tal/talinterpreter.py +++ b/src/zope/tal/talinterpreter.py @@ -26,10 +26,9 @@ from zope.tal.translationcontext import TranslationContext try: unicode - _BLANK = unicode('') except NameError: unicode = str # Python 3.x - _BLANK = '' +_BLANK = u'' # Avoid constructing this tuple over and over @@ -43,6 +42,7 @@ BOOLEAN_HTML_ATTRS = frozenset([ # From http://www.w3.org/TR/xhtml1/#guidelines (C.10) # TODO: The problem with this is that this is not valid XML and # can't be parsed back! + # XXX: This is an exact duplicate of htmltalparser.BOOLEAN_HTML_ATTRS. Why? "compact", "nowrap", "ismap", "declare", "noshade", "checked", "disabled", "readonly", "multiple", "selected", "noresize", "defer" @@ -116,25 +116,25 @@ class TALInterpreter(object): """TAL interpreter. Some notes on source annotations. They are HTML/XML comments added to the - output whenever sourceFile is changed by a setSourceFile bytecode. Source + output whenever ``sourceFile`` is changed by a ``setSourceFile`` bytecode. Source annotations are disabled by default, but you can turn them on by passing a - sourceAnnotations argument to the constructor. You can change the format + ``sourceAnnotations`` argument to the constructor. You can change the format of the annotations by overriding formatSourceAnnotation in a subclass. The output of the annotation is delayed until some actual text is output for two reasons: - 1. setPosition bytecode follows setSourceFile, and we need position + 1. ``setPosition`` bytecode follows ``setSourceFile``, and we need position information to output the line number. - 2. Comments are not allowed in XML documents before the <?xml?> + 2. Comments are not allowed in XML documents before the ``<?xml?>`` declaration. For performance reasons (TODO: premature optimization?) instead of checking - the value of _pending_source_annotation on every write to the output - stream, the _stream_write attribute is changed to point to - _annotated_stream_write method whenever _pending_source_annotation is + the value of ``_pending_source_annotation`` on every write to the output + stream, the ``_stream_write`` attribute is changed to point to + ``_annotated_stream_write`` method whenever ``_pending_source_annotation`` is set to True, and to _stream.write when it is False. The following - invariant always holds: + invariant always holds:: if self._pending_source_annotation: assert self._stream_write is self._annotated_stream_write @@ -149,36 +149,31 @@ class TALInterpreter(object): sourceAnnotations=0): """Create a TAL interpreter. - Optional arguments: - - stream -- output stream (defaults to sys.stdout). + :param program: A compiled program, as generated + by :class:`zope.tal.talgenerator.TALGenerator` + :param macros: Namespace of macros, usually also from + :class:`~.TALGenerator` - debug -- enable debugging output to sys.stderr (off by default). + Optional arguments: - wrap -- try to wrap attributes on opening tags to this number of + :keyword stream: output stream (defaults to sys.stdout). + :keyword bool debug: enable debugging output to sys.stderr (off by default). + :keyword int wrap: try to wrap attributes on opening tags to this number of column (default: 1023). - - metal -- enable METAL macro processing (on by default). - - tal -- enable TAL processing (on by default). - - showtal -- do not strip away TAL directives. A special value of + :keyword bool metal: enable METAL macro processing (on by default). + :keyword bool tal: enable TAL processing (on by default). + :keyword int showtal: do not strip away TAL directives. A special value of -1 (which is the default setting) enables showtal when TAL processing is disabled, and disables showtal when TAL processing is enabled. Note that you must use 0, 1, or -1; true boolean values - are not supported (TODO: why?). - - strictinsert -- enable TAL processing and stricter HTML/XML + are not supported (for historical reasons). + :keyword bool strictinsert: enable TAL processing and stricter HTML/XML checking on text produced by structure inserts (on by default). Note that Zope turns this value off by default. - - stackLimit -- set macro nesting limit (default: 100). - - i18nInterpolate -- enable i18n translations (default: on). - - sourceAnnotations -- enable source annotations with HTML comments + :keyword int stackLimit: set macro nesting limit (default: 100). + :keyword bool i18nInterpolate: enable i18n translations (default: on). + :keyword bool sourceAnnotations: enable source annotations with HTML comments (default: off). - """ self.program = program self.macros = macros @@ -266,6 +261,11 @@ class TALInterpreter(object): return self.macroStack.pop() def __call__(self): + """ + Interpret the current program. + + :return: Nothing. + """ assert self.level == 0 assert self.scopeLevel == 0 assert self.i18nContext.parent is None @@ -1017,8 +1017,7 @@ class TALInterpreter(object): class FasterStringIO(list): - """Unicode-aware append-only version of StringIO. - """ + # Unicode-aware append-only version of StringIO. write = list.append def __init__(self, value=None): diff --git a/src/zope/tal/talparser.py b/src/zope/tal/talparser.py index 9adba2d..d99fc9f 100644 --- a/src/zope/tal/talparser.py +++ b/src/zope/tal/talparser.py @@ -11,7 +11,9 @@ # FOR A PARTICULAR PURPOSE. # ############################################################################## -"""Parse XML and compile to TALInterpreter intermediate code. +""" +Parse XML and compile to :class:`~.TALInterpreter` intermediate code, +using a :class:`~.TALGenerator`. """ from zope.tal.taldefs import XML_NS, ZOPE_I18N_NS, ZOPE_METAL_NS, ZOPE_TAL_NS from zope.tal.talgenerator import TALGenerator @@ -19,10 +21,22 @@ from zope.tal.xmlparser import XMLParser class TALParser(XMLParser): + """ + Parser for XML. + + After parsing with :meth:`~.XMLParser.parseFile`, + :meth:`~.XMLParser.parseString`, :meth:`~.XMLParser.parseURL` or + :meth:`~.XMLParser.parseStream`, you can call :meth:`getCode` to + retrieve the parsed program and macros. + """ ordered_attributes = 1 def __init__(self, gen=None, encoding=None): # Override + """ + :keyword TALGenerator gen: The configured (with an expression compiler) + code generator to use. If one is not given, a default will be used. + """ XMLParser.__init__(self, encoding) if gen is None: gen = TALGenerator() @@ -32,6 +46,7 @@ class TALParser(XMLParser): self.nsNew = [] def getCode(self): + """Return the compiled program and macros after parsing.""" return self.gen.getCode() def StartNamespaceDeclHandler(self, prefix, uri): @@ -117,7 +132,7 @@ class TALParser(XMLParser): def EndElementHandler(self, name): name = self.fixname(name)[0] - self.gen.emitEndElement(name, position=self.getpos()) + self.gen.emitEndElement(name, position=self.getpos()) def DefaultHandler(self, text): self.gen.emitRawText(text) diff --git a/src/zope/tal/xmlparser.py b/src/zope/tal/xmlparser.py index 9081d37..ca5c216 100644 --- a/src/zope/tal/xmlparser.py +++ b/src/zope/tal/xmlparser.py @@ -32,6 +32,9 @@ except NameError: class XMLParser(object): + """ + Parse XML using :mod:`xml.parsers.expat`. + """ ordered_attributes = 0 @@ -82,10 +85,12 @@ class XMLParser(object): return expat.ParserCreate(encoding, ' ') def parseFile(self, filename): + """Parse from the given filename.""" with open(filename, 'rb') as f: self.parseStream(f) def parseString(self, s): + """Parse the given string.""" if isinstance(s, unicode): # Expat cannot deal with unicode strings, only with # encoded ones. Also, its range of encodings is rather @@ -94,9 +99,11 @@ class XMLParser(object): self.parser.Parse(s, 1) def parseURL(self, url): + """Parse the given URL.""" self.parseStream(urlopen(url)) def parseStream(self, stream): + """Parse the given stream (open file).""" self.parser.ParseFile(stream) def parseFragment(self, s, end=0): @@ -113,4 +120,3 @@ class XMLParser(object): # [1] http://python.org/doc/current/lib/xmlparser-objects.html # [2] http://cvs.sourceforge.net/viewcvs.py/expat/expat/lib/expat.h return (self.parser.ErrorLineNumber, self.parser.ErrorColumnNumber) - |