changeset 145:47bbd9d2a5af trunk

* 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.
author cmlenz
date Tue, 15 Aug 2006 09:52:47 +0000
parents d1ce85a7f296
children 04799355362d
files markup/core.py markup/eval.py markup/filters.py markup/input.py markup/output.py markup/path.py markup/plugin.py markup/template.py markup/tests/path.py markup/tests/template.py setup.py
diffstat 11 files changed, 67 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- 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):
--- 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']
 
 
--- 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
--- 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
 
--- 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']
 
--- 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('/'):
--- 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
--- 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
--- a/markup/tests/path.py
+++ b/markup/tests/path.py
@@ -31,7 +31,7 @@
         xml = XML('<root><elem/></root>')
 
         path = Path('elem')
-        self.assertEqual('<Path "descendant::elem">', repr(path))
+        self.assertEqual('<Path "child::elem">', repr(path))
         self.assertEqual('<elem/>', path.select(xml).render())
 
         path = Path('child::elem')
@@ -62,7 +62,7 @@
         xml = XML('<root><elem/></root>')
 
         path = Path('*')
-        self.assertEqual('<Path "descendant::*">', repr(path))
+        self.assertEqual('<Path "child::*">', repr(path))
         self.assertEqual('<elem/>', path.select(xml).render())
 
         path = Path('child::*')
@@ -94,7 +94,7 @@
         xml = XML('<root>Hey</root>')
 
         path = Path('text()')
-        self.assertEqual('<Path "descendant::text()">', repr(path))
+        self.assertEqual('<Path "child::text()">', repr(path))
         self.assertEqual('Hey', path.select(xml).render())
 
         path = Path('./text()')
@@ -116,30 +116,46 @@
         self.assertEqual('<bar/>', Path('bar').select(xml).render())
         self.assertEqual('', Path('baz').select(xml).render())
 
+    def test_2step_attribute(self):
+        xml = XML('<elem class="x"><span id="joe">Hey Joe</span></elem>')
+        #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('<elem><foo id="1"/>foo id="2"/></elem>')
+        #self.assertEqual('', Path('@*').select(xml).render())
+        #self.assertEqual('12', Path('foo/@*').select(xml).render())
+
     def test_2step_complex(self):
         xml = XML('<root><foo><bar/></foo></root>')
 
         path = Path('foo/bar')
-        self.assertEqual('<Path "descendant::foo/child::bar">', repr(path))
+        self.assertEqual('<Path "child::foo/child::bar">', repr(path))
         self.assertEqual('<bar/>', path.select(xml).render())
 
+        path = Path('./bar')
+        self.assertEqual('<Path "self::node()/child::bar">', repr(path))
+        #self.assertEqual('', path.select(xml).render())
+
         path = Path('foo/*')
-        self.assertEqual('<Path "descendant::foo/child::*">', repr(path))
+        self.assertEqual('<Path "child::foo/child::*">', repr(path))
         self.assertEqual('<bar/>', path.select(xml).render())
 
         xml = XML('<root><foo><bar id="1"/></foo><bar id="2"/></root>')
-        self.assertEqual('<bar id="1"/><bar id="2"/>',
-                         Path('bar').select(xml).render())
+        path = Path('./bar')
+        self.assertEqual('<Path "self::node()/child::bar">', repr(path))
+        #self.assertEqual('<bar id="2"/>', path.select(xml).render())
 
     def test_2step_text(self):
         xml = XML('<root><item>Foo</item></root>')
 
         path = Path('item/text()')
-        self.assertEqual('<Path "descendant::item/child::text()">', repr(path))
+        self.assertEqual('<Path "child::item/child::text()">', repr(path))
         self.assertEqual('Foo', path.select(xml).render())
 
         path = Path('*/text()')
