Mercurial > genshi > mirror
changeset 21:b4d17897d053 trunk
* Include paths are now interpreted relative to the path of the including template. Closes #3.
* The filename is now included as first item in the `pos` tuple of stream events.
* Simplified the "basic" example so that it actually ''is'' basic.
* Added a more complex example using nested relative includes in [source:/trunk/examples/includes/ examples/includes].
author | cmlenz |
---|---|
date | Tue, 20 Jun 2006 13:05:37 +0000 |
parents | cc92d74ce9e5 |
children | 2483fe549959 |
files | examples/basic/common/default_header.html examples/basic/common/default_header.kid examples/basic/common/macros.html examples/basic/common/macros.kid examples/basic/kidrun.py examples/basic/layout.html examples/basic/layout.kid examples/basic/module/test.html examples/basic/module/test.kid examples/basic/run.py examples/basic/test.html examples/basic/test.kid examples/includes/common/macros.html examples/includes/module/test.html examples/includes/run.py examples/includes/skins/default/footer.html examples/includes/skins/default/header.html examples/includes/skins/default/layout.html markup/__init__.py markup/filters.py markup/input.py markup/plugin.py markup/template.py markup/tests/core.py markup/tests/template.py |
diffstat | 21 files changed, 270 insertions(+), 126 deletions(-) [+] |
line wrap: on
line diff
deleted file mode 100644 --- a/examples/basic/common/default_header.html +++ /dev/null @@ -1,4 +0,0 @@ -<head> - <title>Hello ${hello}</title> - <style type="text/css">@import(style.css)</style> -</head>
deleted file mode 100644 --- a/examples/basic/common/default_header.kid +++ /dev/null @@ -1,3 +0,0 @@ -<head> - <title>Hello ${hello}</title> -</head>
--- a/examples/basic/kidrun.py +++ b/examples/basic/kidrun.py @@ -6,8 +6,7 @@ def test(): base_path = os.path.dirname(os.path.abspath(__file__)) - kid.path = kid.TemplatePath([os.path.join(base_path, 'common'), - os.path.join(base_path, 'module')]) + kid.path = kid.TemplatePath([base_path]) ctxt = dict(hello='<world>', hey='ZYX', bozz=None, items=['Number %d' % num for num in range(1, 15)],
rename from examples/basic/common/macros.html rename to examples/basic/layout.html --- a/examples/basic/common/macros.html +++ b/examples/basic/layout.html @@ -1,8 +1,11 @@ -<div xmlns:py="http://purl.org/kid/ns#" - py:strip=""> +<div xmlns:py="http://purl.org/kid/ns#" py:strip=""> + <head> + <title>Hello ${hello}</title> + <style type="text/css">@import(style.css)</style> + </head> <div py:def="macro1">reference me, please</div> <div py:def="macro2(name, classname='expanded')" class="${classname}"> - Hello ${name.title()} + Hello ${name.title()} </div> <span py:match="greeting" class="greeting"> Hello ${select('@name')}
rename from examples/basic/common/macros.kid rename to examples/basic/layout.kid --- a/examples/basic/common/macros.kid +++ b/examples/basic/layout.kid @@ -1,13 +1,15 @@ -<div xmlns:py="http://purl.org/kid/ns#" - py:extends="'default_header.kid'" py:strip=""> +<div xmlns:py="http://purl.org/kid/ns#" py:strip=""> + <head> + <title>Hello ${hello}</title> + <style type="text/css">@import(style.css)</style> + </head> <div py:def="macro1">reference me, please</div> <div py:def="macro2(name, classname='expanded')" class="${classname}"> - Hello ${name.title()} + Hello ${name.title()} </div> <span py:match="item.tag == '{http://www.w3.org/1999/xhtml}greeting'" class="greeting"> Hello ${item.get('name')} </span> - <span py:match="item.tag == '{http://www.w3.org/1999/xhtml}span' and item.get('class') == 'greeting'" style="text-decoration: underline"> - ${item.findtext('')} - </span> + <span py:match="item.tag == '{http://www.w3.org/1999/xhtml}span' and item.get('class') == 'greeting'" + py:content="item.findtext('')" style="text-decoration: underline" /> </div>
--- a/examples/basic/run.py +++ b/examples/basic/run.py @@ -9,9 +9,7 @@ def test(): base_path = os.path.dirname(os.path.abspath(__file__)) - loader = TemplateLoader([os.path.join(base_path, 'common'), - os.path.join(base_path, 'module')], - auto_reload=True) + loader = TemplateLoader([base_path], auto_reload=True) start = datetime.now() tmpl = loader.load('test.html')
rename from examples/basic/module/test.html rename to examples/basic/test.html --- a/examples/basic/module/test.html +++ b/examples/basic/test.html @@ -3,9 +3,9 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#" - xmlns:xi="http://www.w3.org/2001/XInclude"> - <xi:include href="${skin}_header.html" /> - <xi:include href="macros.html" /> + xmlns:xi="http://www.w3.org/2001/XInclude" + lang="en"> + <xi:include href="layout.html" /> <xi:include href="custom_stuff.html"><xi:fallback/></xi:include> <body class="$bozz"> <ul py:attrs="{'id': 'second', 'class': None}" py:if="len(items) > 0">
rename from examples/basic/module/test.kid rename to examples/basic/test.kid --- a/examples/basic/module/test.kid +++ b/examples/basic/test.kid @@ -1,8 +1,10 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#" - py:extends="'macros.kid'" lang="en"> +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:py="http://purl.org/kid/ns#" + py:extends="'layout.kid'" + lang="en"> <body class="${bozz}"> <ul py:attrs="{'id': 'second', 'class': None}" py:if="len(items) > 0"> <li py:for="item in items">Item $prefix${item.split()[-1]}</li>
new file mode 100644 --- /dev/null +++ b/examples/includes/common/macros.html @@ -0,0 +1,12 @@ +<div xmlns:py="http://purl.org/kid/ns#" + py:strip=""> + <div py:def="macro1">reference me, please</div> + <div py:def="macro2(name, classname='expanded')" class="${classname}"> + Hello ${name.title()} + </div> + <span py:match="greeting" class="greeting"> + Hello ${select('@name')} + </span> + <span py:match="span[@class='greeting']" style="text-decoration: underline" + py:content="select('text()')"/> +</div>
new file mode 100644 --- /dev/null +++ b/examples/includes/module/test.html @@ -0,0 +1,22 @@ +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:py="http://purl.org/kid/ns#" + xmlns:xi="http://www.w3.org/2001/XInclude"> + <xi:include href="${skin}/layout.html" /> + <xi:include href="custom_stuff.html"><xi:fallback/></xi:include> + <body class="$bozz"> + <ul py:attrs="{'id': 'second', 'class': None}" py:if="len(items) > 0"> + <li py:for="item in items">Item ${item.split()[-1]}</li> + XYZ ${hey} + </ul> + ${macro1()} ${macro1()} ${macro1()} + ${macro2('john')} + ${macro2('kate', classname='collapsed')} + <div py:content="macro2('helmut')" py:strip="">Replace me</div> + <greeting name="Dude" /> + <greeting name="King" /> + <span class="greeting">Hello Silicon</span> + </body> +</html>
new file mode 100755 --- /dev/null +++ b/examples/includes/run.py @@ -0,0 +1,50 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +from datetime import datetime, timedelta +import os +import sys +import timing + +from markup.template import Context, TemplateLoader + +def test(): + base_path = os.path.dirname(os.path.abspath(__file__)) + loader = TemplateLoader([os.path.join(base_path, 'skins'), + os.path.join(base_path, 'module'), + os.path.join(base_path, 'common')]) + + timing.start() + tmpl = loader.load('test.html') + timing.finish() + print ' --> parse stage: %dms' % timing.milli() + + data = dict(hello='<world>', skin='default', hey='ZYX', bozz=None, + items=['Number %d' % num for num in range(1, 15)]) + + print tmpl.generate(Context(**data)).render(method='html') + + times = [] + for i in range(100): + timing.start() + list(tmpl.generate(Context(**data))) + timing.finish() + sys.stdout.write('.') + sys.stdout.flush() + times.append(timing.milli()) + print + + print ' --> render stage: %dms (avg), %dms (min), %dms (max)' % ( + sum(times) / len(times), min(times), max(times)) + +if __name__ == '__main__': + if '-p' in sys.argv: + import hotshot, hotshot.stats + prof = hotshot.Profile("template.prof") + benchtime = prof.runcall(test) + stats = hotshot.stats.load("template.prof") + stats.strip_dirs() + stats.sort_stats('time', 'calls') + stats.print_stats() + else: + test()
new file mode 100644 --- /dev/null +++ b/examples/includes/skins/default/footer.html @@ -0,0 +1,4 @@ +<div id="footer"> + <hr /> + <h1>And goodbye</h1> +</div>
new file mode 100644 --- /dev/null +++ b/examples/includes/skins/default/header.html @@ -0,0 +1,3 @@ +<div id="masthead"> + <h1>Welcome</h1> +</div> \ No newline at end of file
new file mode 100644 --- /dev/null +++ b/examples/includes/skins/default/layout.html @@ -0,0 +1,17 @@ +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:py="http://purl.org/kid/ns#" + xmlns:xi="http://www.w3.org/2001/XInclude" + py:strip=""> + <xi:include href="../macros.html" /> + <head> + <title>Hello ${hello}</title> + <style type="text/css">@import(style.css)</style> + </head> + <body py:match="body"> + <xi:include href="header.html" /> + <div id="content"> + ${select('body/*')} + </div> + <xi:include href="footer.html" /> + </body> +</html>
--- a/markup/__init__.py +++ b/markup/__init__.py @@ -54,4 +54,4 @@ """ from markup.core import * -from markup.input import XML, HTML +from markup.input import ParseError, XML, HTML
--- a/markup/filters.py +++ b/markup/filters.py @@ -53,7 +53,6 @@ ns_prefixes = [] in_fallback = False include_href, fallback_stream = None, None - indent = 0 for kind, data, pos in stream: @@ -62,7 +61,6 @@ tag, attrib = data if tag.localname == 'include': include_href = attrib.get('href') - indent = pos[1] elif tag.localname == 'fallback': in_fallback = True fallback_stream = [] @@ -73,7 +71,8 @@ if not include_href: raise TemplateError('Include misses required ' 'attribute "href"') - template = self.loader.load(include_href) + template = self.loader.load(include_href, + relative_to=pos[0]) for event in template.generate(ctxt): yield event @@ -85,7 +84,6 @@ include_href = None fallback_stream = None - indent = 0 elif data.localname == 'fallback': in_fallback = False
--- a/markup/input.py +++ b/markup/input.py @@ -24,12 +24,24 @@ from markup.core import Attributes, Markup, QName, Stream +class ParseError(Exception): + """Exception raised when fatal syntax errors are found in the input being + parsed.""" + + def __init__(self, message, filename='<string>', lineno=-1, offset=-1): + Exception.__init__(self, message) + self.filename = filename + self.lineno = lineno + self.offset = offset + + class XMLParser(object): """Generator-based XML parser based on roughly equivalent code in Kid/ElementTree.""" - def __init__(self, source): + def __init__(self, source, filename=None): self.source = source + self.filename = filename # Setup the Expat parser parser = expat.ParserCreate('utf-8', '}') @@ -48,73 +60,80 @@ # Location reporting is only support in Python >= 2.4 if not hasattr(parser, 'CurrentLineNumber'): - self.getpos = self._getpos_unknown + self._getpos = self._getpos_unknown self.expat = parser - self.queue = [] + self._queue = [] def __iter__(self): - bufsize = 4 * 1024 # 4K - done = False - while True: - while not done and len(self.queue) == 0: - data = self.source.read(bufsize) - if data == '': # end of data - if hasattr(self, 'expat'): - self.expat.Parse('', True) - del self.expat # get rid of circular references - done = True - else: - self.expat.Parse(data, False) - for event in self.queue: - yield event - self.queue = [] - if done: - break + try: + bufsize = 4 * 1024 # 4K + done = False + while True: + while not done and len(self._queue) == 0: + data = self.source.read(bufsize) + if data == '': # end of data + if hasattr(self, 'expat'): + self.expat.Parse('', True) + del self.expat # get rid of circular references + done = True + else: + self.expat.Parse(data, False) + for event in self._queue: + yield event + self._queue = [] + if done: + break + except expat.ExpatError, e: + msg = str(e) + if self.filename: + msg += ', in ' + self.filename + raise ParseError(msg, self.filename, e.lineno, e.offset) def _getpos_unknown(self): - return (-1, -1) + return (self.filename or '<string>', -1, -1) - def getpos(self): - return self.expat.CurrentLineNumber, self.expat.CurrentColumnNumber + def _getpos(self): + return (self.filename or '<string>', self.expat.CurrentLineNumber, + self.expat.CurrentColumnNumber) def _handle_start(self, tag, attrib): - self.queue.append((Stream.START, (QName(tag), Attributes(attrib.items())), - self.getpos())) + self._queue.append((Stream.START, (QName(tag), Attributes(attrib.items())), + self._getpos())) def _handle_end(self, tag): - self.queue.append((Stream.END, QName(tag), self.getpos())) + self._queue.append((Stream.END, QName(tag), self._getpos())) def _handle_data(self, text): - self.queue.append((Stream.TEXT, text, self.getpos())) + self._queue.append((Stream.TEXT, text, self._getpos())) def _handle_prolog(self, version, encoding, standalone): - self.queue.append((Stream.PROLOG, (version, encoding, standalone), - self.getpos())) + self._queue.append((Stream.PROLOG, (version, encoding, standalone), + self._getpos())) def _handle_doctype(self, name, sysid, pubid, has_internal_subset): - self.queue.append((Stream.DOCTYPE, (name, pubid, sysid), self.getpos())) + self._queue.append((Stream.DOCTYPE, (name, pubid, sysid), self._getpos())) def _handle_start_ns(self, prefix, uri): - self.queue.append((Stream.START_NS, (prefix or '', uri), self.getpos())) + self._queue.append((Stream.START_NS, (prefix or '', uri), self._getpos())) def _handle_end_ns(self, prefix): - self.queue.append((Stream.END_NS, prefix or '', self.getpos())) + self._queue.append((Stream.END_NS, prefix or '', self._getpos())) def _handle_pi(self, target, data): - self.queue.append((Stream.PI, (target, data), self.getpos())) + self._queue.append((Stream.PI, (target, data), self._getpos())) def _handle_comment(self, text): - self.queue.append((Stream.COMMENT, text, self.getpos())) + self._queue.append((Stream.COMMENT, text, self._getpos())) def _handle_other(self, text): if text.startswith('&'): # deal with undefined entities try: text = unichr(htmlentitydefs.name2codepoint[text[1:-1]]) - self.queue.append((Stream.TEXT, text, self.getpos())) + self._queue.append((Stream.TEXT, text, self._getpos())) except KeyError: - lineno, offset = self.getpos() + lineno, offset = self._getpos() raise expat.error("undefined entity %s: line %d, column %d" % (text, lineno, offset)) @@ -123,7 +142,7 @@ return Stream(list(XMLParser(StringIO(text)))) -class HTMLParser(html.HTMLParser): +class HTMLParser(html.HTMLParser, object): """Parser for HTML input based on the Python `HTMLParser` module. This class provides the same interface for generating stream events as @@ -134,68 +153,79 @@ 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param']) - def __init__(self, source): + def __init__(self, source, filename=None): html.HTMLParser.__init__(self) self.source = source - self.queue = [] + self.filename = filename + self._queue = [] self._open_tags = [] def __iter__(self): - bufsize = 4 * 1024 # 4K - done = False - while True: - while not done and len(self.queue) == 0: - data = self.source.read(bufsize) - if data == '': # end of data - self.close() - done = True - else: - self.feed(data) - for kind, data, pos in self.queue: - yield kind, data, pos - self.queue = [] - if done: - open_tags = self._open_tags - open_tags.reverse() - for tag in open_tags: - yield Stream.END, QName(tag), pos - break + try: + bufsize = 4 * 1024 # 4K + done = False + while True: + while not done and len(self._queue) == 0: + data = self.source.read(bufsize) + if data == '': # end of data + self.close() + done = True + else: + self.feed(data) + for kind, data, pos in self._queue: + yield kind, data, pos + self._queue = [] + if done: + open_tags = self._open_tags + open_tags.reverse() + for tag in open_tags: + yield Stream.END, QName(tag), pos + break + except html.HTMLParseError, e: + msg = '%s: line %d, column %d' % (e.msg, e.lineno, e.offset) + if self.filename: + msg += ', in %s' % self.filename + raise ParseError(msg, self.filename, e.lineno, e.offset) + + def _getpos(self): + lineno, column = self.getpos() + return (self.filename, lineno, column) def handle_starttag(self, tag, attrib): - pos = self.getpos() - self.queue.append((Stream.START, (QName(tag), Attributes(attrib)), pos)) + pos = self._getpos() + self._queue.append((Stream.START, (QName(tag), Attributes(attrib)), pos)) if tag in self._EMPTY_ELEMS: - self.queue.append((Stream.END, QName(tag), pos)) + self._queue.append((Stream.END, QName(tag), pos)) else: self._open_tags.append(tag) def handle_endtag(self, tag): if tag not in self._EMPTY_ELEMS: - pos = self.getpos() + pos = self._getpos() while self._open_tags: open_tag = self._open_tags.pop() if open_tag.lower() == tag.lower(): break - self.queue.append((Stream.END, QName(open_tag), pos)) - self.queue.append((Stream.END, QName(tag), pos)) + self._queue.append((Stream.END, QName(open_tag), pos)) + self._queue.append((Stream.END, QName(tag), pos)) def handle_data(self, text): - self.queue.append((Stream.TEXT, text, self.getpos())) + self._queue.append((Stream.TEXT, text, self._getpos())) def handle_charref(self, name): - self.queue.append((Stream.TEXT, Markup('&#%s;' % name), self.getpos())) + self._queue.append((Stream.TEXT, Markup('&#%s;' % name), self._getpos())) def handle_entityref(self, name): - self.queue.append((Stream.TEXT, Markup('&%s;' % name), self.getpos())) + self._queue.append((Stream.TEXT, Markup('&%s;' % name), self._getpos())) def handle_pi(self, data): target, data = data.split(maxsplit=1) data = data.rstrip('?') - self.queue.append((Stream.PI, (target.strip(), data.strip()), - self.getpos())) + self._queue.append((Stream.PI, (target.strip(), data.strip()), + self._getpos())) def handle_comment(self, text): - self.queue.append((Stream.COMMENT, text, self.getpos())) + self._queue.append((Stream.COMMENT, text, self._getpos())) def HTML(text):
--- a/markup/plugin.py +++ b/markup/plugin.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (C) 2006 Mattew Good +# Copyright (C) 2006 Matthew Good # All rights reserved. # # This software is licensed as described in the file COPYING, which @@ -34,18 +34,16 @@ if divider >= 0: package = templatename[:divider] basename = templatename[divider + 1:] + '.html' - fullpath = resource_filename(package, basename) - dirname, templatename = os.path.split(fullpath) - self.loader.search_path.append(dirname) # Kludge + templatename = resource_filename(package, basename) return self.loader.load(templatename) def render(self, info, format='html', fragment=False, template=None): - """Renders the template to a string using the provided info.""" + """Render the template to a string using the provided info.""" return self.transform(info, template).render(method=format) def transform(self, info, template): - "Render the output to Elements" + """Render the output to an event stream.""" if not isinstance(template, Template): template = self.load_template(template)
--- a/markup/template.py +++ b/markup/template.py @@ -43,6 +43,7 @@ import compiler import os +import posixpath import re from StringIO import StringIO @@ -574,20 +575,24 @@ _dir_by_name = dict(directives) _dir_order = [directive[1] for directive in directives] - def __init__(self, source, filename=None): + def __init__(self, source, basedir=None, filename=None): """Initialize a template from either a string or a file-like object.""" if isinstance(source, basestring): self.source = StringIO(source) else: self.source = source + self.basedir = basedir self.filename = filename or '<string>' + if basedir and filename: + self.filepath = os.path.join(basedir, filename) + else: + self.filepath = '<string>' self.filters = [self._eval, self._match] self.parse() def __repr__(self): - return '<%s "%s">' % (self.__class__.__name__, - os.path.basename(self.filename)) + return '<%s "%s">' % (self.__class__.__name__, self.filename) def parse(self): """Parse the template. @@ -603,7 +608,7 @@ ns_prefix = {} depth = 0 - for kind, data, pos in XMLParser(self.source): + for kind, data, pos in XMLParser(self.source, filename=self.filename): if kind is Stream.START_NS: # Strip out the namespace declaration for template directives @@ -628,7 +633,7 @@ if name in self.NAMESPACE: cls = self._dir_by_name.get(name.localname) if cls is None: - raise BadDirectiveError(name, self.filename, pos[0]) + raise BadDirectiveError(name, self.filename, pos[1]) else: directives.append(cls(self, value, pos)) else: @@ -666,7 +671,7 @@ _FULL_EXPR_RE = re.compile(r'(?<!\$)\$\{(.+?)\}') _SHORT_EXPR_RE = re.compile(r'(?<!\$)\$([a-zA-Z][a-zA-Z0-9_\.]*)') - def _interpolate(cls, text, lineno=-1, offset=-1): + def _interpolate(cls, text, filename=None, lineno=-1, offset=-1): """Parse the given string and extract expressions. This method returns a list containing both literal text and `Expression` @@ -768,8 +773,8 @@ else: yield kind, data, pos except SyntaxError, err: - raise TemplateSyntaxError(err, self.filename, pos[0], - pos[1] + (err.offset or 0)) + raise TemplateSyntaxError(err, self.filename, pos[1], + pos[2] + (err.offset or 0)) def _match(self, stream, ctxt=None): for kind, data, pos in stream: @@ -783,7 +788,7 @@ for idx, (test, path, template) in enumerate(ctxt._match_templates): if (kind, data, pos) in template[::len(template)]: # This is the event this match template produced itself, so - # matching it again would result in an infinite loop + # matching it again would result in an infinite loop continue result = test(kind, data, pos) @@ -804,7 +809,7 @@ # enable the path to keep track of the stream state test(*event) - content = list(self._flatten(content, ctxt, apply_filters=False)) + content = list(self._flatten(content, ctxt, False)) def _apply(stream, ctxt): stream = list(stream) @@ -865,7 +870,7 @@ self._cache = {} self._mtime = {} - def load(self, filename): + def load(self, filename, relative_to=None): """Load the template with the given name. This method searches the search path trying to locate a template @@ -877,13 +882,21 @@ file more than once. Thus, subsequent calls of this method with the same template file name will return the same `Template` object. + If the `relative_to` parameter is provided, the `filename` is + interpreted as being relative to that path. + @param filename: the relative path of the template file to load + @param relative_to: the filename of the template from which the new + template is being loaded, or `None` if the template is being loaded + directly """ + if relative_to: + filename = posixpath.join(posixpath.dirname(relative_to), filename) filename = os.path.normpath(filename) try: tmpl = self._cache[filename] if not self.auto_reload or \ - os.path.getmtime(tmpl.filename) == self._mtime[filename]: + os.path.getmtime(tmpl.filepath) == self._mtime[filename]: return tmpl except KeyError: pass @@ -892,7 +905,7 @@ try: fileobj = file(filepath, 'rt') try: - tmpl = Template(fileobj, filename=filepath) + tmpl = Template(fileobj, basedir=dirname, filename=filename) tmpl.filters.append(IncludeFilter(self)) finally: fileobj.close()
--- a/markup/tests/core.py +++ b/markup/tests/core.py @@ -12,10 +12,10 @@ # history and logs, available at http://projects.edgewall.com/trac/. import doctest -from HTMLParser import HTMLParseError import unittest from markup.core import * +from markup.input import ParseError class MarkupTestCase(unittest.TestCase): @@ -123,9 +123,9 @@ markup = Markup('<SCRIPT SRC="http://example.com/"></SCRIPT>') self.assertEquals('', str(markup.sanitize())) markup = Markup('<SCR\0IPT>alert("foo")</SCR\0IPT>') - self.assertRaises(HTMLParseError, markup.sanitize().render) + self.assertRaises(ParseError, markup.sanitize().render) markup = Markup('<SCRIPT&XYZ SRC="http://example.com/"></SCRIPT>') - self.assertRaises(HTMLParseError, markup.sanitize().render) + self.assertRaises(ParseError, markup.sanitize().render) def test_sanitize_remove_onclick_attr(self): markup = Markup('<div onclick=\'alert("foo")\' />') @@ -156,7 +156,7 @@ self.assertEquals('<img/>', str(markup.sanitize())) # Grave accents (not parsed) markup = Markup('<IMG SRC=`javascript:alert("RSnake says, \'foo\'")`>') - self.assertRaises(HTMLParseError, markup.sanitize().render) + self.assertRaises(ParseError, markup.sanitize().render) # Protocol encoded using UTF-8 numeric entities markup = Markup('<IMG SRC=\'javascri' 'pt:alert("foo")\'>')
--- a/markup/tests/template.py +++ b/markup/tests/template.py @@ -69,7 +69,7 @@ def test_bad_directive_error(self): xml = '<p xmlns:py="http://purl.org/kid/ns#" py:do="nothing" />' try: - tmpl = Template(xml, 'test.html') + tmpl = Template(xml, filename='test.html') except BadDirectiveError, e: self.assertEqual('test.html', e.filename) if sys.version_info[:2] >= (2, 4): @@ -77,7 +77,7 @@ def test_directive_value_syntax_error(self): xml = '<p xmlns:py="http://purl.org/kid/ns#" py:if="bar\'" />' - tmpl = Template(xml, 'test.html') + tmpl = Template(xml, filename='test.html') try: list(tmpl.generate(Context())) self.fail('Expected SyntaxError')