Package lxml :: Package tests :: Module test_xpathevaluator
[hide private]
[frames] | no frames]

Source Code for Module lxml.tests.test_xpathevaluator

  1  # -*- coding: utf-8 -*- 
  2   
  3  """ 
  4  Test cases related to XPath evaluation and the XPath class 
  5  """ 
  6   
  7  import unittest, sys, os.path 
  8   
  9  this_dir = os.path.dirname(__file__) 
 10  if this_dir not in sys.path: 
 11      sys.path.insert(0, this_dir) # needed for Py3 
 12   
 13  from common_imports import etree, HelperTestCase, _bytes, BytesIO 
 14  from common_imports import doctest, make_doctest 
 15   
16 -class ETreeXPathTestCase(HelperTestCase):
17 """XPath tests etree""" 18
19 - def test_xpath_boolean(self):
20 tree = self.parse('<a><b></b><b></b></a>') 21 self.assert_(tree.xpath('boolean(/a/b)')) 22 self.assert_(not tree.xpath('boolean(/a/c)'))
23
24 - def test_xpath_number(self):
25 tree = self.parse('<a>1</a>') 26 self.assertEquals(1., 27 tree.xpath('number(/a)')) 28 tree = self.parse('<a>A</a>') 29 actual = str(tree.xpath('number(/a)')) 30 expected = ['nan', '1.#qnan', 'nanq'] 31 if not actual.lower() in expected: 32 self.fail('Expected a NAN value, got %s' % actual)
33
34 - def test_xpath_string(self):
35 tree = self.parse('<a>Foo</a>') 36 self.assertEquals('Foo', 37 tree.xpath('string(/a/text())'))
38
39 - def test_xpath_document_root(self):
40 tree = self.parse('<a><b/></a>') 41 self.assertEquals([], 42 tree.xpath('/'))
43
44 - def test_xpath_namespace(self):
45 tree = self.parse('<a xmlns="test" xmlns:p="myURI"/>') 46 self.assert_((None, "test") in tree.xpath('namespace::*')) 47 self.assert_(('p', 'myURI') in tree.xpath('namespace::*'))
48
50 tree = self.parse('<a/>') 51 self.assertEquals([('xml', 'http://www.w3.org/XML/1998/namespace')], 52 tree.xpath('namespace::*'))
53
54 - def test_xpath_list_elements(self):
55 tree = self.parse('<a><b>Foo</b><b>Bar</b></a>') 56 root = tree.getroot() 57 self.assertEquals([root[0], root[1]], 58 tree.xpath('/a/b'))
59
60 - def test_xpath_list_nothing(self):
61 tree = self.parse('<a><b/></a>') 62 self.assertEquals([], 63 tree.xpath('/a/c')) 64 # this seems to pass a different code path, also should return nothing 65 self.assertEquals([], 66 tree.xpath('/a/c/text()'))
67
68 - def test_xpath_list_text(self):
69 tree = self.parse('<a><b>Foo</b><b>Bar</b></a>') 70 root = tree.getroot() 71 self.assertEquals(['Foo', 'Bar'], 72 tree.xpath('/a/b/text()'))
73
75 tree = self.parse('<a><b>FooBar</b><b>BarFoo</b></a>') 76 root = tree.getroot() 77 self.assertEquals(['FooBar', 'BarFoo'], 78 tree.xpath('/a/b/text()')) 79 self.assertEquals([root[0], root[1]], 80 [r.getparent() for r in tree.xpath('/a/b/text()')])
81
83 tree = self.parse('<a><b>FooBar</b><b>BarFoo</b></a>') 84 root = tree.getroot() 85 self.assertEquals(['FooBar', 'BarFoo'], 86 tree.xpath('/a/b/text()', smart_strings=True)) 87 self.assertEquals([root[0], root[1]], 88 [r.getparent() for r in 89 tree.xpath('/a/b/text()', smart_strings=True)]) 90 91 self.assertEquals(['FooBar', 'BarFoo'], 92 tree.xpath('/a/b/text()', smart_strings=False)) 93 self.assertEquals([False, False], 94 [hasattr(r, 'getparent') for r in 95 tree.xpath('/a/b/text()', smart_strings=False)])
96
98 xml = _bytes('<a><b>FooBar\\u0680\\u3120</b><b>BarFoo\\u0680\\u3120</b></a>').decode("unicode_escape") 99 tree = self.parse(xml.encode('utf-8')) 100 root = tree.getroot() 101 self.assertEquals([_bytes('FooBar\\u0680\\u3120').decode("unicode_escape"), 102 _bytes('BarFoo\\u0680\\u3120').decode("unicode_escape")], 103 tree.xpath('/a/b/text()')) 104 self.assertEquals([root[0], root[1]], 105 [r.getparent() for r in tree.xpath('/a/b/text()')])
106
108 tree = self.parse('<a b="B" c="C"/>') 109 self.assertEquals(['B'], 110 tree.xpath('/a/@b'))
111
113 tree = self.parse('<a b="BaSdFgHjKl" c="CqWeRtZuI"/>') 114 results = tree.xpath('/a/@c') 115 self.assertEquals(1, len(results)) 116 self.assertEquals('CqWeRtZuI', results[0]) 117 self.assertEquals(tree.getroot().tag, results[0].getparent().tag)
118
120 tree = self.parse('<a b="BaSdFgHjKl" c="CqWeRtZuI"/>') 121 122 results = tree.xpath('/a/@c', smart_strings=True) 123 self.assertEquals(1, len(results)) 124 self.assertEquals('CqWeRtZuI', results[0]) 125 self.assertEquals(tree.getroot().tag, results[0].getparent().tag) 126 127 results = tree.xpath('/a/@c', smart_strings=False) 128 self.assertEquals(1, len(results)) 129 self.assertEquals('CqWeRtZuI', results[0]) 130 self.assertEquals(False, hasattr(results[0], 'getparent'))
131
132 - def test_xpath_list_comment(self):
133 tree = self.parse('<a><!-- Foo --></a>') 134 self.assertEquals(['<!-- Foo -->'], 135 list(map(repr, tree.xpath('/a/node()'))))
136
137 - def test_rel_xpath_boolean(self):
138 root = etree.XML('<a><b><c/></b></a>') 139 el = root[0] 140 self.assert_(el.xpath('boolean(c)')) 141 self.assert_(not el.xpath('boolean(d)'))
142
144 tree = self.parse('<a><c><b>Foo</b><b>Bar</b></c><c><b>Hey</b></c></a>') 145 root = tree.getroot() 146 c = root[0] 147 self.assertEquals([c[0], c[1]], 148 c.xpath('b')) 149 self.assertEquals([c[0], c[1], root[1][0]], 150 c.xpath('//b'))
151
152 - def test_xpath_ns(self):
153 tree = self.parse('<a xmlns="uri:a"><b></b></a>') 154 root = tree.getroot() 155 self.assertEquals( 156 [root[0]], 157 tree.xpath('//foo:b', namespaces={'foo': 'uri:a'})) 158 self.assertEquals( 159 [], 160 tree.xpath('//foo:b', namespaces={'foo': 'uri:c'})) 161 self.assertEquals( 162 [root[0]], 163 root.xpath('//baz:b', namespaces={'baz': 'uri:a'}))
164
165 - def test_xpath_ns_none(self):
166 tree = self.parse('<a xmlns="uri:a"><b></b></a>') 167 root = tree.getroot() 168 self.assertRaises( 169 TypeError, 170 root.xpath, '//b', namespaces={None: 'uri:a'})
171
172 - def test_xpath_ns_empty(self):
173 tree = self.parse('<a xmlns="uri:a"><b></b></a>') 174 root = tree.getroot() 175 self.assertRaises( 176 TypeError, 177 root.xpath, '//b', namespaces={'': 'uri:a'})
178
179 - def test_xpath_error(self):
180 tree = self.parse('<a/>') 181 self.assertRaises(etree.XPathEvalError, tree.xpath, '\\fad')
182
183 - def test_xpath_class_error(self):
184 self.assertRaises(SyntaxError, etree.XPath, '\\fad') 185 self.assertRaises(etree.XPathSyntaxError, etree.XPath, '\\fad')
186
187 - def test_xpath_prefix_error(self):
188 tree = self.parse('<a/>') 189 self.assertRaises(etree.XPathEvalError, tree.xpath, '/fa:d')
190
192 tree = self.parse('<a/>') 193 xpath = etree.XPath("/fa:d") 194 self.assertRaises(etree.XPathEvalError, xpath, tree)
195
196 - def test_elementtree_getpath(self):
197 a = etree.Element("a") 198 b = etree.SubElement(a, "b") 199 c = etree.SubElement(a, "c") 200 d1 = etree.SubElement(c, "d") 201 d2 = etree.SubElement(c, "d") 202 203 tree = etree.ElementTree(a) 204 self.assertEqual('/a/c/d', 205 tree.getpath(d2)[:6]) 206 self.assertEqual([d2], 207 tree.xpath(tree.getpath(d2)))
208
210 a = etree.Element("a") 211 b = etree.SubElement(a, "b") 212 c = etree.SubElement(a, "c") 213 d1 = etree.SubElement(c, "d") 214 d2 = etree.SubElement(c, "d") 215 216 tree = etree.ElementTree(c) 217 self.assertEqual('/c/d', 218 tree.getpath(d2)[:4]) 219 self.assertEqual([d2], 220 tree.xpath(tree.getpath(d2)))
221
222 - def test_xpath_evaluator(self):
223 tree = self.parse('<a><b><c></c></b></a>') 224 e = etree.XPathEvaluator(tree) 225 root = tree.getroot() 226 self.assertEquals( 227 [root], 228 e('//a'))
229
231 tree = self.parse('<a><b><c></c></b></a>') 232 child_tree = etree.ElementTree(tree.getroot()[0]) 233 e = etree.XPathEvaluator(child_tree) 234 self.assertEquals( 235 [], 236 e('a')) 237 root = child_tree.getroot() 238 self.assertEquals( 239 [root[0]], 240 e('c'))
241
243 tree = self.parse('<a><b><c></c></b></a>') 244 child_tree = etree.ElementTree(tree.getroot()[0]) 245 e = etree.XPathEvaluator(child_tree) 246 self.assertEquals( 247 [], 248 e('/a')) 249 root = child_tree.getroot() 250 self.assertEquals( 251 [root], 252 e('/b')) 253 self.assertEquals( 254 [], 255 e('/c'))
256
258 tree = self.parse('<a><b><c></c></b></a>') 259 root = tree.getroot() 260 e = etree.XPathEvaluator(root[0]) 261 self.assertEquals( 262 [root[0][0]], 263 e('c'))
264
265 - def test_xpath_extensions(self):
266 def foo(evaluator, a): 267 return 'hello %s' % a
268 extension = {(None, 'foo'): foo} 269 tree = self.parse('<a><b></b></a>') 270 e = etree.XPathEvaluator(tree, extensions=[extension]) 271 self.assertEquals( 272 "hello you", e("foo('you')"))
273
274 - def test_xpath_extensions_wrong_args(self):
275 def foo(evaluator, a, b): 276 return "hello %s and %s" % (a, b)
277 extension = {(None, 'foo'): foo} 278 tree = self.parse('<a><b></b></a>') 279 e = etree.XPathEvaluator(tree, extensions=[extension]) 280 self.assertRaises(TypeError, e, "foo('you')") 281
282 - def test_xpath_extensions_error(self):
283 def foo(evaluator, a): 284 return 1/0
285 extension = {(None, 'foo'): foo} 286 tree = self.parse('<a/>') 287 e = etree.XPathEvaluator(tree, extensions=[extension]) 288 self.assertRaises(ZeroDivisionError, e, "foo('test')") 289
290 - def test_xpath_extensions_nodes(self):
291 def f(evaluator, arg): 292 r = etree.Element('results') 293 b = etree.SubElement(r, 'result') 294 b.text = 'Hoi' 295 b = etree.SubElement(r, 'result') 296 b.text = 'Dag' 297 return r
298 299 x = self.parse('<a/>') 300 e = etree.XPathEvaluator(x, extensions=[{(None, 'foo'): f}]) 301 r = e("foo('World')/result") 302 self.assertEquals(2, len(r)) 303 self.assertEquals('Hoi', r[0].text) 304 self.assertEquals('Dag', r[1].text) 305
306 - def test_xpath_extensions_nodes_append(self):
307 def f(evaluator, nodes): 308 r = etree.SubElement(nodes[0], 'results') 309 b = etree.SubElement(r, 'result') 310 b.text = 'Hoi' 311 b = etree.SubElement(r, 'result') 312 b.text = 'Dag' 313 return r
314 315 x = self.parse('<a/>') 316 e = etree.XPathEvaluator(x, extensions=[{(None, 'foo'): f}]) 317 r = e("foo(/*)/result") 318 self.assertEquals(2, len(r)) 319 self.assertEquals('Hoi', r[0].text) 320 self.assertEquals('Dag', r[1].text) 321
322 - def test_xpath_extensions_nodes_append2(self):
323 def f(evaluator, nodes): 324 r = etree.Element('results') 325 b = etree.SubElement(r, 'result') 326 b.text = 'Hoi' 327 b = etree.SubElement(r, 'result') 328 b.text = 'Dag' 329 r.append(nodes[0]) 330 return r
331 332 x = self.parse('<result>Honk</result>') 333 e = etree.XPathEvaluator(x, extensions=[{(None, 'foo'): f}]) 334 r = e("foo(/*)/result") 335 self.assertEquals(3, len(r)) 336 self.assertEquals('Hoi', r[0].text) 337 self.assertEquals('Dag', r[1].text) 338 self.assertEquals('Honk', r[2].text) 339
340 - def test_xpath_context_node(self):
341 tree = self.parse('<root><a/><b><c/></b></root>') 342 343 check_call = [] 344 def check_context(ctxt, nodes): 345 self.assertEquals(len(nodes), 1) 346 check_call.append(nodes[0].tag) 347 self.assertEquals(ctxt.context_node, nodes[0]) 348 return True
349 350 find = etree.XPath("//*[p:foo(.)]", 351 namespaces={'p' : 'ns'}, 352 extensions=[{('ns', 'foo') : check_context}]) 353 find(tree) 354 355 check_call.sort() 356 self.assertEquals(check_call, ["a", "b", "c", "root"]) 357
358 - def test_xpath_eval_context_propagation(self):
359 tree = self.parse('<root><a/><b><c/></b></root>') 360 361 check_call = {} 362 def check_context(ctxt, nodes): 363 self.assertEquals(len(nodes), 1) 364 tag = nodes[0].tag 365 # empty during the "b" call, a "b" during the "c" call 366 check_call[tag] = ctxt.eval_context.get("b") 367 ctxt.eval_context[tag] = tag 368 return True
369 370 find = etree.XPath("//b[p:foo(.)]/c[p:foo(.)]", 371 namespaces={'p' : 'ns'}, 372 extensions=[{('ns', 'foo') : check_context}]) 373 result = find(tree) 374 375 self.assertEquals(result, [tree.getroot()[1][0]]) 376 self.assertEquals(check_call, {'b':None, 'c':'b'}) 377
378 - def test_xpath_eval_context_clear(self):
379 tree = self.parse('<root><a/><b><c/></b></root>') 380 381 check_call = {} 382 def check_context(ctxt): 383 check_call["done"] = True 384 # context must be empty for each new evaluation 385 self.assertEquals(len(ctxt.eval_context), 0) 386 ctxt.eval_context["test"] = True 387 return True
388 389 find = etree.XPath("//b[p:foo()]", 390 namespaces={'p' : 'ns'}, 391 extensions=[{('ns', 'foo') : check_context}]) 392 result = find(tree) 393 394 self.assertEquals(result, [tree.getroot()[1]]) 395 self.assertEquals(check_call["done"], True) 396 397 check_call.clear() 398 find = etree.XPath("//b[p:foo()]", 399 namespaces={'p' : 'ns'}, 400 extensions=[{('ns', 'foo') : check_context}]) 401 result = find(tree) 402 403 self.assertEquals(result, [tree.getroot()[1]]) 404 self.assertEquals(check_call["done"], True) 405
406 - def test_xpath_variables(self):
407 x = self.parse('<a attr="true"/>') 408 e = etree.XPathEvaluator(x) 409 410 expr = "/a[@attr=$aval]" 411 r = e(expr, aval=1) 412 self.assertEquals(0, len(r)) 413 414 r = e(expr, aval="true") 415 self.assertEquals(1, len(r)) 416 self.assertEquals("true", r[0].get('attr')) 417 418 r = e(expr, aval=True) 419 self.assertEquals(1, len(r)) 420 self.assertEquals("true", r[0].get('attr'))
421
422 - def test_xpath_variables_nodeset(self):
423 x = self.parse('<a attr="true"/>') 424 e = etree.XPathEvaluator(x) 425 426 element = etree.Element("test-el") 427 etree.SubElement(element, "test-sub") 428 expr = "$value" 429 r = e(expr, value=element) 430 self.assertEquals(1, len(r)) 431 self.assertEquals(element.tag, r[0].tag) 432 self.assertEquals(element[0].tag, r[0][0].tag)
433
434 - def test_xpath_extensions_mix(self):
435 x = self.parse('<a attr="true"><test/></a>') 436 437 class LocalException(Exception): 438 pass
439 440 def foo(evaluator, a, varval): 441 etree.Element("DUMMY") 442 if varval == 0: 443 raise LocalException 444 elif varval == 1: 445 return () 446 elif varval == 2: 447 return None 448 elif varval == 3: 449 return a[0][0] 450 a = a[0] 451 if a.get("attr") == str(varval): 452 return a 453 else: 454 return etree.Element("NODE") 455 456 extension = {(None, 'foo'): foo} 457 e = etree.XPathEvaluator(x, extensions=[extension]) 458 del x 459 460 self.assertRaises(LocalException, e, "foo(., 0)") 461 self.assertRaises(LocalException, e, "foo(., $value)", value=0) 462 463 r = e("foo(., $value)", value=1) 464 self.assertEqual(len(r), 0) 465 466 r = e("foo(., 1)") 467 self.assertEqual(len(r), 0) 468 469 r = e("foo(., $value)", value=2) 470 self.assertEqual(len(r), 0) 471 472 r = e("foo(., $value)", value=3) 473 self.assertEqual(len(r), 1) 474 self.assertEqual(r[0].tag, "test") 475 476 r = e("foo(., $value)", value="false") 477 self.assertEqual(len(r), 1) 478 self.assertEqual(r[0].tag, "NODE") 479 480 r = e("foo(., 'false')") 481 self.assertEqual(len(r), 1) 482 self.assertEqual(r[0].tag, "NODE") 483 484 r = e("foo(., 'true')") 485 self.assertEqual(len(r), 1) 486 self.assertEqual(r[0].tag, "a") 487 self.assertEqual(r[0][0].tag, "test") 488 489 r = e("foo(., $value)", value="true") 490 self.assertEqual(len(r), 1) 491 self.assertEqual(r[0].tag, "a") 492 493 self.assertRaises(LocalException, e, "foo(., 0)") 494 self.assertRaises(LocalException, e, "foo(., $value)", value=0) 495 496
497 -class ETreeXPathClassTestCase(HelperTestCase):
498 "Tests for the XPath class"
499 - def test_xpath_compile_doc(self):
500 x = self.parse('<a attr="true"/>') 501 502 expr = etree.XPath("/a[@attr != 'true']") 503 r = expr(x) 504 self.assertEquals(0, len(r)) 505 506 expr = etree.XPath("/a[@attr = 'true']") 507 r = expr(x) 508 self.assertEquals(1, len(r)) 509 510 expr = etree.XPath( expr.path ) 511 r = expr(x) 512 self.assertEquals(1, len(r))
513
515 x = self.parse('<a><b/><c/></a>') 516 root = x.getroot() 517 518 expr = etree.XPath("./b") 519 r = expr(root) 520 self.assertEquals(1, len(r)) 521 self.assertEquals('b', r[0].tag) 522 523 expr = etree.XPath("./*") 524 r = expr(root) 525 self.assertEquals(2, len(r))
526
527 - def test_xpath_compile_vars(self):
528 x = self.parse('<a attr="true"/>') 529 530 expr = etree.XPath("/a[@attr=$aval]") 531 r = expr(x, aval=False) 532 self.assertEquals(0, len(r)) 533 534 r = expr(x, aval=True) 535 self.assertEquals(1, len(r))
536
537 - def test_xpath_compile_error(self):
538 self.assertRaises(SyntaxError, etree.XPath, '\\fad')
539
541 self.assertRaises(ValueError, etree.XPath('*'), etree.ElementTree())
542
543 -class ETreeETXPathClassTestCase(HelperTestCase):
544 "Tests for the ETXPath class"
545 - def test_xpath_compile_ns(self):
546 x = self.parse('<a><b xmlns="nsa"/><b xmlns="nsb"/></a>') 547 548 expr = etree.ETXPath("/a/{nsa}b") 549 r = expr(x) 550 self.assertEquals(1, len(r)) 551 self.assertEquals('{nsa}b', r[0].tag) 552 553 expr = etree.ETXPath("/a/{nsb}b") 554 r = expr(x) 555 self.assertEquals(1, len(r)) 556 self.assertEquals('{nsb}b', r[0].tag)
557
559 x = self.parse(_bytes('<a><b xmlns="nsa\\uf8d2"/><b xmlns="nsb\\uf8d1"/></a>' 560 ).decode("unicode_escape")) 561 562 expr = etree.ETXPath(_bytes("/a/{nsa\\uf8d2}b").decode("unicode_escape")) 563 r = expr(x) 564 self.assertEquals(1, len(r)) 565 self.assertEquals(_bytes('{nsa\\uf8d2}b').decode("unicode_escape"), r[0].tag) 566 567 expr = etree.ETXPath(_bytes("/a/{nsb\\uf8d1}b").decode("unicode_escape")) 568 r = expr(x) 569 self.assertEquals(1, len(r)) 570 self.assertEquals(_bytes('{nsb\\uf8d1}b').decode("unicode_escape"), r[0].tag)
571 572 SAMPLE_XML = etree.parse(BytesIO(""" 573 <body> 574 <tag>text</tag> 575 <section> 576 <tag>subtext</tag> 577 </section> 578 <tag /> 579 <tag /> 580 </body> 581 """)) 582
583 -def tag(elem):
584 return elem.tag
585
586 -def stringTest(ctxt, s1):
587 return "Hello "+s1
588
589 -def floatTest(ctxt, f1):
590 return f1+4
591
592 -def booleanTest(ctxt, b1):
593 return not b1
594
595 -def setTest(ctxt, st1):
596 return st1[0]
597
598 -def setTest2(ctxt, st1):
599 return st1[0:2]
600
601 -def argsTest1(ctxt, s, f, b, st):
602 return ", ".join(map(str, (s, f, b, list(map(tag, st)))))
603
604 -def argsTest2(ctxt, st1, st2):
605 st1.extend(st2) 606 return st1
607
608 -def resultTypesTest(ctxt):
609 return ["x","y"]
610
611 -def resultTypesTest2(ctxt):
612 return resultTypesTest
613 614 uri = "http://www.example.com/" 615 616 extension = {(None, 'stringTest'): stringTest, 617 (None, 'floatTest'): floatTest, 618 (None, 'booleanTest'): booleanTest, 619 (None, 'setTest'): setTest, 620 (None, 'setTest2'): setTest2, 621 (None, 'argsTest1'): argsTest1, 622 (None, 'argsTest2'): argsTest2, 623 (None, 'resultTypesTest'): resultTypesTest, 624 (None, 'resultTypesTest2'): resultTypesTest2,} 625
626 -def xpath():
627 """ 628 Test xpath extension functions. 629 630 >>> root = SAMPLE_XML 631 >>> e = etree.XPathEvaluator(root, extensions=[extension]) 632 >>> e("stringTest('you')") 633 'Hello you' 634 >>> e(_bytes("stringTest('\\\\xe9lan')").decode("unicode_escape")) 635 u'Hello \\xe9lan' 636 >>> e("stringTest('you','there')") 637 Traceback (most recent call last): 638 ... 639 TypeError: stringTest() takes exactly 2 arguments (3 given) 640 >>> e("floatTest(2)") 641 6.0 642 >>> e("booleanTest(true())") 643 False 644 >>> list(map(tag, e("setTest(/body/tag)"))) 645 ['tag'] 646 >>> list(map(tag, e("setTest2(/body/*)"))) 647 ['tag', 'section'] 648 >>> e("argsTest1('a',1.5,true(),/body/tag)") 649 "a, 1.5, True, ['tag', 'tag', 'tag']" 650 >>> list(map(tag, e("argsTest2(/body/tag, /body/section)"))) 651 ['tag', 'section', 'tag', 'tag'] 652 >>> e("resultTypesTest()") 653 Traceback (most recent call last): 654 ... 655 XPathResultError: This is not a node: 'x' 656 >>> try: 657 ... e("resultTypesTest2()") 658 ... except etree.XPathResultError: 659 ... print("Got error") 660 Got error 661 """
662 663 if sys.version_info[0] >= 3: 664 xpath.__doc__ = xpath.__doc__.replace(" u'", " '") 665 xpath.__doc__ = xpath.__doc__.replace(" XPathResultError", 666 " lxml.etree.XPathResultError") 667 xpath.__doc__ = xpath.__doc__.replace(" exactly 2 arguments", 668 " exactly 2 positional arguments") 669
670 -def test_suite():
671 suite = unittest.TestSuite() 672 suite.addTests([unittest.makeSuite(ETreeXPathTestCase)]) 673 suite.addTests([unittest.makeSuite(ETreeXPathClassTestCase)]) 674 suite.addTests([unittest.makeSuite(ETreeETXPathClassTestCase)]) 675 suite.addTests([doctest.DocTestSuite()]) 676 suite.addTests( 677 [make_doctest('../../../doc/xpathxslt.txt')]) 678 return suite
679 680 if __name__ == '__main__': 681 print('to test use test.py %s' % __file__) 682