-        self.assertEqual('<Path "descendant::*/child::text()">', repr(path))
+        self.assertEqual('<Path "child::*/child::text()">', 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('<Path "self::node()/child::text()">', repr(path))
+        #self.assertEqual('', path.select(xml).render())
+
         xml = XML('<root><item>Foo</item><item>Bar</item></root>')
-        self.assertEqual('FooBar', Path('item/text()').select(xml).render())
+        path = Path('item/text()')
+        self.assertEqual('<Path "child::item/child::text()">', repr(path))
+        self.assertEqual('FooBar', path.select(xml).render())
+
+        xml = XML('<root><item>Foo</item><item>Bar</item></root>')
+        self.assertEqual('FooBar', path.select(xml).render())
 
     def test_3step(self):
         xml = XML('<root><foo><bar/></foo></root>')
         path = Path('root/foo/*')
-        self.assertEqual('<Path "descendant::root/child::foo/child::*">',
+        self.assertEqual('<Path "child::root/child::foo/child::*">',
                          repr(path))
         self.assertEqual('<bar/>', path.select(xml).render())
 
     def test_3step_complex(self):
         xml = XML('<root><foo><bar/></foo></root>')
         path = Path('*/bar')
-        self.assertEqual('<Path "descendant::*/child::bar">', repr(path))
+        self.assertEqual('<Path "child::*/child::bar">', repr(path))
         self.assertEqual('<bar/>', path.select(xml).render())
 
         xml = XML('<root><foo><bar id="1"/></foo><bar id="2"/></root>')
@@ -173,39 +198,39 @@
     def test_node_type_comment(self):
         xml = XML('<root><!-- commented --></root>')
         path = Path('comment()')
-        self.assertEqual('<Path "descendant::comment()">', repr(path))
+        self.assertEqual('<Path "child::comment()">', repr(path))
         self.assertEqual('<!-- commented -->', path.select(xml).render())
 
     def test_node_type_text(self):
         xml = XML('<root>Some text <br/>in here.</root>')
         path = Path('text()')
-        self.assertEqual('<Path "descendant::text()">', repr(path))
+        self.assertEqual('<Path "child::text()">', repr(path))
         self.assertEqual('Some text in here.', path.select(xml).render())
 
     def test_node_type_node(self):
         xml = XML('<root>Some text <br/>in here.</root>')
         path = Path('node()')
-        self.assertEqual('<Path "descendant::node()">', repr(path))
+        self.assertEqual('<Path "child::node()">', repr(path))
         self.assertEqual('Some text <br/>in here.', path.select(xml).render())
 
     def test_node_type_processing_instruction(self):
         xml = XML('<?python x = 2 * 3 ?><root><?php echo("x") ?></root>')
 
         path = Path('processing-instruction()')
-        self.assertEqual('<Path "descendant::processing-instruction()">',
+        self.assertEqual('<Path "child::processing-instruction()">',
                          repr(path))
         self.assertEqual('<?python x = 2 * 3 ?><?php echo("x") ?>',
                          path.select(xml).render())
 
         path = Path('processing-instruction("php")')
-        self.assertEqual('<Path "descendant::processing-instruction(\"php\")">',
+        self.assertEqual('<Path "child::processing-instruction(\"php\")">',
                          repr(path))
         self.assertEqual('<?php echo("x") ?>', path.select(xml).render())
 
     def test_simple_union(self):
         xml = XML('<root>Oh <foo>my</foo></root>')
         path = Path('*|text()')
-        self.assertEqual('<Path "descendant::*|descendant::text()">',
+        self.assertEqual('<Path "child::*|child::text()">',
                          repr(path))
         self.assertEqual('Oh <foo>my</foo>', path.select(xml).render())
 
--- a/markup/tests/template.py
+++ b/markup/tests/template.py
@@ -496,6 +496,11 @@
         tmpl = Template('<root attr="${1}"/>')
         self.assertEqual('<root attr="1"/>', str(tmpl.generate()))
 
+    def test_interpolate_list_result(self):
+        tmpl = Template('<root>$foo</root>')
+        ctxt = Context(foo=('buzz',))
+        self.assertEqual('<root>buzz</root>', str(tmpl.generate(ctxt)))
+
     def test_empty_attr(self):
         tmpl = Template('<root attr=""/>')
         self.assertEqual('<root attr=""/>', str(tmpl.generate()))
--- 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
 
Copyright (C) 2012-2017 Edgewall Software