diff --git a/.coveragerc b/.coveragerc
index 4add1e8d..6463262c 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -1,7 +1,9 @@
[run]
branch = True
source = xmlschema/
-omit = xmlschema/testing/*
+omit =
+ xmlschema/testing/*
+ xmlschema/aliases.py
[report]
exclude_lines =
diff --git a/tests/test_helpers.py b/tests/test_helpers.py
index de7840ae..3c372ba3 100644
--- a/tests/test_helpers.py
+++ b/tests/test_helpers.py
@@ -235,7 +235,7 @@ def test_get_prefixed_qname(self):
self.assertEqual(get_prefixed_qname('', namespaces), '')
self.assertEqual(get_prefixed_qname(None, namespaces), None)
- # self.assertEqual(get_prefixed_qname(0, namespaces), 0)
+ self.assertEqual(get_prefixed_qname('{uri}element', namespaces), '{uri}element')
self.assertEqual(get_prefixed_qname(XSI_TYPE, {}), XSI_TYPE)
self.assertEqual(get_prefixed_qname(None, {}), None)
diff --git a/tests/test_namespaces.py b/tests/test_namespaces.py
index f17c7239..e37d77ef 100644
--- a/tests/test_namespaces.py
+++ b/tests/test_namespaces.py
@@ -205,6 +205,17 @@ def test_repr(self):
ns_view = NamespaceView(qnames, 'tns0')
self.assertEqual(repr(ns_view), "NamespaceView({'name0': 0})")
+ def test_contains(self):
+ qnames = {'{tns0}name0': 0, '{tns1}name1': 1, 'name2': 2}
+ ns_view = NamespaceView(qnames, 'tns1')
+
+ self.assertIn('name1', ns_view)
+ self.assertNotIn('{tns1}name1', ns_view)
+ self.assertNotIn('{tns0}name0', ns_view)
+ self.assertNotIn('name0', ns_view)
+ self.assertNotIn('name2', ns_view)
+ self.assertNotIn(1, ns_view)
+
def test_as_dict(self):
qnames = {'{tns0}name0': 0, '{tns1}name1': 1, '{tns1}name2': 2, 'name3': 3}
ns_view = NamespaceView(qnames, 'tns1')
diff --git a/tests/test_resources.py b/tests/test_resources.py
index d3579bb4..6451f6c8 100644
--- a/tests/test_resources.py
+++ b/tests/test_resources.py
@@ -321,20 +321,39 @@ def test_is_url_function(self):
def test_is_local_url_function(self):
self.assertTrue(is_local_url(self.col_xsd_file))
+ self.assertTrue(is_local_url(Path(self.col_xsd_file)))
+
self.assertTrue(is_local_url('/home/user/'))
+ self.assertFalse(is_local_url(''))
self.assertTrue(is_local_url('/home/user/schema.xsd'))
self.assertTrue(is_local_url(' /home/user/schema.xsd '))
self.assertTrue(is_local_url('C:\\Users\\foo\\schema.xsd'))
self.assertTrue(is_local_url(' file:///home/user/schema.xsd'))
self.assertFalse(is_local_url('http://example.com/schema.xsd'))
+ self.assertTrue(is_local_url(b'/home/user/'))
+ self.assertFalse(is_local_url(b''))
+ self.assertTrue(is_local_url(b'/home/user/schema.xsd'))
+ self.assertTrue(is_local_url(b' /home/user/schema.xsd '))
+ self.assertTrue(is_local_url(b'C:\\Users\\foo\\schema.xsd'))
+ self.assertTrue(is_local_url(b' file:///home/user/schema.xsd'))
+ self.assertFalse(is_local_url(b'http://example.com/schema.xsd'))
+
def test_is_remote_url_function(self):
self.assertFalse(is_remote_url(self.col_xsd_file))
+
self.assertFalse(is_remote_url('/home/user/'))
+ self.assertFalse(is_remote_url(''))
self.assertFalse(is_remote_url('/home/user/schema.xsd'))
self.assertFalse(is_remote_url(' file:///home/user/schema.xsd'))
self.assertTrue(is_remote_url(' http://example.com/schema.xsd'))
+ self.assertFalse(is_remote_url(b'/home/user/'))
+ self.assertFalse(is_remote_url(b''))
+ self.assertFalse(is_remote_url(b'/home/user/schema.xsd'))
+ self.assertFalse(is_remote_url(b' file:///home/user/schema.xsd'))
+ self.assertTrue(is_remote_url(b' http://example.com/schema.xsd'))
+
def test_url_path_is_file_function(self):
self.assertTrue(url_path_is_file(self.col_xml_file))
self.assertTrue(url_path_is_file(normalize_url(self.col_xml_file)))
@@ -449,6 +468,15 @@ def test_xml_resource_from_url(self):
with self.assertRaises(XMLResourceError):
resource.load()
+ def test_xml_resource_from_url_in_bytes(self):
+ resource = XMLResource(self.vh_xml_file.encode('utf-8'), lazy=False)
+ self.assertEqual(resource.source, self.vh_xml_file.encode('utf-8'))
+ self.assertEqual(resource.root.tag, '{http://example.com/vehicles}vehicles')
+ self.check_url(resource.url, self.vh_xml_file)
+ self.assertIsNone(resource.text)
+ resource.load()
+ self.assertTrue(resource.text.startswith('')
+ with self.assertRaises(ValueError):
+ XMLResource(self.vh_xml_file, base_url=b'')
+
def test_xml_resource_is_local(self):
resource = XMLResource(self.vh_xml_file)
self.assertTrue(resource.is_local())
diff --git a/tests/validators/test_particles.py b/tests/validators/test_particles.py
index 4b5c3bd7..de738ddb 100644
--- a/tests/validators/test_particles.py
+++ b/tests/validators/test_particles.py
@@ -120,6 +120,11 @@ def test_has_occurs_restriction(self):
self.assertTrue(xsd_group[9].has_occurs_restriction(xsd_group[1]))
self.assertTrue(xsd_group[9].has_occurs_restriction(xsd_group[2]))
+ def test_default_parse_error(self):
+ with self.assertRaises(ValueError) as ctx:
+ ParticleMixin().parse_error('unexpected error')
+ self.assertEqual(str(ctx.exception), 'unexpected error')
+
def test_parse_particle(self):
schema = XMLSchema10("""
diff --git a/xmlschema/resources.py b/xmlschema/resources.py
index ac91dfd0..24a9c40e 100644
--- a/xmlschema/resources.py
+++ b/xmlschema/resources.py
@@ -890,9 +890,8 @@ def tostring(self, indent: str = '', max_lines: Optional[int] = None,
namespaces = self.get_namespaces(root_only=False)
_string = etree_tostring(elem, namespaces, indent, max_lines,
spaces_for_tab, xml_declaration)
- if isinstance(_string, bytes):
- return _string.decode('utf-8')
- return _string
+
+ return _string.decode('utf-8') if isinstance(_string, bytes) else _string
def subresource(self, elem: ElementType) -> 'XMLResource':
"""Create an XMLResource instance from a subelement of a non-lazy XML tree."""
diff --git a/xmlschema/validators/builtins.py b/xmlschema/validators/builtins.py
index f2017a6e..64492665 100644
--- a/xmlschema/validators/builtins.py
+++ b/xmlschema/validators/builtins.py
@@ -15,7 +15,7 @@
"""
from decimal import Decimal
from elementpath import datatypes
-from typing import Any, Dict, Optional, Type, Tuple, Union
+from typing import cast, Any, Dict, Optional, Type, Tuple, Union
from ..exceptions import XMLSchemaValueError
from ..names import XSD_LENGTH, XSD_MIN_LENGTH, XSD_MAX_LENGTH, XSD_ENUMERATION, \
@@ -83,7 +83,7 @@
)
-XSD_COMMON_BUILTIN_TYPES = (
+XSD_COMMON_BUILTIN_TYPES: Tuple[Dict[str, Any], ...] = (
# ***********************
# *** Primitive types ***
# ***********************
@@ -491,15 +491,12 @@ def xsd_builtin_types_factory(
item = item.copy()
name: str = item['name']
try:
- value = xsd_types[name]
+ value = cast(Tuple[ElementType, SchemaType], xsd_types[name])
except KeyError:
# If builtin type element is missing create a dummy element. Necessary for the
# meta-schema XMLSchema.xsd of XSD 1.1, that not includes builtins declarations.
elem = etree_element(XSD_SIMPLE_TYPE, name=name, id=name)
else:
- if not isinstance(value, tuple):
- continue
-
elem, schema = value
if schema is not meta_schema:
raise XMLSchemaValueError("loaded entry schema is not the meta-schema!")
diff --git a/xmlschema/validators/xsdbase.py b/xmlschema/validators/xsdbase.py
index 5a5a6556..5cad9f9d 100644
--- a/xmlschema/validators/xsdbase.py
+++ b/xmlschema/validators/xsdbase.py
@@ -466,7 +466,7 @@ def _parse_target_namespace(self) -> None:
"must have the same namespace as its parent schema")
if self.name is None:
- pass
+ pass # pragma: no cover
elif not self._target_namespace:
self.name = local_name(self.name)
else:
@@ -581,7 +581,7 @@ def get_global(self) -> 'XsdComponent':
return component
component = component.parent
else:
- return self
+ raise XMLSchemaValueError(f"parent circularity from {self}") # pragma: no cover
def get_parent_type(self) -> Optional['XsdType']:
"""
@@ -745,7 +745,7 @@ def simple_type(self) -> Optional['XsdSimpleType']:
complexType is the instance's *content* if this is a simpleType
or `None` if the instance's *content* is a model group.
"""
- return None
+ raise NotImplementedError()
@property
def model_group(self) -> Optional['XsdGroup']:
@@ -968,7 +968,7 @@ def decode(self, obj: ST, validation: str = 'strict', **kwargs: Any) -> DecodeTy
else:
errors.append(result)
- return (None, errors) if validation == 'lax' else None
+ return (None, errors) if validation == 'lax' else None # fallback: pragma: no cover
def encode(self, obj: Any, validation: str = 'strict', **kwargs: Any) -> EncodeType[Any]:
"""