# HG changeset patch # User cmlenz # Date 1155635567 0 # Node ID 47bbd9d2a5af54ca67867d2896b87b1f02bca851 # Parent d1ce85a7f296da208d0efdf8e89d16fa4e691995 * Fix error in expression evaluation when the expression evaluates to an iterable that does not produce event tuples. * The first location step in path expressions longer assumes the `descendant::` axis, but rather the `child::` axis. * Import cleanups. diff --git a/markup/core.py b/markup/core.py --- a/markup/core.py +++ b/markup/core.py @@ -15,7 +15,6 @@ import htmlentitydefs import re -from StringIO import StringIO __all__ = ['Stream', 'Markup', 'escape', 'unescape', 'Namespace', 'QName'] @@ -145,11 +144,12 @@ def _ensure(stream): """Ensure that every item on the stream is actually a markup event.""" for event in stream: - try: - kind, data, pos = event - except ValueError: - kind, data, pos = event.totuple() - yield kind, data, pos + if type(event) is not tuple: + if hasattr(event, 'totuple'): + event = event.totuple() + else: + event = TEXT, unicode(event), (None, -1, -1) + yield event class Attributes(list): diff --git a/markup/eval.py b/markup/eval.py --- a/markup/eval.py +++ b/markup/eval.py @@ -18,8 +18,6 @@ from compiler.pycodegen import ExpressionCodeGenerator import new -from markup.core import Stream - __all__ = ['Expression'] diff --git a/markup/filters.py b/markup/filters.py --- a/markup/filters.py +++ b/markup/filters.py @@ -13,16 +13,14 @@ """Implementation of a number of stream filters.""" -from itertools import chain try: frozenset except NameError: from sets import ImmutableSet as frozenset import re -from markup.core import Attributes, Markup, Namespace, escape, stripentities -from markup.core import END, END_NS, START, START_NS, TEXT -from markup.path import Path +from markup.core import Attributes, Namespace, stripentities +from markup.core import END, END_NS, START, START_NS __all__ = ['HTMLSanitizer', 'IncludeFilter'] @@ -139,7 +137,7 @@ @param stream: the markup event stream to filter @param ctxt: the template context """ - from markup.template import Template, TemplateError, TemplateNotFound + from markup.template import TemplateError, TemplateNotFound ns_prefixes = [] in_fallback = False diff --git a/markup/input.py b/markup/input.py --- a/markup/input.py +++ b/markup/input.py @@ -21,7 +21,7 @@ import htmlentitydefs from StringIO import StringIO -from markup.core import Attributes, Markup, QName, Stream +from markup.core import Attributes, QName, Stream from markup.core import DOCTYPE, START, END, START_NS, END_NS, TEXT, \ START_CDATA, END_CDATA, PI, COMMENT diff --git a/markup/output.py b/markup/output.py --- a/markup/output.py +++ b/markup/output.py @@ -22,9 +22,9 @@ from sets import ImmutableSet as frozenset import re -from markup.core import escape, Markup, Namespace, QName, XML_NAMESPACE -from markup.core import DOCTYPE, START, END, START_NS, END_NS, TEXT, \ - START_CDATA, END_CDATA, PI, COMMENT +from markup.core import escape, Markup, Namespace, QName +from markup.core import DOCTYPE, START, END, START_NS, TEXT, START_CDATA, \ + END_CDATA, PI, COMMENT, XML_NAMESPACE __all__ = ['Serializer', 'XMLSerializer', 'HTMLSerializer'] diff --git a/markup/path.py b/markup/path.py --- a/markup/path.py +++ b/markup/path.py @@ -33,7 +33,7 @@ import re -from markup.core import QName, Stream, START, END, TEXT, COMMENT, PI +from markup.core import Stream, START, END, TEXT, COMMENT, PI __all__ = ['Path', 'PathSyntaxError'] @@ -281,9 +281,7 @@ axis, nodetest, predicates = self._location_step() if not axis: - # The default axis for the first step is "descendant", for other - # steps it's "child" - axis = steps and CHILD or DESCENDANT + axis = CHILD steps.append((axis, nodetest, predicates)) if self.at_end or not self.cur_token.startswith('/'): diff --git a/markup/plugin.py b/markup/plugin.py --- a/markup/plugin.py +++ b/markup/plugin.py @@ -16,11 +16,10 @@ CherryPy/Buffet. """ -import os from pkg_resources import resource_filename +from markup import Stream, QName from markup.template import Context, Template, TemplateLoader -from markup.core import Stream, QName def ET(element): tag_name = element.tag diff --git a/markup/template.py b/markup/template.py --- a/markup/template.py +++ b/markup/template.py @@ -25,8 +25,8 @@ import re from StringIO import StringIO -from markup.core import Attributes, Namespace, Stream, StreamEventKind -from markup.core import _ensure, START, END, START_NS, END_NS, TEXT, COMMENT +from markup.core import Attributes, Namespace, Stream, StreamEventKind, _ensure +from markup.core import START, END, START_NS, END_NS, TEXT, COMMENT from markup.eval import Expression from markup.input import XMLParser from markup.path import Path diff --git a/markup/tests/path.py b/markup/tests/path.py --- a/markup/tests/path.py +++ b/markup/tests/path.py @@ -31,7 +31,7 @@ xml = XML('') path = Path('elem') - self.assertEqual('', repr(path)) + self.assertEqual('', repr(path)) self.assertEqual('', path.select(xml).render()) path = Path('child::elem') @@ -62,7 +62,7 @@ xml = XML('') path = Path('*') - self.assertEqual('', repr(path)) + self.assertEqual('', repr(path)) self.assertEqual('', path.select(xml).render()) path = Path('child::*') @@ -94,7 +94,7 @@ xml = XML('Hey') path = Path('text()') - self.assertEqual('', repr(path)) + self.assertEqual('', repr(path)) self.assertEqual('Hey', path.select(xml).render()) path = Path('./text()') @@ -116,30 +116,46 @@ self.assertEqual('', Path('bar').select(xml).render()) self.assertEqual('', Path('baz').select(xml).render()) + def test_2step_attribute(self): + xml = XML('Hey Joe') + #self.assertEqual('x', Path('@*').select(xml).render()) + #self.assertEqual('x', Path('./@*').select(xml).render()) + #self.assertEqual('xjoe', Path('//@*').select(xml).render()) + self.assertEqual('joe', Path('*/@*').select(xml).render()) + + xml = XML('foo id="2"/>') + #self.assertEqual('', Path('@*').select(xml).render()) + #self.assertEqual('12', Path('foo/@*').select(xml).render()) + def test_2step_complex(self): xml = XML('') path = Path('foo/bar') - self.assertEqual('', repr(path)) + self.assertEqual('', repr(path)) self.assertEqual('', path.select(xml).render()) + path = Path('./bar') + self.assertEqual('', repr(path)) + #self.assertEqual('', path.select(xml).render()) + path = Path('foo/*') - self.assertEqual('', repr(path)) + self.assertEqual('', repr(path)) self.assertEqual('', path.select(xml).render()) xml = XML('') - self.assertEqual('', - Path('bar').select(xml).render()) + path = Path('./bar') + self.assertEqual('', repr(path)) + #self.assertEqual('', path.select(xml).render()) def test_2step_text(self): xml = XML('Foo') path = Path('item/text()') - self.assertEqual('', repr(path)) + self.assertEqual('', repr(path)) self.assertEqual('Foo', path.select(xml).render()) path = Path('*/text()') - self.assertEqual('', repr(path)) + self.assertEqual('', repr(path)) self.assertEqual('Foo', path.select(xml).render()) path = Path('//text()') @@ -147,20 +163,29 @@ repr(path)) self.assertEqual('Foo', path.select(xml).render()) + path = Path('./text()') + self.assertEqual('', repr(path)) + #self.assertEqual('', path.select(xml).render()) + xml = XML('FooBar') - self.assertEqual('FooBar', Path('item/text()').select(xml).render()) + path = Path('item/text()') + self.assertEqual('', repr(path)) + self.assertEqual('FooBar', path.select(xml).render()) + + xml = XML('FooBar') + self.assertEqual('FooBar', path.select(xml).render()) def test_3step(self): xml = XML('') path = Path('root/foo/*') - self.assertEqual('', + self.assertEqual('', repr(path)) self.assertEqual('', path.select(xml).render()) def test_3step_complex(self): xml = XML('') path = Path('*/bar') - self.assertEqual('', repr(path)) + self.assertEqual('', repr(path)) self.assertEqual('', path.select(xml).render()) xml = XML('') @@ -173,39 +198,39 @@ def test_node_type_comment(self): xml = XML('') path = Path('comment()') - self.assertEqual('', repr(path)) + self.assertEqual('', repr(path)) self.assertEqual('', path.select(xml).render()) def test_node_type_text(self): xml = XML('Some text
in here.
') path = Path('text()') - self.assertEqual('', repr(path)) + self.assertEqual('', repr(path)) self.assertEqual('Some text in here.', path.select(xml).render()) def test_node_type_node(self): xml = XML('Some text
in here.
') path = Path('node()') - self.assertEqual('', repr(path)) + self.assertEqual('', repr(path)) self.assertEqual('Some text
in here.', path.select(xml).render()) def test_node_type_processing_instruction(self): xml = XML('') path = Path('processing-instruction()') - self.assertEqual('', + self.assertEqual('', repr(path)) self.assertEqual('', path.select(xml).render()) path = Path('processing-instruction("php")') - self.assertEqual('', + self.assertEqual('', repr(path)) self.assertEqual('', path.select(xml).render()) def test_simple_union(self): xml = XML('Oh my') path = Path('*|text()') - self.assertEqual('', + self.assertEqual('', repr(path)) self.assertEqual('Oh my', path.select(xml).render()) diff --git a/markup/tests/template.py b/markup/tests/template.py --- a/markup/tests/template.py +++ b/markup/tests/template.py @@ -496,6 +496,11 @@ tmpl = Template('') self.assertEqual('', str(tmpl.generate())) + def test_interpolate_list_result(self): + tmpl = Template('$foo') + ctxt = Context(foo=('buzz',)) + self.assertEqual('buzz', str(tmpl.generate(ctxt))) + def test_empty_attr(self): tmpl = Template('') self.assertEqual('', str(tmpl.generate())) diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ # history and logs, available at http://markup.edgewall.org/log/. try: - from setuptools import setup, find_packages + from setuptools import setup except ImportError: from distutils.core import setup