Hello community,
here is the log from the commit of package python-xmlschema for
openSUSE:Factory checked in at 2020-03-27 00:29:18
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-xmlschema (Old)
and /work/SRC/openSUSE:Factory/.python-xmlschema.new.3160 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-xmlschema"
Fri Mar 27 00:29:18 2020 rev:6 rq:787856 version:1.1.2
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-xmlschema/python-xmlschema.changes
2020-03-12 22:58:57.995006525 +0100
+++
/work/SRC/openSUSE:Factory/.python-xmlschema.new.3160/python-xmlschema.changes
2020-03-27 00:29:19.408379167 +0100
@@ -1,0 +2,7 @@
+Tue Mar 24 15:10:44 UTC 2020 - [email protected]
+
+- version update to 1.1.2
+ * Extension of validation tests with *XMLSchema11* validator
+ * Fixed several bugs
+
+-------------------------------------------------------------------
Old:
----
xmlschema-1.1.1.tar.gz
New:
----
xmlschema-1.1.2.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-xmlschema.spec ++++++
--- /var/tmp/diff_new_pack.cAoFEU/_old 2020-03-27 00:29:19.980379457 +0100
+++ /var/tmp/diff_new_pack.cAoFEU/_new 2020-03-27 00:29:19.984379459 +0100
@@ -19,18 +19,20 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%define skip_python2 1
Name: python-xmlschema
-Version: 1.1.1
+Version: 1.1.2
Release: 0
Summary: An XML Schema validator and decoder
License: MIT
URL: https://github.com/brunato/xmlschema
Source:
https://files.pythonhosted.org/packages/source/x/xmlschema/xmlschema-%{version}.tar.gz
BuildRequires: %{python_module elementpath >= 1.4.0}
+BuildRequires: %{python_module lxml}
BuildRequires: %{python_module pytest}
BuildRequires: %{python_module setuptools}
BuildRequires: fdupes
BuildRequires: python-rpm-macros
Requires: python-elementpath >= 1.4.0
+Requires: python-lxml
BuildArch: noarch
%python_subpackages
++++++ xmlschema-1.1.1.tar.gz -> xmlschema-1.1.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/CHANGELOG.rst
new/xmlschema-1.1.2/CHANGELOG.rst
--- old/xmlschema-1.1.1/CHANGELOG.rst 2020-02-19 22:24:57.000000000 +0100
+++ new/xmlschema-1.1.2/CHANGELOG.rst 2020-03-22 17:03:21.000000000 +0100
@@ -2,6 +2,12 @@
CHANGELOG
*********
+`v1.1.2`_ (2020-03-22)
+======================
+* Extension of validation tests with *XMLSchema11* validator
+* Fixed several bugs
+* Extended testing with Travis CI
+
`v1.1.1`_ (2020-02-19)
======================
* Change of *skip* validation mode with errors filtering in decode() or
encode()
@@ -302,3 +308,4 @@
.. _v1.0.18: https://github.com/brunato/xmlschema/compare/v1.0.17...v1.0.18
.. _v1.1.0: https://github.com/brunato/xmlschema/compare/v1.0.18...v1.1.0
.. _v1.1.1: https://github.com/brunato/xmlschema/compare/v1.1.0...v1.1.1
+.. _v1.1.2: https://github.com/brunato/xmlschema/compare/v1.1.1...v1.1.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/PKG-INFO new/xmlschema-1.1.2/PKG-INFO
--- old/xmlschema-1.1.1/PKG-INFO 2020-02-19 22:33:28.000000000 +0100
+++ new/xmlschema-1.1.2/PKG-INFO 2020-03-22 19:41:36.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: xmlschema
-Version: 1.1.1
+Version: 1.1.2
Summary: An XML Schema validator and decoder
Home-page: https://github.com/brunato/xmlschema
Author: Davide Brunato
@@ -10,6 +10,22 @@
xmlschema
*********
+ .. image:: https://img.shields.io/pypi/v/xmlschema.svg
+ :target: https://pypi.python.org/pypi/xmlschema/
+ .. image:: https://img.shields.io/pypi/pyversions/xmlschema.svg
+ :target: https://pypi.python.org/pypi/xmlschema/
+ .. image:: https://img.shields.io/pypi/implementation/xmlschema.svg
+ :target: https://pypi.python.org/pypi/xmlschema/
+ .. image:: https://img.shields.io/badge/License-MIT-blue.svg
+ :alt: MIT License
+ :target: https://lbesson.mit-license.org/
+ .. image::
https://travis-ci.org/sissaschool/xmlschema.svg?branch=master
+ :target: https://travis-ci.org/sissaschool/xmlschema
+ .. image:: https://img.shields.io/pypi/dm/xmlschema.svg
+ :target: https://pypi.python.org/pypi/xmlschema/
+ .. image:: https://img.shields.io/badge/Maintained%3F-yes-green.svg
+ :target:
https://GitHub.com/Naereen/StrapDown.js/graphs/commit-activity
+
.. xmlschema-introduction-start
The *xmlschema* library is an implementation of `XML Schema
<http://www.w3.org/2001/XMLSchema>`_
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/README.rst
new/xmlschema-1.1.2/README.rst
--- old/xmlschema-1.1.1/README.rst 2020-01-23 22:11:08.000000000 +0100
+++ new/xmlschema-1.1.2/README.rst 2020-03-19 09:52:19.000000000 +0100
@@ -2,6 +2,22 @@
xmlschema
*********
+.. image:: https://img.shields.io/pypi/v/xmlschema.svg
+ :target: https://pypi.python.org/pypi/xmlschema/
+.. image:: https://img.shields.io/pypi/pyversions/xmlschema.svg
+ :target: https://pypi.python.org/pypi/xmlschema/
+.. image:: https://img.shields.io/pypi/implementation/xmlschema.svg
+ :target: https://pypi.python.org/pypi/xmlschema/
+.. image:: https://img.shields.io/badge/License-MIT-blue.svg
+ :alt: MIT License
+ :target: https://lbesson.mit-license.org/
+.. image:: https://travis-ci.org/sissaschool/xmlschema.svg?branch=master
+ :target: https://travis-ci.org/sissaschool/xmlschema
+.. image:: https://img.shields.io/pypi/dm/xmlschema.svg
+ :target: https://pypi.python.org/pypi/xmlschema/
+.. image:: https://img.shields.io/badge/Maintained%3F-yes-green.svg
+ :target: https://GitHub.com/Naereen/StrapDown.js/graphs/commit-activity
+
.. xmlschema-introduction-start
The *xmlschema* library is an implementation of `XML Schema
<http://www.w3.org/2001/XMLSchema>`_
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/doc/conf.py
new/xmlschema-1.1.2/doc/conf.py
--- old/xmlschema-1.1.1/doc/conf.py 2020-02-19 22:24:57.000000000 +0100
+++ new/xmlschema-1.1.2/doc/conf.py 2020-03-13 23:03:13.000000000 +0100
@@ -62,7 +62,7 @@
# The short X.Y version.
version = '1.1'
# The full version, including alpha/beta/rc tags.
-release = '1.1.1'
+release = '1.1.2'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/doc/testing.rst
new/xmlschema-1.1.2/doc/testing.rst
--- old/xmlschema-1.1.1/doc/testing.rst 2020-01-23 21:05:17.000000000 +0100
+++ new/xmlschema-1.1.2/doc/testing.rst 2020-02-19 22:42:32.000000000 +0100
@@ -99,9 +99,10 @@
**--timeout=SEC**
Timeout for fetching resources (default=300).
-**--skip**
- Skip strict encoding checks (for cases where test data uses default or
fixed values
- or some test data are skipped by wildcards processContents).
+**--lax-encode**
+ Use lax mode on encode checks (for cases where test data uses default or
+ fixed values or some test data are skipped by wildcards processContents).
+ Ignored on schema tests.
**--debug**
Activate the debug mode (only the cases with `--debug` are executed).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/setup.py new/xmlschema-1.1.2/setup.py
--- old/xmlschema-1.1.1/setup.py 2020-02-19 22:24:57.000000000 +0100
+++ new/xmlschema-1.1.2/setup.py 2020-03-13 23:02:19.000000000 +0100
@@ -37,7 +37,7 @@
setup(
name='xmlschema',
- version='1.1.1',
+ version='1.1.2',
packages=['xmlschema'],
include_package_data=True,
setup_requires=['elementpath~=1.4.0'],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/tests/check_etree_import.py
new/xmlschema-1.1.2/tests/check_etree_import.py
--- old/xmlschema-1.1.1/tests/check_etree_import.py 2020-01-23
21:05:17.000000000 +0100
+++ new/xmlschema-1.1.2/tests/check_etree_import.py 2020-03-22
18:38:59.000000000 +0100
@@ -41,13 +41,16 @@
# Check imported ElementTree
assert ElementTree._Element_Py is not ElementTree.Element, "ElementTree is
pure Python!"
- assert xmlschema.etree.ElementTree is ElementTree, "xmlschema has a
different ElementTree module!"
+ assert xmlschema.etree.ElementTree is ElementTree, \
+ "xmlschema has a different ElementTree module!"
# Check ElementTree and pure Python ElementTree imported in xmlschema
PyElementTree = xmlschema.etree.PyElementTree
assert xmlschema.etree.ElementTree.Element is not
xmlschema.etree.ElementTree._Element_Py, \
"xmlschema's ElementTree is pure Python!"
- assert PyElementTree.Element is PyElementTree._Element_Py, "PyElementTree
is not pure Python!"
- assert xmlschema.etree.ElementTree is not PyElementTree, "xmlschema
ElementTree is PyElementTree!"
+ assert PyElementTree.Element is PyElementTree._Element_Py, \
+ "PyElementTree is not pure Python!"
+ assert xmlschema.etree.ElementTree is not PyElementTree, \
+ "xmlschema ElementTree is PyElementTree!"
print("\nTest OK: ElementTree import is working as expected!")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/xmlschema-1.1.1/tests/test_cases/features/decoder/data.xml
new/xmlschema-1.1.2/tests/test_cases/features/decoder/data.xml
--- old/xmlschema-1.1.1/tests/test_cases/features/decoder/data.xml
2020-01-23 21:05:17.000000000 +0100
+++ new/xmlschema-1.1.2/tests/test_cases/features/decoder/data.xml
2020-03-16 08:53:36.000000000 +0100
@@ -11,4 +11,5 @@
<complex_boolean>false</complex_boolean>
<simple_boolean>true</simple_boolean>
<simple_boolean>false</simple_boolean>
+ <date_and_time>2020-03-05T23:04:10.047</date_and_time>
</ns:data>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/xmlschema-1.1.1/tests/test_cases/issues/issue_171/issue_171.xsd
new/xmlschema-1.1.2/tests/test_cases/issues/issue_171/issue_171.xsd
--- old/xmlschema-1.1.1/tests/test_cases/issues/issue_171/issue_171.xsd
1970-01-01 01:00:00.000000000 +0100
+++ new/xmlschema-1.1.2/tests/test_cases/issues/issue_171/issue_171.xsd
2020-03-19 10:42:52.000000000 +0100
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
+ vc:minVersion="1.1">
+ <xs:element name="tag">
+ <xs:complexType>
+ <xs:sequence/>
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="abc" type="xs:integer"/>
+ <xs:attribute name="def" type="xs:integer"/>
+ <xs:assert test="(@abc and not(@def)) or (not(@abc) and @def)"/>
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/xmlschema-1.1.1/tests/test_cases/issues/issue_171/issue_171b.xsd
new/xmlschema-1.1.2/tests/test_cases/issues/issue_171/issue_171b.xsd
--- old/xmlschema-1.1.1/tests/test_cases/issues/issue_171/issue_171b.xsd
1970-01-01 01:00:00.000000000 +0100
+++ new/xmlschema-1.1.2/tests/test_cases/issues/issue_171/issue_171b.xsd
2020-03-18 15:27:13.000000000 +0100
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
+ vc:minVersion="1.1">
+ <xs:element name="tag">
+ <xs:complexType>
+ <xs:sequence/>
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="abc" type="xs:float"/>
+ <xs:attribute name="def" type="xs:float"/>
+ <xs:assert test="(@abc and not(@def castable as xs:double)) or
+ (not(@abc castable as xs:double) and @def)"/>
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/tests/test_cases/testfiles
new/xmlschema-1.1.2/tests/test_cases/testfiles
--- old/xmlschema-1.1.1/tests/test_cases/testfiles 2020-01-23
21:05:17.000000000 +0100
+++ new/xmlschema-1.1.2/tests/test_cases/testfiles 2020-03-19
19:23:22.000000000 +0100
@@ -9,6 +9,7 @@
# Cases with schema examples
examples/collection/collection.xsd --inspect
+examples/collection/collection.xsd --inspect --version=1.1
examples/collection/collection.xml
examples/collection/collection2.xsd --inspect # key constraint
examples/collection/collection2.xml --errors 1
@@ -18,6 +19,7 @@
examples/collection/collection3bis.xml --errors 1
examples/collection/collection4.xml # Many XML comments inserted
examples/vehicles/vehicles.xsd --inspect
+examples/vehicles/vehicles.xsd --inspect --version=1.1
examples/vehicles/vehicles.xml
examples/vehicles/vehicles-1_error.xml --errors=1
examples/vehicles/vehicles-2_errors.xml --errors=2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/tests/test_etree.py
new/xmlschema-1.1.2/tests/test_etree.py
--- old/xmlschema-1.1.1/tests/test_etree.py 2020-01-23 21:05:17.000000000
+0100
+++ new/xmlschema-1.1.2/tests/test_etree.py 2020-03-22 18:38:59.000000000
+0100
@@ -54,19 +54,24 @@
self.assertIs(importlib.import_module('xml.etree.ElementTree'),
ElementTree)
self.assertIs(xmlschema_etree.ElementTree, ElementTree)
- @unittest.skipIf(platform.system() == 'Windows', "Run only for UNIX based
systems.")
+ @unittest.skipIf(platform.system() != 'Linux', "Skip macOS and Windows
platforms")
def test_element_tree_import_script(self):
test_dir = os.path.dirname(__file__) or '.'
cmd = [os.path.join(test_dir, 'check_etree_import.py')]
process = subprocess.run(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
- output = process.stdout.decode('utf-8')
- self.assertTrue("\nTest OK:" in output, msg="Wrong import of
ElementTree after xmlschema")
+
+ stderr = process.stderr.decode('utf-8')
+ self.assertTrue("ModuleNotFoundError" not in stderr,
+ msg="Test script fails because a package is
missing:\n\n{}".format(stderr))
+
+ self.assertIn("\nTest OK:", process.stdout.decode('utf-8'),
+ msg="Wrong import of ElementTree after
xmlschema:\n\n{}".format(stderr))
cmd.append('--before')
process = subprocess.run(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
- output = process.stdout.decode('utf-8')
- self.assertTrue("\nTest OK:" in output, msg="Wrong import of
ElementTree before xmlschema")
+ self.assertTrue("\nTest OK:" in process.stdout.decode('utf-8'),
+ msg="Wrong import of ElementTree before
xmlschema:\n\n{}".format(stderr))
def test_safe_xml_parser(self):
test_dir = os.path.dirname(__file__) or '.'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/tests/test_namespaces.py
new/xmlschema-1.1.2/tests/test_namespaces.py
--- old/xmlschema-1.1.1/tests/test_namespaces.py 1970-01-01
01:00:00.000000000 +0100
+++ new/xmlschema-1.1.2/tests/test_namespaces.py 2020-03-22
15:58:48.000000000 +0100
@@ -0,0 +1,217 @@
+#!/usr/bin/env python
+#
+# Copyright (c), 2016-2020, 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 <[email protected]>
+#
+import unittest
+import os
+import sys
+
+from xmlschema.testing import print_test_header
+from xmlschema.namespaces import XSD_NAMESPACE, XSI_NAMESPACE, \
+ NamespaceResourcesMap, NamespaceMapper, NamespaceView
+
+
+CASES_DIR = os.path.join(os.path.dirname(__file__), '../test_cases')
+
+
+class TestNamespaceResourcesMap(unittest.TestCase):
+
+ def test_init(self):
+ nsmap = [('tns0', 'schema1.xsd')]
+ self.assertEqual(NamespaceResourcesMap(), {})
+ self.assertEqual(NamespaceResourcesMap(nsmap), {'tns0':
['schema1.xsd']})
+ nsmap.append(('tns0', 'schema2.xsd'))
+ self.assertEqual(NamespaceResourcesMap(nsmap), {'tns0':
['schema1.xsd', 'schema2.xsd']})
+
+ @unittest.skipIf(sys.version_info[:2] < (3, 6), "Python 3.6+ needed")
+ def test_repr(self):
+ namespaces = NamespaceResourcesMap()
+ namespaces['tns0'] = 'schema1.xsd'
+ namespaces['tns1'] = 'schema2.xsd'
+ self.assertEqual(repr(namespaces), "{'tns0': ['schema1.xsd'], 'tns1':
['schema2.xsd']}")
+
+ def test_dictionary_methods(self):
+ namespaces = NamespaceResourcesMap()
+ namespaces['tns0'] = 'schema1.xsd'
+ namespaces['tns1'] = 'schema2.xsd'
+ self.assertEqual(namespaces, {'tns0': ['schema1.xsd'], 'tns1':
['schema2.xsd']})
+
+ self.assertEqual(len(namespaces), 2)
+ self.assertEqual(set(x for x in namespaces), {'tns0', 'tns1'})
+
+ del namespaces['tns0']
+ self.assertEqual(namespaces, {'tns1': ['schema2.xsd']})
+ self.assertEqual(len(namespaces), 1)
+
+ namespaces.clear()
+ self.assertEqual(namespaces, {})
+
+
+class TestNamespaceMapper(unittest.TestCase):
+
+ def test_init(self):
+ namespaces = dict(xs=XSD_NAMESPACE, xsi=XSI_NAMESPACE)
+ mapper = NamespaceMapper(namespaces)
+ self.assertEqual(mapper, namespaces)
+
+ def test_dictionary_methods(self):
+ namespaces = dict(xs=XSD_NAMESPACE)
+ mapper = NamespaceMapper(namespaces)
+
+ mapper['xsi'] = XSI_NAMESPACE
+ self.assertEqual(mapper, dict(xs=XSD_NAMESPACE, xsi=XSI_NAMESPACE))
+
+ del mapper['xs']
+ self.assertEqual(len(mapper), 1)
+ self.assertEqual(mapper, dict(xsi=XSI_NAMESPACE))
+
+ mapper.clear()
+ self.assertEqual(mapper, {})
+
+ def test_strip_namespaces(self):
+ namespaces = dict(xs=XSD_NAMESPACE, xsi=XSI_NAMESPACE)
+ mapper = NamespaceMapper(namespaces, strip_namespaces=True)
+
+ self.assertEqual(mapper.map_qname('{%s}name' % XSD_NAMESPACE), 'name')
+ self.assertEqual(mapper.map_qname('{unknown}name'), 'name')
+
+ mapper.strip_namespaces = False
+ self.assertEqual(mapper.map_qname('{%s}name' % XSD_NAMESPACE),
'xs:name')
+ self.assertEqual(mapper.map_qname('{unknown}name'), '{unknown}name')
+
+ def test_default_namespace(self):
+ namespaces = dict(xs=XSD_NAMESPACE, xsi=XSI_NAMESPACE)
+ mapper = NamespaceMapper(namespaces)
+
+ self.assertIsNone(mapper.default_namespace)
+ mapper[''] = 'tns0'
+ self.assertEqual(mapper.default_namespace, 'tns0')
+
+ def test_insert_item(self):
+ namespaces = dict(xs=XSD_NAMESPACE, xsi=XSI_NAMESPACE)
+ mapper = NamespaceMapper(namespaces)
+
+ mapper.insert_item('xs', XSD_NAMESPACE)
+ self.assertEqual(len(mapper), 2)
+
+ mapper.insert_item('', XSD_NAMESPACE)
+ self.assertEqual(len(mapper), 3)
+ mapper.insert_item('', XSD_NAMESPACE)
+ self.assertEqual(len(mapper), 3)
+ mapper.insert_item('', 'tns0')
+ self.assertEqual(len(mapper), 4)
+
+ mapper.insert_item('xs', XSD_NAMESPACE)
+ self.assertEqual(len(mapper), 4)
+ mapper.insert_item('xs', 'tns1')
+ self.assertEqual(len(mapper), 5)
+ mapper.insert_item('xs', 'tns2')
+ self.assertEqual(len(mapper), 6)
+
+ def test_map_qname(self):
+ namespaces = dict(xs=XSD_NAMESPACE, xsi=XSI_NAMESPACE)
+ mapper = NamespaceMapper(namespaces)
+
+ mapper.insert_item('', XSD_NAMESPACE)
+ self.assertEqual(mapper.map_qname(''), '')
+ self.assertEqual(mapper.map_qname('{%s}element' % XSD_NAMESPACE),
'xs:element')
+ mapper.pop('xs')
+ self.assertEqual(mapper.map_qname('{%s}element' % XSD_NAMESPACE),
'element')
+
+ with self.assertRaises(ValueError) as ctx:
+ mapper.map_qname('{%selement' % XSD_NAMESPACE)
+ self.assertIn("wrong format", str(ctx.exception))
+
+ with self.assertRaises(ValueError) as ctx:
+ mapper.map_qname('{%s}element}' % XSD_NAMESPACE)
+ self.assertIn("wrong format", str(ctx.exception))
+
+ with self.assertRaises(TypeError) as ctx:
+ mapper.map_qname(None)
+ self.assertIn("must be a string-like object", str(ctx.exception))
+
+ with self.assertRaises(TypeError) as ctx:
+ mapper.map_qname(99)
+ self.assertIn("must be a string-like object", str(ctx.exception))
+
+ def test_unmap_qname(self):
+ namespaces = dict(xs=XSD_NAMESPACE, xsi=XSI_NAMESPACE)
+ mapper = NamespaceMapper(namespaces)
+
+ self.assertEqual(mapper.unmap_qname(''), '')
+ self.assertEqual(mapper.unmap_qname('xs:element'), '{%s}element' %
XSD_NAMESPACE)
+ self.assertEqual(mapper.unmap_qname('{foo}bar'), '{foo}bar')
+ self.assertEqual(mapper.unmap_qname('xsd:element'), 'xsd:element')
+
+ with self.assertRaises(ValueError) as ctx:
+ mapper.unmap_qname('xs::element')
+ self.assertIn("wrong format", str(ctx.exception))
+
+ with self.assertRaises(TypeError) as ctx:
+ mapper.unmap_qname(None)
+ self.assertIn("must be a string-like object", str(ctx.exception))
+
+ with self.assertRaises(TypeError) as ctx:
+ mapper.unmap_qname(99)
+ self.assertIn("must be a string-like object", str(ctx.exception))
+
+ self.assertEqual(mapper.unmap_qname('element'), 'element')
+ mapper[''] = 'foo'
+ self.assertEqual(mapper.unmap_qname('element'), '{foo}element')
+ self.assertEqual(mapper.unmap_qname('element',
name_table=['element']), 'element')
+
+ def test_transfer(self):
+ mapper = NamespaceMapper(namespaces={'xs': XSD_NAMESPACE, 'xsi':
XSI_NAMESPACE})
+
+ namespaces = {'xs': 'foo'}
+ mapper.transfer(namespaces)
+ self.assertEqual(len(mapper), 2)
+ self.assertEqual(len(namespaces), 1)
+
+ namespaces = {'xs': XSD_NAMESPACE}
+ mapper.transfer(namespaces)
+ self.assertEqual(len(mapper), 2)
+ self.assertEqual(len(namespaces), 0)
+
+ namespaces = {'xs': XSI_NAMESPACE, 'tns0': 'http://xmlschema.test/ns'}
+ mapper.transfer(namespaces)
+ self.assertEqual(len(mapper), 3)
+ self.assertIn('tns0', mapper)
+ self.assertEqual(len(namespaces), 1)
+ self.assertIn('xs', namespaces)
+
+ mapper = NamespaceMapper()
+ namespaces = {'xs': XSD_NAMESPACE}
+ mapper.transfer(namespaces)
+ self.assertEqual(mapper, {'xs': XSD_NAMESPACE})
+ self.assertEqual(namespaces, {})
+
+
+class TestNamespaceView(unittest.TestCase):
+
+ def test_init(self):
+ qnames = {'{tns0}name0': 0, '{tns1}name1': 1, 'name2': 2}
+ ns_view = NamespaceView(qnames, 'tns1')
+ self.assertEqual(ns_view, {'name1': 1})
+
+ def test_repr(self):
+ qnames = {'{tns0}name0': 0, '{tns1}name1': 1, 'name2': 2}
+ ns_view = NamespaceView(qnames, 'tns0')
+ self.assertEqual(repr(ns_view), "NamespaceView({'name0': 0})")
+
+ def test_as_dict(self):
+ qnames = {'{tns0}name0': 0, '{tns1}name1': 1, '{tns1}name2': 2,
'name3': 3}
+ ns_view = NamespaceView(qnames, 'tns1')
+ self.assertEqual(ns_view.as_dict(), {'name1': 1, 'name2': 2})
+ self.assertEqual(ns_view.as_dict(True), {'{tns1}name1': 1,
'{tns1}name2': 2})
+
+
+if __name__ == '__main__':
+ print_test_header()
+ unittest.main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/tests/test_qnames.py
new/xmlschema-1.1.2/tests/test_qnames.py
--- old/xmlschema-1.1.1/tests/test_qnames.py 1970-01-01 01:00:00.000000000
+0100
+++ new/xmlschema-1.1.2/tests/test_qnames.py 2020-03-21 18:51:44.000000000
+0100
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+#
+# Copyright (c), 2016-2020, 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 <[email protected]>
+#
+import unittest
+
+from xmlschema.testing import print_test_header
+from xmlschema.qnames import get_namespace, get_qname, local_name, \
+ qname_to_prefixed, qname_to_extended, XSD_ELEMENT
+from xmlschema.namespaces import XSD_NAMESPACE
+
+
+class TestQNameHelpers(unittest.TestCase):
+
+ def test_get_namespace(self):
+ self.assertEqual(get_namespace(''), '')
+ self.assertEqual(get_namespace('local'), '')
+ self.assertEqual(get_namespace(XSD_ELEMENT), XSD_NAMESPACE)
+ self.assertEqual(get_namespace('{wrong'), '')
+
+ def test_get_qname(self):
+ self.assertEqual(get_qname(XSD_NAMESPACE, 'element'), XSD_ELEMENT)
+
+ def test_local_name(self):
+ self.assertEqual(local_name('element'), 'element')
+ self.assertEqual(local_name(XSD_ELEMENT), 'element')
+ self.assertEqual(local_name('xs:element'), 'element')
+
+ def test_qname_to_prefixed(self):
+ namespaces = {'xsd': XSD_NAMESPACE}
+ self.assertEqual(qname_to_prefixed(XSD_ELEMENT, namespaces),
'xsd:element')
+
+ def test_qname_to_extended(self):
+ namespaces = {'xsd': XSD_NAMESPACE}
+ self.assertEqual(qname_to_extended('xsd:element', namespaces),
XSD_ELEMENT)
+ self.assertEqual(qname_to_extended(XSD_ELEMENT, namespaces),
XSD_ELEMENT)
+ self.assertEqual(qname_to_extended('xsd:element', namespaces={}),
'xsd:element')
+ self.assertEqual(qname_to_extended('', namespaces), '')
+
+ namespaces = {'xs': XSD_NAMESPACE}
+ self.assertEqual(qname_to_extended('xsd:element', namespaces),
'xsd:element')
+
+ namespaces = {'': XSD_NAMESPACE}
+ self.assertEqual(qname_to_extended('element', namespaces), XSD_ELEMENT)
+
+
+if __name__ == '__main__':
+ print_test_header()
+ unittest.main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/tests/test_resources.py
new/xmlschema-1.1.2/tests/test_resources.py
--- old/xmlschema-1.1.1/tests/test_resources.py 2020-02-19 22:24:57.000000000
+0100
+++ new/xmlschema-1.1.2/tests/test_resources.py 2020-03-22 18:13:42.000000000
+0100
@@ -107,7 +107,9 @@
self.check_url(normalize_url('other.xsd', 'file:///home/'),
'file:///home/other.xsd')
self.check_url(normalize_url('file:other.xsd', 'file:///home'),
'file:///home/other.xsd')
- cwd_url = 'file://{}/'.format(os.getcwd())
+ cwd = os.getcwd()
+ cwd_url = 'file://{}/'.format(cwd) if cwd.startswith('/') else
'file:///{}/'.format(cwd)
+
self.check_url(normalize_url('file:other.xsd', keep_relative=True),
'file:other.xsd')
self.check_url(normalize_url('file:other.xsd'), cwd_url + 'other.xsd')
self.check_url(normalize_url('file:other.xsd', 'http://site/base',
True), 'file:other.xsd')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/tests/validation/test_decoding.py
new/xmlschema-1.1.2/tests/validation/test_decoding.py
--- old/xmlschema-1.1.1/tests/validation/test_decoding.py 2020-02-19
22:24:34.000000000 +0100
+++ new/xmlschema-1.1.2/tests/validation/test_decoding.py 2020-03-16
09:01:33.000000000 +0100
@@ -245,11 +245,12 @@
{'$': 'ISO-27001', '@Year': 2009}
],
'decimal_value': [Decimal('1')],
- u'menù': u'baccalà mantecato',
- u'complex_boolean': [
+ 'menù': 'baccalà mantecato',
+ 'complex_boolean': [
{'$': True, '@Type': 2}, {'$': False, '@Type': 1}, True, False
],
- u'simple_boolean': [True, False]
+ 'simple_boolean': [True, False],
+ 'date_and_time': '2020-03-05T23:04:10.047', # xs:dateTime is not decoded
for default
}
@@ -294,7 +295,8 @@
xml_dict = self.col_schema.to_dict(col_xml_tree,
namespaces=self.col_namespaces)
self.assertEqual(xml_dict, COLLECTION_DICT)
- xml_dict = xmlschema.to_dict(col_xml_tree, self.col_schema.url,
namespaces=self.col_namespaces)
+ xml_dict = xmlschema.to_dict(col_xml_tree, self.col_schema.url,
+ namespaces=self.col_namespaces)
self.assertEqual(xml_dict, COLLECTION_DICT)
def test_to_dict_from_string(self):
@@ -307,13 +309,15 @@
xml_dict = self.vh_schema.to_dict(vh_xml_string,
namespaces=self.vh_namespaces)
self.assertEqual(xml_dict, VEHICLES_DICT)
- xml_dict = xmlschema.to_dict(vh_xml_string, self.vh_schema.url,
namespaces=self.vh_namespaces)
+ xml_dict = xmlschema.to_dict(vh_xml_string, self.vh_schema.url,
+ namespaces=self.vh_namespaces)
self.assertEqual(xml_dict, VEHICLES_DICT)
xml_dict = self.col_schema.to_dict(col_xml_string,
namespaces=self.col_namespaces)
self.assertTrue(xml_dict, COLLECTION_DICT)
- xml_dict = xmlschema.to_dict(col_xml_string, self.col_schema.url,
namespaces=self.col_namespaces)
+ xml_dict = xmlschema.to_dict(col_xml_string, self.col_schema.url,
+ namespaces=self.col_namespaces)
self.assertTrue(xml_dict, COLLECTION_DICT)
def test_date_decoding(self):
@@ -338,7 +342,8 @@
self.assertEqual(data, '2019-01-01')
self.assertEqual(errors, [])
- data, errors = schema.to_dict("<Date>2019-01-01</Date>",
validation='lax', datetime_types=True)
+ data, errors = schema.to_dict("<Date>2019-01-01</Date>",
validation='lax',
+ datetime_types=True)
self.assertEqual(data, datatypes.Date10.fromstring('2019-01-01'))
self.assertEqual(errors, [])
@@ -347,7 +352,8 @@
self.assertEqual(len(errors), 1)
self.assertIn('value has to be greater or equal than', str(errors[0]))
- data, errors = schema.to_dict("<Date>1999-12-31</Date>",
validation='lax', datetime_types=True)
+ data, errors = schema.to_dict("<Date>1999-12-31</Date>",
validation='lax',
+ datetime_types=True)
self.assertEqual(data, datatypes.Date10.fromstring('1999-12-31'))
self.assertEqual(len(errors), 1)
@@ -528,7 +534,8 @@
def test_default_converter(self):
self.assertEqual(self.col_schema.to_dict(self.col_xml_file),
COLLECTION_DICT)
- default_dict = self.col_schema.to_dict(self.col_xml_file,
converter=xmlschema.XMLSchemaConverter)
+ default_dict = self.col_schema.to_dict(self.col_xml_file,
+
converter=xmlschema.XMLSchemaConverter)
self.assertEqual(default_dict, COLLECTION_DICT)
default_dict_root = self.col_schema.to_dict(self.col_xml_file,
preserve_root=True)
@@ -543,7 +550,8 @@
self.assertEqual(visitor_dict_root, {'col:collection':
COLLECTION_DICT})
def test_parker_converter(self):
- parker_dict = self.col_schema.to_dict(self.col_xml_file,
converter=xmlschema.ParkerConverter)
+ parker_dict = self.col_schema.to_dict(self.col_xml_file,
+
converter=xmlschema.ParkerConverter)
self.assertEqual(parker_dict, COLLECTION_PARKER)
parker_dict_root = self.col_schema.to_dict(
@@ -574,7 +582,8 @@
xml_data_1 = xsd_schema.to_dict(xml_string_1)
xml_data_2 = xsd_schema.to_dict(xml_string_2)
self.assertTrue(isinstance(xml_data_1['bar'], type(xml_data_2['bar'])),
- msg="XSD with an array that return a single element
from xml must still yield a list.")
+ msg="XSD with an array that return a single element
from "
+ "xml must still yield a list.")
def test_any_type(self):
any_type = xmlschema.XMLSchema.meta_schema.types['anyType']
@@ -634,9 +643,11 @@
self.check_decode(base64_length4_type, base64.b64encode(b'abcef'),
XMLSchemaValidationError)
base64_length5_type = self.st_schema.types['base64Length5']
- self.check_decode(base64_length5_type, base64.b64encode(b'1234'),
XMLSchemaValidationError)
+ self.check_decode(base64_length5_type, base64.b64encode(b'1234'),
+ XMLSchemaValidationError)
self.check_decode(base64_length5_type, base64.b64encode(b'12345'),
u'MTIzNDU=')
- self.check_decode(base64_length5_type, base64.b64encode(b'123456'),
XMLSchemaValidationError)
+ self.check_decode(base64_length5_type, base64.b64encode(b'123456'),
+ XMLSchemaValidationError)
def test_decimal_type(self):
schema = self.get_schema("""
@@ -682,8 +693,9 @@
def test_default_namespace(self):
# Issue #77
xs = xmlschema.XMLSchema("""<?xml version="1.0" encoding="UTF-8"?>
- <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://example.com/foo">
- <xs:element name="foo" type="xs:string" />
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://example.com/foo">
+ <xs:element name="foo" type="xs:string" />
</xs:schema>""")
self.assertEqual(xs.to_dict("""<foo
xmlns="http://example.com/foo">bar</foo>""",
path='/foo', namespaces={'':
'http://example.com/foo'}), 'bar')
@@ -691,7 +703,9 @@
path='/foo', namespaces={'':
'http://example.com/foo'}), None)
def test_complex_with_simple_content_restriction(self):
- xs =
self.schema_class(self.casepath('features/derivations/complex-with-simple-content-restriction.xsd'))
+ xs = self.schema_class(
+
self.casepath('features/derivations/complex-with-simple-content-restriction.xsd')
+ )
self.assertTrue(xs.is_valid('<value>10</value>'))
self.assertFalse(xs.is_valid('<value>alpha</value>'))
self.assertEqual(xs.decode('<value>10</value>'), 10)
@@ -736,9 +750,11 @@
self.assertEqual(schema.to_dict("<root>text</root>",
use_defaults=False),
{'@attrWithFixed': 'fixed_value', '$': 'text'})
- self.assertEqual(schema.to_dict("""<root
attr="attr_value">text</root>""", use_defaults=False),
+ self.assertEqual(schema.to_dict("""<root
attr="attr_value">text</root>""",
+ use_defaults=False),
{'$': 'text', '@attr': 'attr_value',
'@attrWithFixed': 'fixed_value'})
- self.assertEqual(schema.to_dict("<root/>", use_defaults=False),
{'@attrWithFixed': 'fixed_value'})
+ self.assertEqual(schema.to_dict("<root/>", use_defaults=False),
+ {'@attrWithFixed': 'fixed_value'})
self.assertEqual(schema.to_dict("<simple_root/>"), 'default_value')
self.assertIsNone(schema.to_dict("<simple_root/>", use_defaults=False))
@@ -761,7 +777,8 @@
schema = self.schema_class(xsd_text)
self.assertIsNone(schema.to_dict("<simple_root>alpha</simple_root>",
validation='lax')[0])
- self.assertEqual(schema.to_dict("<root int_attr='10'>20</root>"),
{'@int_attr': 10, '$': 20})
+ self.assertEqual(schema.to_dict("<root int_attr='10'>20</root>"),
+ {'@int_attr': 10, '$': 20})
self.assertEqual(schema.to_dict("<root int_attr='wrong'>20</root>",
validation='lax')[0],
{'@int_attr': None, '$': 20})
self.assertEqual(schema.to_dict("<root int_attr='wrong'>20</root>",
validation='skip'),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/tests/validation/test_validation.py
new/xmlschema-1.1.2/tests/validation/test_validation.py
--- old/xmlschema-1.1.1/tests/validation/test_validation.py 2020-01-23
21:05:17.000000000 +0100
+++ new/xmlschema-1.1.2/tests/validation/test_validation.py 2020-03-19
18:35:12.000000000 +0100
@@ -44,6 +44,19 @@
def test_issue_064(self):
self.check_validity(self.st_schema, '<name xmlns="ns"></name>', False)
+ def test_issue_171(self):
+ # First schema has an assert with naive check that maps '0' to False
('0'--> 0--> false)
+ schema =
xmlschema.XMLSchema11(self.casepath('issues/issue_171/issue_171.xsd'))
+ self.check_validity(schema, '<tag name="test" abc="10" def="0"/>',
True)
+ self.check_validity(schema, '<tag name="test" abc="10" def="1"/>',
False)
+ self.check_validity(schema, '<tag name="test" abc="10"/>', True)
+
+ # Same schema with a more reliable assert expression
+ schema =
xmlschema.XMLSchema11(self.casepath('issues/issue_171/issue_171b.xsd'))
+ self.check_validity(schema, '<tag name="test" abc="10" def="0"/>',
False)
+ self.check_validity(schema, '<tag name="test" abc="10" def="1"/>',
False)
+ self.check_validity(schema, '<tag name="test" abc="10"/>', True)
+
def test_document_validate_api(self):
self.assertIsNone(xmlschema.validate(self.vh_xml_file))
self.assertIsNone(xmlschema.validate(self.vh_xml_file,
use_defaults=False))
@@ -62,7 +75,8 @@
self.assertEqual('Path: /vhx:vehicles/vhx:cars', path_line)
else:
self.assertTrue(
- 'Path: /vh:vehicles/vh:cars' == path_line or 'Path:
/vhx:vehicles/vhx:cars', path_line
+ 'Path: /vh:vehicles/vh:cars' == path_line or
+ 'Path: /vhx:vehicles/vhx:cars', path_line
) # Due to unordered dicts
# Issue #80
@@ -80,10 +94,11 @@
source.root[1].clear()
xsd_element = self.col_schema.elements['collection']
- self.assertRaises(XMLSchemaValidationError, xsd_element.decode,
source.root, namespaces=namespaces)
+ self.assertRaises(XMLSchemaValidationError, xsd_element.decode,
source.root,
+ namespaces=namespaces)
for _ in xsd_element.iter_decode(source.root, 'strict',
namespaces=namespaces,
- source=source, max_depth=1):
+ source=source, max_depth=1):
del _
self.assertIsNone(xmlschema.validate(self.col_xml_file, lazy=True))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/tests/validators/test_exceptions.py
new/xmlschema-1.1.2/tests/validators/test_exceptions.py
--- old/xmlschema-1.1.1/tests/validators/test_exceptions.py 1970-01-01
01:00:00.000000000 +0100
+++ new/xmlschema-1.1.2/tests/validators/test_exceptions.py 2020-03-21
17:56:32.000000000 +0100
@@ -0,0 +1,220 @@
+#!/usr/bin/env python
+#
+# Copyright (c), 2016-2020, 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 <[email protected]>
+#
+import unittest
+import os
+import io
+import xml.etree.ElementTree as ElementTree
+import lxml.etree
+
+from xmlschema.testing import print_test_header
+from xmlschema import XMLSchema, XMLResource
+from xmlschema.validators.exceptions import XMLSchemaValidatorError, \
+ XMLSchemaNotBuiltError, XMLSchemaModelDepthError,
XMLSchemaValidationError, \
+ XMLSchemaChildrenValidationError
+
+CASES_DIR = os.path.join(os.path.dirname(__file__), '../test_cases')
+
+
+class TestValidatorExceptions(unittest.TestCase):
+
+ def test_exception_init(self):
+ xs = XMLSchema(os.path.join(CASES_DIR,
'examples/vehicles/vehicles.xsd'))
+
+ with self.assertRaises(ValueError) as ctx:
+ XMLSchemaValidatorError(xs, 'unknown error', elem='wrong')
+ self.assertIn("'elem' attribute requires an Element",
str(ctx.exception))
+
+ error = XMLSchemaNotBuiltError(xs, 'schema not built!')
+ self.assertEqual(error.message, 'schema not built!')
+
+ schema = XMLSchema("""
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:group name="group1">
+ <xs:choice>
+ <xs:element name="root" type="xs:integer"/>
+ </xs:choice>
+ </xs:group>
+ </xs:schema>""")
+
+ error = XMLSchemaModelDepthError(schema.groups['group1'])
+ self.assertEqual("maximum model recursion depth exceeded",
error.message[:38])
+
+ def test_exception_repr(self):
+ xs = XMLSchema(os.path.join(CASES_DIR,
'examples/vehicles/vehicles.xsd'))
+
+ error = XMLSchemaValidatorError(xs, 'unknown error')
+ self.assertEqual(str(error), 'unknown error')
+ self.assertEqual(error.msg, 'unknown error')
+
+ error = XMLSchemaValidatorError(xs, 'unknown error', elem=xs.root)
+ lines = str(error).split('\n')
+
+ self.assertEqual(lines[0], 'unknown error:')
+ self.assertEqual(lines[2], 'Schema:')
+ self.assertTrue(lines[4].strip().startswith('<xs:schema '))
+ self.assertEqual(lines[-2].strip(), '</xs:schema>')
+
+ schema = XMLSchema("""
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="root" type="xs:integer"/>
+ </xs:schema>""")
+ root = lxml.etree.XML('<root a="10"/>')
+
+ with self.assertRaises(XMLSchemaValidationError) as ctx:
+ schema.validate(root)
+
+ lines = str(ctx.exception).split('\n')
+ self.assertEqual(lines[0], "failed validating {'a': '10'} with
XsdAttributeGroup():")
+ self.assertEqual(lines[2], "Reason: 'a' attribute not allowed for
element.")
+ self.assertEqual(lines[8], "Instance (line 1):")
+ self.assertEqual(lines[12], "Path: /root")
+
+ self.assertEqual(repr(ctx.exception),
"XMLSchemaValidationError(reason=\"'a' "
+ "attribute not allowed for
element.\")")
+
+ error = XMLSchemaValidationError(schema.elements['root'], root)
+ self.assertIsNone(error.reason)
+ self.assertNotIn("Reason:", str(error))
+ self.assertIn("Schema:", str(error))
+
+ error = XMLSchemaValidationError(schema, root)
+ self.assertNotIn("Reason:", str(error))
+ self.assertNotIn("Schema:", str(error))
+
+ error = XMLSchemaValidationError(schema, 10)
+ self.assertEqual(str(error), "failed validating 10 with
XMLSchema10(namespace='')")
+
+ def test_setattr(self):
+ schema = XMLSchema("""
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="root" type="xs:integer"/>
+ </xs:schema>""")
+
+ root = ElementTree.XML('<root a="10"/>')
+ with self.assertRaises(XMLSchemaValidationError) as ctx:
+ schema.validate(root)
+
+ self.assertIsInstance(ctx.exception.source, XMLResource)
+ self.assertFalse(ctx.exception.source.is_lazy())
+
+ resource = XMLResource(io.StringIO('<root a="10"/>'), lazy=True)
+ with self.assertRaises(XMLSchemaValidationError) as ctx:
+ schema.validate(resource)
+
+ self.assertIsInstance(ctx.exception.source, XMLResource)
+ self.assertTrue(ctx.exception.source.is_lazy())
+ self.assertIsNone(ctx.exception.elem)
+ self.assertEqual(ctx.exception.source, resource)
+ self.assertEqual(ctx.exception.path, '/root')
+
+ def test_properties(self):
+ schema = XMLSchema("""
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="root" type="xs:integer"/>
+ </xs:schema>""")
+
+ root = lxml.etree.XML('<root a="10"/>')
+ with self.assertRaises(XMLSchemaValidationError) as ctx:
+ schema.validate(root)
+
+ self.assertEqual(ctx.exception.sourceline, 1)
+ self.assertEqual(ctx.exception.root, root)
+
+ xsd_file = os.path.join(CASES_DIR, 'examples/vehicles/vehicles.xsd')
+ xs = XMLSchema(xsd_file)
+
+ with self.assertRaises(XMLSchemaValidatorError) as ctx:
+ raise XMLSchemaValidatorError(xs, 'unknown error')
+
+ self.assertIsNone(ctx.exception.root)
+ self.assertIsNone(ctx.exception.schema_url)
+ self.assertEqual(ctx.exception.origin_url, xs.source.url)
+ self.assertIsNone(XMLSchemaValidatorError(None, 'unknown
error').origin_url)
+
+ def test_children_validation_error(self):
+ schema = XMLSchema("""
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="a">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="b1" type="xs:string"/>
+ <xs:element name="b2" type="xs:string"/>
+ <xs:element name="b3" type="xs:string" minOccurs="2"
maxOccurs="3"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:schema>""")
+
+ with self.assertRaises(XMLSchemaChildrenValidationError) as ctx:
+ schema.validate('<a><b1/><b2/><b3/><b3/><b3/><b3/></a>')
+
+ lines = str(ctx.exception).split('\n')
+ self.assertEqual(lines[2], "Reason: Unexpected child with tag 'b3' at
position 6.")
+ self.assertEqual(lines[-2], "Path: /a")
+
+ with self.assertRaises(XMLSchemaChildrenValidationError) as ctx:
+ schema.validate('<a><b1/><b2/><b3/></a>')
+
+ lines = str(ctx.exception).split('\n')
+ self.assertEqual(lines[2][:51], "Reason: The content of element 'a' is
not complete.")
+ self.assertEqual(lines[-2], "Path: /a")
+
+ root = ElementTree.XML('<a><b1/><b2/><b2/><b3/><b3/><b3/></a>')
+ validator = schema.elements['a'].type.content_type
+ with self.assertRaises(XMLSchemaChildrenValidationError) as ctx:
+ raise XMLSchemaChildrenValidationError(validator, root, 2,
validator[1], 2)
+
+ lines = str(ctx.exception).split('\n')
+ self.assertTrue(lines[2].endswith("occurs 2 times but the maximum is
1."))
+
+ schema = XMLSchema("""
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="a">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="b1" type="xs:string"/>
+ <xs:any/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:schema>""")
+
+ with self.assertRaises(XMLSchemaChildrenValidationError) as ctx:
+ schema.validate('<a><b1/></a>')
+
+ lines = str(ctx.exception).split('\n')
+ self.assertTrue(lines[2].endswith("Tag from \'##any\' namespace/s
expected."))
+
+ schema = XMLSchema("""
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="a">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="b1" type="xs:string"/>
+ <xs:choice>
+ <xs:any namespace="tns0" processContents="lax"/>
+ <xs:element name="b2" type="xs:string"/>
+ </xs:choice>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:schema>""")
+
+ with self.assertRaises(XMLSchemaChildrenValidationError) as ctx:
+ schema.validate('<a><b1/></a>')
+
+ lines = str(ctx.exception).split('\n')
+ self.assertTrue(lines[2].endswith("Tag b2 expected."))
+
+
+if __name__ == '__main__':
+ print_test_header()
+ unittest.main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/tests/validators/test_xsdbase.py
new/xmlschema-1.1.2/tests/validators/test_xsdbase.py
--- old/xmlschema-1.1.1/tests/validators/test_xsdbase.py 2020-02-19
22:24:57.000000000 +0100
+++ new/xmlschema-1.1.2/tests/validators/test_xsdbase.py 2020-03-22
17:54:12.000000000 +0100
@@ -38,9 +38,9 @@
validator = XsdValidator()
tmpl = '<xmlschema.validators.xsdbase.XsdValidator object at {}>'
string_repr = str(validator)
- if platform.python_implementation() == 'PyPy':
+ if platform.python_implementation() == 'PyPy' or platform.system() ==
'Windows':
string_repr = re.sub(r'0x[0]+', '0x', string_repr, 1)
- self.assertEqual(string_repr, tmpl.format(hex(id(validator))))
+ self.assertEqual(string_repr.lower(),
tmpl.format(hex(id(validator))).lower())
def test_parse_error(self):
xsd_file = os.path.join(CASES_DIR, 'examples/vehicles/vehicles.xsd')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/xmlschema/__init__.py
new/xmlschema-1.1.2/xmlschema/__init__.py
--- old/xmlschema-1.1.1/xmlschema/__init__.py 2020-02-19 22:24:57.000000000
+0100
+++ new/xmlschema-1.1.2/xmlschema/__init__.py 2020-03-13 23:02:43.000000000
+0100
@@ -29,7 +29,7 @@
XsdGlobals, XMLSchemaBase, XMLSchema, XMLSchema10, XMLSchema11
)
-__version__ = '1.1.1'
+__version__ = '1.1.2'
__author__ = "Davide Brunato"
__contact__ = "[email protected]"
__copyright__ = "Copyright 2016-2020, SISSA"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/xmlschema/namespaces.py
new/xmlschema-1.1.2/xmlschema/namespaces.py
--- old/xmlschema-1.1.1/xmlschema/namespaces.py 2020-01-23 21:05:17.000000000
+0100
+++ new/xmlschema-1.1.2/xmlschema/namespaces.py 2020-03-22 15:47:58.000000000
+0100
@@ -14,6 +14,7 @@
import re
from collections.abc import MutableMapping, Mapping
+from .exceptions import XMLSchemaValueError, XMLSchemaTypeError
from .qnames import get_namespace, local_name
###
@@ -196,20 +197,17 @@
try:
if qname[0] != '{' or not self._namespaces:
return qname
+ namespace, local_part = qname[1:].split('}')
except IndexError:
return qname
-
- qname_uri = get_namespace(qname)
- for prefix, uri in self._namespaces.items():
- if uri != qname_uri:
- continue
- if prefix:
- self._namespaces[prefix] = uri
- return qname.replace(u'{%s}' % uri, u'%s:' % prefix)
- else:
- if uri:
- self._namespaces[prefix] = uri
- return qname.replace(u'{%s}' % uri, '')
+ except ValueError:
+ raise XMLSchemaValueError("the argument 'qname' has a wrong
format: %r" % qname)
+ except TypeError:
+ raise XMLSchemaTypeError("the argument 'qname' must be a
string-like object")
+
+ for prefix, uri in sorted(self._namespaces.items(), reverse=True):
+ if uri == namespace:
+ return '%s:%s' % (prefix, local_part) if prefix else local_part
else:
return qname
@@ -227,27 +225,29 @@
:return: a QName in extended format or a local name.
"""
try:
- if qname[0] == '{' or not self:
+ if qname[0] == '{' or not self._namespaces:
return qname
+ prefix, name = qname.split(':')
except IndexError:
return qname
-
- try:
- prefix, name = qname.split(':', 1)
except ValueError:
+ if ':' in qname:
+ raise XMLSchemaValueError("the argument 'qname' has a wrong
format: %r" % qname)
if not self._namespaces.get(''):
return qname
elif name_table is None or qname not in name_table:
return '{%s}%s' % (self._namespaces.get(''), qname)
else:
return qname
+ except (TypeError, AttributeError):
+ raise XMLSchemaTypeError("the argument 'qname' must be a
string-like object")
else:
try:
uri = self._namespaces[prefix]
except KeyError:
return qname
else:
- return u'{%s}%s' % (uri, name) if uri else name
+ return '{%s}%s' % (uri, name) if uri else name
unmap_qname = _unmap_qname
@@ -255,17 +255,24 @@
def _local_name(qname, *_args, **_kwargs):
return local_name(qname)
- def transfer(self, other):
+ def transfer(self, namespaces):
+ """
+ Transfers compatible prefix/namespace registrations from a dictionary.
+ Registrations added to namespace mapper instance are deleted from
argument.
+
+ :param namespaces: a dictionary containing prefix/namespace
registrations.
+ """
transferred = []
- for k, v in other.items():
- if k in self:
- if v != self[k]:
+ for k, v in namespaces.items():
+ if k in self._namespaces:
+ if v != self._namespaces[k]:
continue
else:
self[k] = v
transferred.append(k)
+
for k in transferred:
- del other[k]
+ del namespaces[k]
class NamespaceView(Mapping):
@@ -298,9 +305,6 @@
def __eq__(self, other):
return self.as_dict() == dict(other.items())
- def copy(self, **kwargs):
- return self.__class__(self, **kwargs)
-
def as_dict(self, fqn_keys=False):
if fqn_keys:
return {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/xmlschema/testing/builders.py
new/xmlschema-1.1.2/xmlschema/testing/builders.py
--- old/xmlschema-1.1.1/xmlschema/testing/builders.py 2020-02-19
22:24:57.000000000 +0100
+++ new/xmlschema-1.1.2/xmlschema/testing/builders.py 2020-03-20
16:33:57.000000000 +0100
@@ -17,15 +17,16 @@
import warnings
import xmlschema
-from xmlschema import XMLSchemaBase, XMLSchemaValidationError,
ParkerConverter, \
- BadgerFishConverter, AbderaConverter, JsonMLConverter, UnorderedConverter
+from xmlschema import XMLSchemaBase, XMLSchema11, XMLSchemaValidationError, \
+ XMLSchemaParseError, ParkerConverter, BadgerFishConverter,
AbderaConverter, \
+ JsonMLConverter, UnorderedConverter
from xmlschema.compat import ordered_dict_class
from xmlschema.etree import etree_tostring, ElementTree, lxml_etree, \
etree_elements_assert_equal, py_etree_element, lxml_etree_element
from xmlschema.helpers import iter_nested_items
from xmlschema.resources import fetch_namespaces
from xmlschema.xpath import XMLSchemaContext
-from xmlschema.validators import XsdValidator
+from xmlschema.validators import XsdValidator, XsdType, Xsd11ComplexType
from .case_class import XsdValidatorTestCase
from .observers import SchemaObserver
@@ -106,6 +107,26 @@
self.assertEqual(context_elements, [x for x in
context.iter_descendants()])
self.assertEqual(context_elements, elements)
+ # Checks on XSD types
+ for xsd_type in xs.maps.iter_components(xsd_classes=XsdType):
+ self.assertNotEqual(xsd_type.content_type_label, 'unknown')
+
+ # Check that the schema is valid also with XSD 1.1 validator
+ if not expected_errors and schema_class.XSD_VERSION == '1.0':
+ try:
+ XMLSchema11(xsd_file, locations=locations, defuse=defuse,
loglevel=loglevel)
+ except XMLSchemaParseError as err:
+ if not isinstance(err.validator, Xsd11ComplexType) or \
+ "is simple or has a simple content" not in
str(err):
+ raise # Not a case of forbidden complex content
extension
+
+ xs = schema_class(xsd_file, validation='lax',
locations=locations,
+ defuse=defuse, loglevel=loglevel)
+ for error in xs.all_errors:
+ if not isinstance(err.validator, Xsd11ComplexType) or \
+ "is simple or has a simple content" not in
str(err):
+ raise error
+
def check_xsd_file_with_lxml(self, xmlschema_time):
start_time = time.time()
lxs = lxml_etree.parse(xsd_file)
@@ -145,7 +166,7 @@
else:
self.check_xsd_file()
- # Check with lxml.etree.XMLSchema class
+ # Check with lxml.etree.XMLSchema class
if check_with_lxml and lxml_etree is not None:
self.check_xsd_file_with_lxml(xmlschema_time=time.time() -
start_time)
self.check_errors(xsd_file, expected_errors)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/xmlschema/validators/assertions.py
new/xmlschema-1.1.2/xmlschema/validators/assertions.py
--- old/xmlschema-1.1.1/xmlschema/validators/assertions.py 2020-01-23
21:05:17.000000000 +0100
+++ new/xmlschema-1.1.2/xmlschema/validators/assertions.py 2020-03-18
11:57:34.000000000 +0100
@@ -62,6 +62,7 @@
return self.token is not None and (self.base_type.parent is None or
self.base_type.built)
def parse_xpath_test(self):
+ # FIXME: parser's variables filled with XSD type with next elementpath
minor release
if not self.base_type.has_simple_content():
variables = {'value': XSD_BUILTIN_TYPES['anyType'].value}
else:
@@ -85,17 +86,22 @@
except ElementPathError as err:
self.parse_error(err, elem=self.elem)
self.token = self.parser.parse('true()')
+ finally:
+ self.parser.variables.clear()
def __call__(self, elem, value=None, source=None, namespaces=None,
**kwargs):
- if value is not None:
- self.parser.variables['value'] = self.base_type.text_decode(value)
if not self.parser.is_schema_bound():
self.parser.schema.bind_parser(self.parser)
+ if value is not None:
+ variables = {'value': self.base_type.text_decode(value)}
+ else:
+ variables = {'value': ''}
+
if source is None:
- context = XPathContext(root=elem)
+ context = XPathContext(root=elem, variables=variables)
else:
- context = XPathContext(root=source.root, item=elem)
+ context = XPathContext(root=source.root, item=elem,
variables=variables)
default_namespace = self.parser.namespaces['']
if namespaces and '' in namespaces:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/xmlschema/validators/elements.py
new/xmlschema-1.1.2/xmlschema/validators/elements.py
--- old/xmlschema-1.1.1/xmlschema/validators/elements.py 2020-02-19
22:24:57.000000000 +0100
+++ new/xmlschema-1.1.2/xmlschema/validators/elements.py 2020-03-19
16:08:18.000000000 +0100
@@ -1079,6 +1079,9 @@
for alt in self.alternatives:
yield from alt.iter_components(xsd_classes)
+ if not hasattr(self.type, 'attributes'):
+ yield from self.attributes.iter_components(xsd_classes)
+
if self.ref is None and self.type.parent is not None:
yield from self.type.iter_components(xsd_classes)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/xmlschema/validators/exceptions.py
new/xmlschema-1.1.2/xmlschema/validators/exceptions.py
--- old/xmlschema-1.1.1/xmlschema/validators/exceptions.py 2020-01-23
21:05:17.000000000 +0100
+++ new/xmlschema-1.1.2/xmlschema/validators/exceptions.py 2020-03-21
17:37:41.000000000 +0100
@@ -40,22 +40,19 @@
def __str__(self):
if self.elem is None:
- return '%s.' % self.message
- else:
- msg = ['%s:\n' % self.message]
- if self.elem is not None:
- elem_as_string = etree_tostring(self.elem, self.namespaces, '
', 20)
- if hasattr(self.elem, 'sourceline'):
- msg.append("Schema (line %r):\n\n%s\n" %
(self.elem.sourceline, elem_as_string))
- else:
- msg.append("Schema:\n\n%s\n" % elem_as_string)
- if self.path is not None:
- msg.append("Path: %s\n" % self.path)
- if self.schema_url is not None:
- msg.append("Schema URL: %s\n" % self.schema_url)
- if self.origin_url not in (None, self.schema_url):
- msg.append("Origin URL: %s\n" % self.origin_url)
- return '\n'.join(msg)
+ return self.message
+
+ msg = ['%s:\n' % self.message]
+ elem_as_string = etree_tostring(self.elem, self.namespaces, ' ', 20)
+ msg.append("Schema:\n\n%s\n" % elem_as_string)
+
+ if self.path is not None:
+ msg.append("Path: %s\n" % self.path)
+ if self.schema_url is not None:
+ msg.append("Schema URL: %s\n" % self.schema_url)
+ if self.origin_url not in (None, self.schema_url):
+ msg.append("Origin URL: %s\n" % self.origin_url)
+ return '\n'.join(msg)
@property
def msg(self):
@@ -72,11 +69,6 @@
relative=False, add_position=True)
if self.source.is_lazy():
value = None # Don't save the element of a lazy resource
- if name == 'source' and value is not None and getattr(self, 'elem',
None) is not None:
- self.path = etree_getpath(self.elem, value.root, self.namespaces,
- relative=False, add_position=True)
- if value.is_lazy():
- self.elem = None
super(XMLSchemaValidatorError, self).__setattr__(name, value)
@property
@@ -167,7 +159,7 @@
class XMLSchemaModelDepthError(XMLSchemaModelError):
"""Raised when recursion depth is exceeded while iterating a model
group."""
def __init__(self, group):
- msg = "maximum model recursion depth exceeded while iterating group
%r" % group
+ msg = "maximum model recursion depth exceeded while iterating
{!r}".format(group)
super(XMLSchemaModelDepthError, self).__init__(group, message=msg)
@@ -226,6 +218,8 @@
msg.append("Instance:\n\n%s\n" % elem_as_string)
if self.path is not None:
msg.append("Path: %s\n" % self.path)
+ if len(msg) == 1:
+ return msg[0][:-2]
return '\n'.join(msg)
@@ -334,7 +328,7 @@
if not expected_tags:
pass
elif len(expected_tags) == 1:
- reason += " Tag %r expected." % expected_tags[0]
+ reason += " Tag %s expected." % expected_tags[0]
else:
reason += " Tag (%s) expected." % ' | '.join(expected_tags)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/xmlschema/validators/facets.py
new/xmlschema-1.1.2/xmlschema/validators/facets.py
--- old/xmlschema-1.1.1/xmlschema/validators/facets.py 2020-02-19
22:24:57.000000000 +0100
+++ new/xmlschema-1.1.2/xmlschema/validators/facets.py 2020-03-11
11:38:12.000000000 +0100
@@ -289,10 +289,10 @@
_ADMITTED_TAGS = XSD_MIN_INCLUSIVE,
def _parse_value(self, elem):
- try:
- self.value =
self.base_type.primitive_type.decode(elem.attrib['value'])
- except AttributeError:
- self.value = self.base_type.decode(elem.attrib['value'])
+ self.value, errors = self.base_type.decode(elem.attrib['value'],
validation='lax')
+ for e in errors:
+ if not isinstance(e.validator, self.__class__) or
e.validator.value != self.value:
+ raise e
facet = self.base_type.get_facet(XSD_MIN_EXCLUSIVE)
if facet is not None and facet.value >= self.value:
@@ -331,10 +331,10 @@
_ADMITTED_TAGS = XSD_MIN_EXCLUSIVE,
def _parse_value(self, elem):
- try:
- self.value =
self.base_type.primitive_type.decode(elem.attrib['value'])
- except AttributeError:
- self.value = self.base_type.decode(elem.attrib['value'])
+ self.value, errors = self.base_type.decode(elem.attrib['value'],
validation='lax')
+ for e in errors:
+ if not isinstance(e.validator, self.__class__) or
e.validator.value != self.value:
+ raise e
facet = self.base_type.get_facet(XSD_MIN_EXCLUSIVE)
if facet is not None and facet.value > self.value:
@@ -373,10 +373,10 @@
_ADMITTED_TAGS = XSD_MAX_INCLUSIVE,
def _parse_value(self, elem):
- try:
- self.value =
self.base_type.primitive_type.decode(elem.attrib['value'])
- except AttributeError:
- self.value = self.base_type.decode(elem.attrib['value'])
+ self.value, errors = self.base_type.decode(elem.attrib['value'],
validation='lax')
+ for e in errors:
+ if not isinstance(e.validator, self.__class__) or
e.validator.value != self.value:
+ raise e
facet = self.base_type.get_facet(XSD_MIN_EXCLUSIVE)
if facet is not None and facet.value >= self.value:
@@ -415,10 +415,10 @@
_ADMITTED_TAGS = XSD_MAX_EXCLUSIVE,
def _parse_value(self, elem):
- try:
- self.value =
self.base_type.primitive_type.decode(elem.attrib['value'])
- except AttributeError:
- self.value = self.base_type.decode(elem.attrib['value'])
+ self.value, errors = self.base_type.decode(elem.attrib['value'],
validation='lax')
+ for e in errors:
+ if not isinstance(e.validator, self.__class__) or
e.validator.value != self.value:
+ raise e
facet = self.base_type.get_facet(XSD_MIN_EXCLUSIVE)
if facet is not None and facet.value >= self.value:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/xmlschema.egg-info/PKG-INFO
new/xmlschema-1.1.2/xmlschema.egg-info/PKG-INFO
--- old/xmlschema-1.1.1/xmlschema.egg-info/PKG-INFO 2020-02-19
22:33:28.000000000 +0100
+++ new/xmlschema-1.1.2/xmlschema.egg-info/PKG-INFO 2020-03-22
19:41:36.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: xmlschema
-Version: 1.1.1
+Version: 1.1.2
Summary: An XML Schema validator and decoder
Home-page: https://github.com/brunato/xmlschema
Author: Davide Brunato
@@ -10,6 +10,22 @@
xmlschema
*********
+ .. image:: https://img.shields.io/pypi/v/xmlschema.svg
+ :target: https://pypi.python.org/pypi/xmlschema/
+ .. image:: https://img.shields.io/pypi/pyversions/xmlschema.svg
+ :target: https://pypi.python.org/pypi/xmlschema/
+ .. image:: https://img.shields.io/pypi/implementation/xmlschema.svg
+ :target: https://pypi.python.org/pypi/xmlschema/
+ .. image:: https://img.shields.io/badge/License-MIT-blue.svg
+ :alt: MIT License
+ :target: https://lbesson.mit-license.org/
+ .. image::
https://travis-ci.org/sissaschool/xmlschema.svg?branch=master
+ :target: https://travis-ci.org/sissaschool/xmlschema
+ .. image:: https://img.shields.io/pypi/dm/xmlschema.svg
+ :target: https://pypi.python.org/pypi/xmlschema/
+ .. image:: https://img.shields.io/badge/Maintained%3F-yes-green.svg
+ :target:
https://GitHub.com/Naereen/StrapDown.js/graphs/commit-activity
+
.. xmlschema-introduction-start
The *xmlschema* library is an implementation of `XML Schema
<http://www.w3.org/2001/XMLSchema>`_
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.1.1/xmlschema.egg-info/SOURCES.txt
new/xmlschema-1.1.2/xmlschema.egg-info/SOURCES.txt
--- old/xmlschema-1.1.1/xmlschema.egg-info/SOURCES.txt 2020-02-19
22:33:28.000000000 +0100
+++ new/xmlschema-1.1.2/xmlschema.egg-info/SOURCES.txt 2020-03-22
19:41:36.000000000 +0100
@@ -24,7 +24,9 @@
tests/test_files.py
tests/test_helpers.py
tests/test_memory.py
+tests/test_namespaces.py
tests/test_package.py
+tests/test_qnames.py
tests/test_regex.py
tests/test_resources.py
tests/test_schemas.py
@@ -151,6 +153,8 @@
tests/test_cases/issues/issue_111/issue_111.xsd
tests/test_cases/issues/issue_111/issue_111_skeleton.xsd
tests/test_cases/issues/issue_115/Rotation.xsd
+tests/test_cases/issues/issue_171/issue_171.xsd
+tests/test_cases/issues/issue_171/issue_171b.xsd
tests/test_cases/resources/dummy file #2.txt
tests/test_cases/resources/dummy file.txt
tests/test_cases/resources/external_entity.xml
@@ -165,6 +169,7 @@
tests/validators/test_attributes.py
tests/validators/test_builtins.py
tests/validators/test_complex_types.py
+tests/validators/test_exceptions.py
tests/validators/test_global_maps.py
tests/validators/test_identities.py
tests/validators/test_models.py