# HG changeset patch # User cmlenz # Date 1258038566 0 # Node ID 24733a5854d9172a02ded5710b425e3cd733b14e # Parent 1e2be9fb3348d6fe22d4cf04486dc1dd285793d8 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary. diff --git a/doc/streams.txt b/doc/streams.txt --- a/doc/streams.txt +++ b/doc/streams.txt @@ -48,15 +48,15 @@ >>> for kind, data, pos in stream: ... print('%s %r %r' % (kind, data, pos)) ... - START (QName(u'p'), Attrs([(QName(u'class'), u'intro')])) (None, 1, 0) + START (QName('p'), Attrs([(QName('class'), u'intro')])) (None, 1, 0) TEXT u'Some text and ' (None, 1, 17) - START (QName(u'a'), Attrs([(QName(u'href'), u'http://example.org/')])) (None, 1, 31) + START (QName('a'), Attrs([(QName('href'), u'http://example.org/')])) (None, 1, 31) TEXT u'a link' (None, 1, 61) - END QName(u'a') (None, 1, 67) + END QName('a') (None, 1, 67) TEXT u'.' (None, 1, 71) - START (QName(u'br'), Attrs()) (None, 1, 72) - END QName(u'br') (None, 1, 77) - END QName(u'p') (None, 1, 77) + START (QName('br'), Attrs()) (None, 1, 72) + END QName('br') (None, 1, 77) + END QName('p') (None, 1, 77) Filtering @@ -379,7 +379,7 @@ .. code-block:: python - START, (QName(u'p'), Attrs([(QName(u'class'), u'intro')])), pos + START, (QName('p'), Attrs([(QName('class'), u'intro')])), pos END --- @@ -390,7 +390,7 @@ .. code-block:: python - END, QName(u'p'), pos + END, QName('p'), pos TEXT ---- diff --git a/genshi/core.py b/genshi/core.py --- a/genshi/core.py +++ b/genshi/core.py @@ -20,7 +20,7 @@ from itertools import chain import operator -from genshi.util import plaintext, stripentities, striptags +from genshi.util import plaintext, stripentities, striptags, stringrepr __all__ = ['Stream', 'Markup', 'escape', 'unescape', 'Attrs', 'Namespace', 'QName'] @@ -463,7 +463,7 @@ return Markup(num * unicode(self)) def __repr__(self): - return '<%s %r>' % (self.__class__.__name__, unicode(self)) + return "<%s %s>" % (self.__class__.__name__, unicode.__repr__(self)) def join(self, seq, escape_quotes=True): """Return a `Markup` object which is the concatenation of the strings @@ -600,7 +600,7 @@ >>> html = Namespace('http://www.w3.org/1999/xhtml') >>> html - + Namespace('http://www.w3.org/1999/xhtml') >>> html.uri u'http://www.w3.org/1999/xhtml' @@ -608,7 +608,7 @@ that namespace: >>> html.body - QName(u'http://www.w3.org/1999/xhtml}body') + QName('http://www.w3.org/1999/xhtml}body') >>> html.body.localname u'body' >>> html.body.namespace @@ -618,7 +618,7 @@ attribute names that are not valid Python identifiers: >>> html['body'] - QName(u'http://www.w3.org/1999/xhtml}body') + QName('http://www.w3.org/1999/xhtml}body') A `Namespace` object can also be used to test whether a specific `QName` belongs to that namespace using the ``in`` operator: @@ -665,7 +665,7 @@ return hash(self.uri) def __repr__(self): - return '' % self.uri + return 'Namespace(%s)' % stringrepr(self.uri) def __str__(self): return self.uri.encode('utf-8') @@ -688,14 +688,14 @@ >>> qname = QName('foo') >>> qname - QName(u'foo') + QName('foo') >>> qname.localname u'foo' >>> qname.namespace >>> qname = QName('http://www.w3.org/1999/xhtml}body') >>> qname - QName(u'http://www.w3.org/1999/xhtml}body') + QName('http://www.w3.org/1999/xhtml}body') >>> qname.localname u'body' >>> qname.namespace @@ -726,4 +726,4 @@ return (self.lstrip('{'),) def __repr__(self): - return 'QName(%s)' % unicode.__repr__(self.lstrip('{')) + return 'QName(%s)' % stringrepr(self.lstrip('{')) diff --git a/genshi/filters/tests/transform.py b/genshi/filters/tests/transform.py --- a/genshi/filters/tests/transform.py +++ b/genshi/filters/tests/transform.py @@ -544,29 +544,29 @@ def test_map_element(self): self.assertEqual( self._map('foo'), - [(QName(u'foo'), Attrs([(QName(u'name'), u'foo'), - (QName(u'size'), u'100')])), + [(QName('foo'), Attrs([(QName('name'), u'foo'), + (QName('size'), u'100')])), u'FOO', - QName(u'foo')] - ) + QName('foo')] + ) def test_map_with_text_kind(self): self.assertEqual( self._map('.', TEXT), [u'ROOT', u'FOO', u'BAR'] - ) + ) def test_map_with_root_and_end_kind(self): self.assertEqual( self._map('.', END), - [QName(u'foo'), QName(u'bar'), QName(u'root')] - ) + [QName('foo'), QName('bar'), QName('root')] + ) def test_map_with_attribute(self): self.assertEqual( self._map('foo/@name'), - [(QName(u'foo@*'), Attrs([('name', u'foo')]))] - ) + [(QName('foo@*'), Attrs([('name', u'foo')]))] + ) class SubstituteTest(unittest.TestCase): diff --git a/genshi/filters/transform.py b/genshi/filters/transform.py --- a/genshi/filters/transform.py +++ b/genshi/filters/transform.py @@ -235,13 +235,13 @@ >>> html = HTML('Some test text') >>> print(html | Transformer().select('.//em').trace()) - (None, ('START', (QName(u'body'), Attrs()), (None, 1, 0))) + (None, ('START', (QName('body'), Attrs()), (None, 1, 0))) (None, ('TEXT', u'Some ', (None, 1, 6))) - ('ENTER', ('START', (QName(u'em'), Attrs()), (None, 1, 11))) + ('ENTER', ('START', (QName('em'), Attrs()), (None, 1, 11))) ('INSIDE', ('TEXT', u'test', (None, 1, 15))) - ('EXIT', ('END', QName(u'em'), (None, 1, 19))) + ('EXIT', ('END', QName('em'), (None, 1, 19))) (None, ('TEXT', u' text', (None, 1, 24))) - (None, ('END', QName(u'body'), (None, 1, 29))) + (None, ('END', QName('body'), (None, 1, 29))) Some test text :param path: an XPath expression (as string) or a `Path` instance @@ -259,13 +259,13 @@ >>> html = HTML('Some test text') >>> print(html | Transformer('//em').invert().trace()) - ('OUTSIDE', ('START', (QName(u'body'), Attrs()), (None, 1, 0))) + ('OUTSIDE', ('START', (QName('body'), Attrs()), (None, 1, 0))) ('OUTSIDE', ('TEXT', u'Some ', (None, 1, 6))) - (None, ('START', (QName(u'em'), Attrs()), (None, 1, 11))) + (None, ('START', (QName('em'), Attrs()), (None, 1, 11))) (None, ('TEXT', u'test', (None, 1, 15))) - (None, ('END', QName(u'em'), (None, 1, 19))) + (None, ('END', QName('em'), (None, 1, 19))) ('OUTSIDE', ('TEXT', u' text', (None, 1, 24))) - ('OUTSIDE', ('END', QName(u'body'), (None, 1, 29))) + ('OUTSIDE', ('END', QName('body'), (None, 1, 29))) Some test text :rtype: `Transformer` @@ -279,13 +279,13 @@ >>> html = HTML('Some test text') >>> print(html | Transformer('//em').end().trace()) - ('OUTSIDE', ('START', (QName(u'body'), Attrs()), (None, 1, 0))) + ('OUTSIDE', ('START', (QName('body'), Attrs()), (None, 1, 0))) ('OUTSIDE', ('TEXT', u'Some ', (None, 1, 6))) - ('OUTSIDE', ('START', (QName(u'em'), Attrs()), (None, 1, 11))) + ('OUTSIDE', ('START', (QName('em'), Attrs()), (None, 1, 11))) ('OUTSIDE', ('TEXT', u'test', (None, 1, 15))) - ('OUTSIDE', ('END', QName(u'em'), (None, 1, 19))) + ('OUTSIDE', ('END', QName('em'), (None, 1, 19))) ('OUTSIDE', ('TEXT', u' text', (None, 1, 24))) - ('OUTSIDE', ('END', QName(u'body'), (None, 1, 29))) + ('OUTSIDE', ('END', QName('body'), (None, 1, 29))) Some test text :return: the stream augmented by transformation marks @@ -470,7 +470,7 @@ ... print(attrs) ... return attrs.get(name) >>> print(html | Transformer('body/em').attr('class', print_attr)) - Attrs([(QName(u'class'), u'before')]) + Attrs([(QName('class'), u'before')]) Attrs() Some TitleSome body text. @@ -660,13 +660,13 @@ >>> html = HTML('Some test text') >>> print(html | Transformer('em').trace()) - (None, ('START', (QName(u'body'), Attrs()), (None, 1, 0))) + (None, ('START', (QName('body'), Attrs()), (None, 1, 0))) (None, ('TEXT', u'Some ', (None, 1, 6))) - ('ENTER', ('START', (QName(u'em'), Attrs()), (None, 1, 11))) + ('ENTER', ('START', (QName('em'), Attrs()), (None, 1, 11))) ('INSIDE', ('TEXT', u'test', (None, 1, 15))) - ('EXIT', ('END', QName(u'em'), (None, 1, 19))) + ('EXIT', ('END', QName('em'), (None, 1, 19))) (None, ('TEXT', u' text', (None, 1, 24))) - (None, ('END', QName(u'body'), (None, 1, 29))) + (None, ('END', QName('body'), (None, 1, 29))) Some test text :param prefix: a string to prefix each event with in the output diff --git a/genshi/input.py b/genshi/input.py --- a/genshi/input.py +++ b/genshi/input.py @@ -88,8 +88,8 @@ >>> parser = XMLParser(StringIO('Foo')) >>> for kind, data, pos in parser: ... print('%s %s' % (kind, data)) - START (QName(u'root'), Attrs([(QName(u'id'), u'2')])) - START (QName(u'child'), Attrs()) + START (QName('root'), Attrs([(QName('id'), u'2')])) + START (QName('child'), Attrs()) TEXT Foo END child END root @@ -289,8 +289,8 @@ >>> parser = HTMLParser(StringIO('')) >>> for kind, data, pos in parser: ... print('%s %s' % (kind, data)) - START (QName(u'ul'), Attrs([(QName(u'compact'), u'compact')])) - START (QName(u'li'), Attrs()) + START (QName('ul'), Attrs([(QName('compact'), u'compact')])) + START (QName('li'), Attrs()) TEXT Foo END li END ul diff --git a/genshi/path.py b/genshi/path.py --- a/genshi/path.py +++ b/genshi/path.py @@ -619,7 +619,7 @@ >>> for event in xml: ... if test(event, namespaces, variables): ... print('%s %r' % (event[0], event[1])) - START (QName(u'child'), Attrs([(QName(u'id'), u'2')])) + START (QName('child'), Attrs([(QName('id'), u'2')])) :param ignore_context: if `True`, the path is interpreted like a pattern in XSLT, meaning for example that it will match diff --git a/genshi/tests/core.py b/genshi/tests/core.py --- a/genshi/tests/core.py +++ b/genshi/tests/core.py @@ -182,13 +182,25 @@ class NamespaceTestCase(unittest.TestCase): + def test_repr(self): + self.assertEqual("Namespace('http://www.example.org/namespace')", + repr(Namespace('http://www.example.org/namespace'))) + + def test_repr_eval(self): + ns = Namespace('http://www.example.org/namespace') + self.assertEqual(eval(repr(ns)), ns) + + def test_repr_eval_non_ascii(self): + ns = Namespace(u'http://www.example.org/nämespäcé') + self.assertEqual(eval(repr(ns)), ns) + def test_pickle(self): ns = Namespace('http://www.example.org/namespace') buf = StringIO() pickle.dump(ns, buf, 2) buf.seek(0) unpickled = pickle.load(buf) - self.assertEquals('', + self.assertEquals("Namespace('http://www.example.org/namespace')", repr(unpickled)) self.assertEquals('http://www.example.org/namespace', unpickled.uri) @@ -207,19 +219,23 @@ self.assertEquals('elem', unpickled.localname) def test_repr(self): - self.assertEqual("QName(u'elem')", repr(QName('elem'))) - self.assertEqual("QName(u'http://www.example.org/namespace}elem')", + self.assertEqual("QName('elem')", repr(QName('elem'))) + self.assertEqual("QName('http://www.example.org/namespace}elem')", repr(QName('http://www.example.org/namespace}elem'))) + def test_repr_eval(self): + qn = QName('elem') + self.assertEqual(eval(repr(qn)), qn) + + def test_repr_eval_non_ascii(self): + qn = QName(u'élem') + self.assertEqual(eval(repr(qn)), qn) + def test_leading_curly_brace(self): qname = QName('{http://www.example.org/namespace}elem') self.assertEquals('http://www.example.org/namespace', qname.namespace) self.assertEquals('elem', qname.localname) - def test_non_ascii(self): - qname = QName(u'http://www.example.org/namespace}gürü') - self.assertEqual(u'gürü', qname.localname) - def suite(): suite = unittest.TestSuite() diff --git a/genshi/util.py b/genshi/util.py --- a/genshi/util.py +++ b/genshi/util.py @@ -250,6 +250,15 @@ return _STRIPTAGS_RE.sub('', text) +def stringrepr(string): + slen = len(string) + ascii = string.encode('ascii', 'backslashreplace') + r = "'" + ascii.replace("'", "\\'") + "'" + if (unicode is not str) and (len(ascii) > len(string)): + return 'u' + r + return r + + # Compatibility fallback implementations for older Python versions try: