Update test requirements
- Now uses xmlschema~=1.0.14 - Update fn:in-scope-prefixes() - Remove module xpath_helpers.py
This commit is contained in:
parent
22d9f4258d
commit
de6955b36c
|
@ -257,7 +257,11 @@ def select(self, context=None):
|
|||
xsd_type = self.match_xsd_type(item, name)
|
||||
if xsd_type is not None:
|
||||
primitive_type = self.parser.schema.get_primitive_type(xsd_type)
|
||||
value = XSD_BUILTIN_TYPES[primitive_type.local_name].value
|
||||
try:
|
||||
value = XSD_BUILTIN_TYPES[primitive_type.local_name or 'anyType'].value
|
||||
except KeyError:
|
||||
value = XSD_BUILTIN_TYPES['anyType'].value
|
||||
|
||||
if isinstance(item, AttributeNode):
|
||||
yield TypedAttribute(item, value)
|
||||
else:
|
||||
|
@ -676,7 +680,6 @@ def select(self, context=None):
|
|||
yield result
|
||||
else:
|
||||
items = []
|
||||
context2 = context.copy()
|
||||
left_results = list(self[0].select(context))
|
||||
context.size = len(left_results)
|
||||
for context.position, context.item in enumerate(left_results):
|
||||
|
@ -749,7 +752,10 @@ def led(self, left):
|
|||
|
||||
@method('[')
|
||||
def select(self, context=None):
|
||||
if context is not None:
|
||||
if isinstance(context, XPathSchemaContext):
|
||||
for item in self[0].select(context):
|
||||
yield item
|
||||
elif context is not None:
|
||||
for position, item in enumerate(self[0].select(context), start=1):
|
||||
predicate = list(self[1].select(context.copy()))
|
||||
if len(predicate) == 1 and isinstance(predicate[0], NumericTypeProxy):
|
||||
|
@ -825,14 +831,20 @@ def select(self, context=None):
|
|||
else:
|
||||
return
|
||||
|
||||
for elem in context.iter_parent(axis=self.symbol):
|
||||
follows = False
|
||||
for child in context.iter_children_or_self(elem, child_axis=True):
|
||||
if follows:
|
||||
for parent in context.iter_parent(axis=self.symbol):
|
||||
if isinstance(context, XPathSchemaContext):
|
||||
for _ in context.iter_children_or_self(parent, child_axis=True):
|
||||
for result in self[0].select(context):
|
||||
yield result
|
||||
elif item is child:
|
||||
follows = True
|
||||
|
||||
else:
|
||||
follows = False
|
||||
for child in context.iter_children_or_self(parent, child_axis=True):
|
||||
if follows:
|
||||
for result in self[0].select(context):
|
||||
yield result
|
||||
elif item is child:
|
||||
follows = True
|
||||
|
||||
|
||||
@method(axis('following'))
|
||||
|
|
|
@ -19,6 +19,7 @@ import time
|
|||
import re
|
||||
import locale
|
||||
import unicodedata
|
||||
import xml.etree.ElementTree as ElementTree
|
||||
|
||||
from .compat import PY3, string_base_type, unicode_chr, urlparse, urljoin, urllib_quote, unicode_type
|
||||
from .datatypes import QNAME_PATTERN, DateTime10, Date10, Time, Timezone, Duration, DayTimeDuration
|
||||
|
@ -182,11 +183,21 @@ def select(self, context=None):
|
|||
elem = self.get_argument(context)
|
||||
if not is_element_node(elem):
|
||||
raise self.error('FORG0006', 'argument %r is not a node' % elem)
|
||||
for e in elem.iter():
|
||||
tag_ns = get_namespace(e.tag)
|
||||
for pfx, uri in self.parser.namespaces.items():
|
||||
if uri == tag_ns:
|
||||
yield pfx
|
||||
|
||||
if isinstance(context, XPathSchemaContext):
|
||||
# For schema context returns prefixes of static namespaces
|
||||
for prefix in self.parser.namespaces:
|
||||
yield prefix
|
||||
elif hasattr(elem, 'nsmap'):
|
||||
# For lxml returns Element's prefixes
|
||||
for prefix in elem.nsmap:
|
||||
yield prefix or ''
|
||||
else:
|
||||
# For ElementTree returns module registered prefixes
|
||||
prefixes = {x for x in self.parser.namespaces}
|
||||
prefixes.update(x for x in ElementTree._namespace_map.values())
|
||||
for prefix in prefixes:
|
||||
yield prefix
|
||||
|
||||
|
||||
@method(function('resolve-QName', nargs=2))
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c), 2018-2019, SISSA (International School for Advanced Studies).
|
||||
# All rights reserved.
|
||||
# This file is distributed under the terms of the MIT License.
|
||||
# See the file 'LICENSE' in the root directory of the present
|
||||
# distribution, or http://opensource.org/licenses/MIT.
|
||||
#
|
||||
# @author Davide Brunato <brunato@sissa.it>
|
||||
#
|
||||
from .exceptions import xpath_error
|
||||
from .xpath_nodes import is_element_node
|
||||
|
||||
|
||||
def boolean_value(obj, token=None):
|
||||
"""
|
||||
The effective boolean value, as computed by fn:boolean().
|
||||
Moved to token class but kept for backward compatibility.
|
||||
"""
|
||||
if isinstance(obj, list):
|
||||
if not obj:
|
||||
return False
|
||||
elif isinstance(obj[0], tuple) or is_element_node(obj[0]):
|
||||
return True
|
||||
elif len(obj) == 1:
|
||||
return bool(obj[0])
|
||||
else:
|
||||
raise xpath_error(
|
||||
code='FORG0006', token=token, prefix=getattr(token, 'error_prefix', 'err'),
|
||||
message="Effective boolean value is not defined for a sequence of two or "
|
||||
"more items not starting with an XPath node.",
|
||||
)
|
||||
elif isinstance(obj, tuple) or is_element_node(obj):
|
||||
raise xpath_error(
|
||||
code='FORG0006', token=token, prefix=getattr(token, 'error_prefix', 'err'),
|
||||
message="Effective boolean value is not defined for {}.".format(obj)
|
||||
)
|
||||
return bool(obj)
|
|
@ -3,6 +3,6 @@ setuptools
|
|||
tox
|
||||
coverage
|
||||
lxml
|
||||
xmlschema~=1.0.13
|
||||
xmlschema~=1.0.14
|
||||
Sphinx
|
||||
-e .
|
||||
|
|
|
@ -23,7 +23,6 @@ from elementpath.xpath_nodes import AttributeNode, NamespaceNode, is_etree_eleme
|
|||
node_base_uri, node_document_uri, node_children, node_is_id, node_is_idrefs, \
|
||||
node_nilled, node_kind, node_name
|
||||
from elementpath.xpath_token import ordinal
|
||||
from elementpath.xpath_helpers import boolean_value
|
||||
from elementpath.xpath1_parser import XPath1Parser
|
||||
|
||||
|
||||
|
@ -247,20 +246,6 @@ class XPathTokenHelpersTest(unittest.TestCase):
|
|||
self.assertEqual(ordinal(23), '23rd')
|
||||
self.assertEqual(ordinal(34), '34th')
|
||||
|
||||
def test_boolean_value_function(self):
|
||||
elem = ElementTree.Element('A')
|
||||
|
||||
self.assertFalse(boolean_value([]))
|
||||
self.assertTrue(boolean_value([elem]))
|
||||
self.assertFalse(boolean_value([0]))
|
||||
self.assertTrue(boolean_value([1]))
|
||||
with self.assertRaises(TypeError):
|
||||
boolean_value([1, 1])
|
||||
with self.assertRaises(TypeError):
|
||||
boolean_value(elem)
|
||||
self.assertFalse(boolean_value(0))
|
||||
self.assertTrue(boolean_value(1))
|
||||
|
||||
def test_get_argument_method(self):
|
||||
token = self.parser.symbol_table['true'](self.parser)
|
||||
|
||||
|
|
|
@ -217,6 +217,17 @@ class XPath1ParserTest(unittest.TestCase):
|
|||
with self.assertRaises(TypeError):
|
||||
token.boolean_value(elem)
|
||||
|
||||
self.assertFalse(token.boolean_value([]))
|
||||
self.assertTrue(token.boolean_value([elem]))
|
||||
self.assertFalse(token.boolean_value([0]))
|
||||
self.assertTrue(token.boolean_value([1]))
|
||||
with self.assertRaises(TypeError):
|
||||
token.boolean_value([1, 1])
|
||||
with self.assertRaises(TypeError):
|
||||
token.boolean_value(elem)
|
||||
self.assertFalse(token.boolean_value(0))
|
||||
self.assertTrue(token.boolean_value(1))
|
||||
|
||||
def test_data_value_function(self):
|
||||
token = self.parser.parse('true()')
|
||||
self.assertIsNone(token.data_value(None))
|
||||
|
|
|
@ -552,6 +552,12 @@ class XPath2ParserTest(test_xpath1_parser.XPath1ParserTest):
|
|||
)
|
||||
self.assertIsNone(parser.parse('fn:resolve-uri(())').evaluate(context))
|
||||
|
||||
def test_predicate(self):
|
||||
super(XPath2ParserTest, self).test_predicate()
|
||||
root = self.etree.XML('<A><B1><B2/><B2/></B1><C1><C2/><C2/></C1></A>')
|
||||
self.check_selector("/(A/*/*)[1]", root, [root[0][0]])
|
||||
self.check_selector("/A/*/*[1]", root, [root[0][0], root[1][0]])
|
||||
|
||||
def test_sequence_general_functions(self):
|
||||
# Test cases from https://www.w3.org/TR/xquery-operators/#general-seq-funcs
|
||||
self.check_value('fn:empty(("hello", "world"))', False)
|
||||
|
@ -647,7 +653,16 @@ class XPath2ParserTest(test_xpath1_parser.XPath1ParserTest):
|
|||
self.check_value("fn:namespace-uri-for-prefix('eg', .)", 'http://www.example.com/ns/', context=context)
|
||||
self.check_selector("fn:namespace-uri-for-prefix('p3', .)", root, NameError, namespaces={'p3': ''})
|
||||
|
||||
self.check_selector("fn:in-scope-prefixes(.)", root, ['p2', 'p0'], namespaces={'p0': 'ns0', 'p2': 'ns2'})
|
||||
def test_in_scope_prefixes_function(self):
|
||||
root = self.etree.XML('<p1:A xmlns:p1="ns1" xmlns:p0="ns0">'
|
||||
' <B1><p2:C xmlns:p2="ns2"/></B1><B2/>'
|
||||
' <p0:B3><eg:C1 xmlns:eg="http://www.example.com/ns/"/><C2/></p0:B3>'
|
||||
'</p1:A>')
|
||||
if self.etree is lxml_etree:
|
||||
prefixes = {'p0', 'p1'}
|
||||
else:
|
||||
prefixes = {'p0', 'p2', 'fn', 'xlink', 'err'} | {x for x in self.etree._namespace_map.values()}
|
||||
self.check_selector("fn:in-scope-prefixes(.)", root, prefixes, namespaces={'p0': 'ns0', 'p2': 'ns2'})
|
||||
|
||||
def test_string_constructors(self):
|
||||
self.check_value("xs:string(5.0)", '5.0')
|
||||
|
|
4
tox.ini
4
tox.ini
|
@ -11,7 +11,7 @@ toxworkdir = {homedir}/.tox/elementpath
|
|||
[testenv]
|
||||
deps =
|
||||
lxml
|
||||
xmlschema~=1.0.13
|
||||
xmlschema~=1.0.14
|
||||
docs: Sphinx
|
||||
flake8: flake8
|
||||
coverage: coverage
|
||||
|
@ -24,7 +24,7 @@ commands = python tests/test_elementpath.py
|
|||
[testenv:py38]
|
||||
deps =
|
||||
lxml==4.3.5
|
||||
xmlschema~=1.0.13
|
||||
xmlschema~=1.0.14
|
||||
commands = python -m unittest
|
||||
|
||||
[testenv:docs]
|
||||
|
|
Loading…
Reference in New Issue