summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lxml/builder.py12
-rw-r--r--src/lxml/tests/test_builder.py39
2 files changed, 49 insertions, 2 deletions
diff --git a/src/lxml/builder.py b/src/lxml/builder.py
index c5c25b74..b7fcf406 100644
--- a/src/lxml/builder.py
+++ b/src/lxml/builder.py
@@ -212,12 +212,20 @@ class ElementMaker(object):
for item in children:
if callable(item):
item = item()
- t = get(type(item))
+ for basetype in type(item).__mro__:
+ # __mro__ starts with the type itself, and then
+ # searches all supertypes. If typemap contains
+ # object, this will never fall back to appending an
+ # element.
+ t = get(basetype)
+ if t is not None:
+ break
if t is None:
if ET.iselement(item):
elem.append(item)
continue
- raise TypeError("bad argument type: %r" % item)
+ raise TypeError("bad argument type: %s(%r)" %
+ (type(item).__name__, item))
else:
v = t(elem, item)
if v:
diff --git a/src/lxml/tests/test_builder.py b/src/lxml/tests/test_builder.py
new file mode 100644
index 00000000..b3a31488
--- /dev/null
+++ b/src/lxml/tests/test_builder.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+import unittest
+
+"""
+Tests that ElementMaker works properly.
+"""
+
+import sys, os.path
+from lxml import etree
+from lxml.builder import E
+
+try:
+ import cStringIO
+ StringIO = cStringIO.StringIO
+except ImportError:
+ from io import StringIO
+
+this_dir = os.path.dirname(__file__)
+if this_dir not in sys.path:
+ sys.path.insert(0, this_dir) # needed for Py3
+
+from common_imports import HelperTestCase
+
+class BuilderTestCase(HelperTestCase):
+ etree = etree
+
+ def test_build_from_xpath_result(self):
+ elem = etree.parse(StringIO('<root><node>text</node></root>'))
+ wrapped = E.b(elem.xpath('string(node)'))
+ self.assertEquals(b'<b>text</b>', etree.tostring(wrapped))
+
+
+def test_suite():
+ suite = unittest.TestSuite()
+ suite.addTests([unittest.makeSuite(BuilderTestCase)])
+ return suite
+
+if __name__ == '__main__':
+ print('to test use test.py %s' % __file__)