Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-xmlschema for
openSUSE:Factory checked in at 2023-02-11 22:20:05
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-xmlschema (Old)
and /work/SRC/openSUSE:Factory/.python-xmlschema.new.1848 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-xmlschema"
Sat Feb 11 22:20:05 2023 rev:19 rq:1064241 version:2.2.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-xmlschema/python-xmlschema.changes
2022-10-04 20:37:17.748879628 +0200
+++
/work/SRC/openSUSE:Factory/.python-xmlschema.new.1848/python-xmlschema.changes
2023-02-11 22:20:07.168048762 +0100
@@ -1,0 +2,11 @@
+Fri Feb 10 12:46:13 UTC 2023 - Dirk Müller <[email protected]>
+
+- update to 2.2.0:
+ * Refine string serialization of XML resources and data
+ elements
+ * Switch to use elementpath v4
+ * Fix sequence_type property for XSD types
+ * Remove *XsdElement.get_attribute()*: unused and doesn't work
+ as expected
+
+-------------------------------------------------------------------
Old:
----
xmlschema-2.1.1.tar.gz
New:
----
xmlschema-2.2.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-xmlschema.spec ++++++
--- /var/tmp/diff_new_pack.vp5zlv/_old 2023-02-11 22:20:07.740052262 +0100
+++ /var/tmp/diff_new_pack.vp5zlv/_new 2023-02-11 22:20:07.756052360 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-xmlschema
#
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%define skip_python2 1
Name: python-xmlschema
-Version: 2.1.1
+Version: 2.2.0
Release: 0
Summary: An XML Schema validator and decoder
License: MIT
++++++ xmlschema-2.1.1.tar.gz -> xmlschema-2.2.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/CHANGELOG.rst
new/xmlschema-2.2.0/CHANGELOG.rst
--- old/xmlschema-2.1.1/CHANGELOG.rst 2022-10-01 15:42:01.000000000 +0200
+++ new/xmlschema-2.2.0/CHANGELOG.rst 2023-02-06 07:20:42.000000000 +0100
@@ -2,6 +2,13 @@
CHANGELOG
*********
+`v2.2.0`_ (2023-02-06)
+======================
+* Refine string serialization of XML resources and data elements
+* Switch to use elementpath v4
+* Fix sequence_type property for XSD types
+* Remove *XsdElement.get_attribute()*: unused and doesn't work as expected
+
`v2.1.1`_ (2022-10-01)
======================
* Fix *schema_path* usage in `XMLSchemaBase.iter_errors()`
@@ -591,3 +598,4 @@
.. _v2.0.4: https://github.com/brunato/xmlschema/compare/v2.0.3...v2.0.4
.. _v2.1.0: https://github.com/brunato/xmlschema/compare/v2.0.4...v2.1.0
.. _v2.1.1: https://github.com/brunato/xmlschema/compare/v2.1.0...v2.1.1
+.. _v2.2.0: https://github.com/brunato/xmlschema/compare/v2.1.1...v2.2.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/PKG-INFO new/xmlschema-2.2.0/PKG-INFO
--- old/xmlschema-2.1.1/PKG-INFO 2022-10-01 19:02:18.985521600 +0200
+++ new/xmlschema-2.2.0/PKG-INFO 2023-02-06 10:06:40.856029000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: xmlschema
-Version: 2.1.1
+Version: 2.2.0
Summary: An XML Schema validator and decoder
Home-page: https://github.com/sissaschool/xmlschema
Author: Davide Brunato
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/doc/conf.py
new/xmlschema-2.2.0/doc/conf.py
--- old/xmlschema-2.1.1/doc/conf.py 2022-10-01 15:42:01.000000000 +0200
+++ new/xmlschema-2.2.0/doc/conf.py 2023-02-06 07:20:42.000000000 +0100
@@ -79,9 +79,9 @@
# built documents.
#
# The short X.Y version.
-version = '2.1'
+version = '2.2'
# The full version, including alpha/beta/rc tags.
-release = '2.1.1'
+release = '2.2.0'
# 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-2.1.1/requirements-dev.txt
new/xmlschema-2.2.0/requirements-dev.txt
--- old/xmlschema-2.1.1/requirements-dev.txt 2022-07-18 16:19:15.000000000
+0200
+++ new/xmlschema-2.2.0/requirements-dev.txt 2023-02-06 07:20:42.000000000
+0100
@@ -1,8 +1,8 @@
# Requirements for setup a development environment for the xmlschema package.
setuptools
-tox
+tox>=4.0
coverage
-elementpath>=3.0.0, <4.0.0
+elementpath>=4.0.0, <5.0.0
lxml
jinja2
memory_profiler
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/setup.py new/xmlschema-2.2.0/setup.py
--- old/xmlschema-2.1.1/setup.py 2022-10-01 15:42:01.000000000 +0200
+++ new/xmlschema-2.2.0/setup.py 2023-02-06 07:20:42.000000000 +0100
@@ -18,7 +18,7 @@
setup(
name='xmlschema',
- version='2.1.1',
+ version='2.2.0',
packages=find_packages(include=['xmlschema*']),
package_data={
'xmlschema': ['py.typed', 'locale/**/*.mo', 'locale/**/*.po',
'schemas/*/*.xsd'],
@@ -32,13 +32,13 @@
]
},
python_requires='>=3.7',
- install_requires=['elementpath>=3.0.0, <4.0.0'],
+ install_requires=['elementpath>=4.0.0, <5.0.0'],
extras_require={
- 'codegen': ['elementpath>=3.0.0, <4.0.0', 'jinja2'],
- 'dev': ['tox', 'coverage', 'lxml', 'elementpath>=3.0.0, <4.0.0',
+ 'codegen': ['elementpath>=4.0.0, <5.0.0', 'jinja2'],
+ 'dev': ['tox', 'coverage', 'lxml', 'elementpath>=4.0.0, <5.0.0',
'memory_profiler', 'Sphinx', 'sphinx_rtd_theme', 'jinja2',
'flake8', 'mypy', 'lxml-stubs'],
- 'docs': ['elementpath>=3.0.0, <4.0.0', 'Sphinx', 'sphinx_rtd_theme',
'jinja2']
+ 'docs': ['elementpath>=4.0.0, <5.0.0', 'Sphinx', 'sphinx_rtd_theme',
'jinja2']
},
author='Davide Brunato',
author_email='[email protected]',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/tests/test_dataobjects.py
new/xmlschema-2.2.0/tests/test_dataobjects.py
--- old/xmlschema-2.1.1/tests/test_dataobjects.py 2022-07-21
11:40:50.000000000 +0200
+++ new/xmlschema-2.2.0/tests/test_dataobjects.py 2023-02-06
09:55:27.000000000 +0100
@@ -14,8 +14,10 @@
from typing import Dict
from xmlschema import XMLSchema10, XMLSchema11, fetch_namespaces,
etree_tostring, \
- XMLSchemaValidationError, DataElement, DataElementConverter, XMLResource
+ XMLSchemaValidationError, DataElement, DataElementConverter, XMLResource, \
+ XsdElement, XsdAttribute, XsdType
+from xmlschema.validators import XsdAttributeGroup
from xmlschema.helpers import is_etree_element
from xmlschema.names import XSI_TYPE
from xmlschema.dataobjects import DataBindingMeta, DataBindingConverter
@@ -45,10 +47,11 @@
self.assertIsNone(data_element.get('a'))
self.assertEqual(data_element.get('b'), 9)
- def test_namespaces(self):
+ def test_nsmap(self):
self.assertEqual(DataElement('foo').nsmap, {})
nsmap = {'tns': 'http://xmlschema.test/ns'}
self.assertEqual(DataElement('foo', nsmap=nsmap).nsmap, nsmap)
+ self.assertIsNot(DataElement('foo', nsmap=nsmap).nsmap, nsmap)
def test_attributes_with_namespaces(self):
nsmap = {'tns': 'http://xmlschema.test/ns'}
@@ -265,12 +268,72 @@
self.assertIsInstance(etree_tostring(obj), str)
self.assertIsNone(etree_elements_assert_equal(obj, root, strict=False))
+ def test_collapsed_namespace_map(self):
+ col_data = self.col_schema.decode(self.col_xml_filename)
+
+ namespaces = col_data.get_namespaces()
+ self.assertDictEqual(
+ namespaces,
+ {'col': 'http://example.com/ns/collection',
+ 'xsi': 'http://www.w3.org/2001/XMLSchema-instance'}
+ )
+
+ namespaces = col_data.get_namespaces({'': 'http://xmlschema.test/ns'})
+ self.assertDictEqual(
+ namespaces,
+ {'': 'http://xmlschema.test/ns',
+ 'col': 'http://example.com/ns/collection',
+ 'xsi': 'http://www.w3.org/2001/XMLSchema-instance'}
+ )
+
+ namespaces = col_data.get_namespaces({'tns':
'http://xmlschema.test/ns'})
+ self.assertDictEqual(
+ namespaces,
+ {'tns': 'http://xmlschema.test/ns',
+ 'col': 'http://example.com/ns/collection',
+ 'xsi': 'http://www.w3.org/2001/XMLSchema-instance'}
+ )
+
+ namespaces = col_data.get_namespaces({'xsi':
'http://xmlschema.test/ns'})
+ self.assertDictEqual(
+ namespaces,
+ {'xsi': 'http://xmlschema.test/ns',
+ 'col': 'http://example.com/ns/collection',
+ 'xsi0': 'http://www.w3.org/2001/XMLSchema-instance'}
+ )
+
+ xsd_filename = self.casepath('examples/collection/collection5.xsd')
+ col_schema = self.schema_class(xsd_filename, converter=self.converter)
+ xml_filename =
self.casepath('examples/collection/collection-default.xml')
+ col_data = col_schema.decode(xml_filename)
+
+ namespaces = col_data.get_namespaces()
+ self.assertDictEqual(
+ namespaces,
+ {'': 'http://example.com/ns/collection',
+ 'xsi': 'http://www.w3.org/2001/XMLSchema-instance'}
+ )
+
+ namespaces = col_data.get_namespaces({'': 'http://xmlschema.test/ns'})
+ self.assertDictEqual(
+ namespaces,
+ {'': 'http://xmlschema.test/ns',
+ 'default': 'http://example.com/ns/collection',
+ 'xsi': 'http://www.w3.org/2001/XMLSchema-instance'}
+ )
+
def test_serialize_to_xml_source(self):
col_data = self.col_schema.decode(self.col_xml_filename)
- xml_source = col_data.tostring()
- self.assertTrue(xml_source.startswith('<col:collection '))
- self.assertTrue(xml_source.endswith('</col:collection>'))
+ with Path(self.col_xml_filename).open() as fp:
+ _ = fp.read()
+
+ result = col_data.tostring()
+ self.assertTrue(result.startswith('<col:collection '))
+ self.assertTrue(result.endswith('</col:collection>'))
+
+ result = col_data.tostring(xml_declaration=True)
+ self.assertTrue(self.col_schema.is_valid(result))
def test_validation(self):
with self.assertRaises(ValueError) as ec:
@@ -433,6 +496,21 @@
self.assertEqual(data_element[0][0].get('b:type'),
'p:ConcreteContainterItemInfo')
self.assertIsNone(data_element[0][0].get('xsi:type'))
+ def test_xsd_attribute_access__issue_331(self):
+ col_data = self.col_schema.decode(self.col_xml_filename)
+ self.assertIsInstance(col_data[0].xsd_element, XsdElement)
+ self.assertEqual(col_data[0].xsd_element.name, 'object')
+ self.assertIsInstance(
+ col_data[0].xsd_element.attributes, XsdAttributeGroup
+ )
+ xsd_attribute = col_data[0].xsd_element.attributes.get('id')
+ self.assertIsInstance(xsd_attribute, XsdAttribute)
+
+ xsd_attribute = col_data[0].xsd_element.find('@id')
+ self.assertIsInstance(xsd_attribute, XsdAttribute)
+ self.assertIsInstance(xsd_attribute.type, XsdType)
+ self.assertIsNone(col_data[0].xsd_element.find('@unknown'))
+
class TestDataBindings(TestDataObjects):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/tests/test_documents.py
new/xmlschema-2.2.0/tests/test_documents.py
--- old/xmlschema-2.1.1/tests/test_documents.py 2022-09-25 09:58:42.000000000
+0200
+++ new/xmlschema-2.2.0/tests/test_documents.py 2023-02-06 07:20:42.000000000
+0100
@@ -458,7 +458,7 @@
xml_document = XmlDocument(self.col_xml_file, lazy=True)
with self.assertRaises(XMLResourceError) as ctx:
xml_document.write(str(col_file_path))
- self.assertEqual(str(ctx.exception), "cannot serialize a lazy XML
document")
+ self.assertEqual(str(ctx.exception), "cannot serialize a lazy XML
resource")
def test_xml_document_etree_interface(self):
xml_document = XmlDocument(self.vh_xml_file)
@@ -471,7 +471,8 @@
xml_document = XmlDocument(self.vh_xml_file, lazy=1)
with self.assertRaises(XMLResourceError) as ctx:
xml_document.get_etree_document()
- self.assertIn('cannot create an ElementTree from a lazy resource',
str(ctx.exception))
+ self.assertIn('cannot create an ElementTree instance from a lazy XML
resource',
+ str(ctx.exception))
vh_tree = ElementTree.parse(self.vh_xml_file)
xml_document = XmlDocument(vh_tree, base_url=self.vh_dir)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/tests/test_resources.py
new/xmlschema-2.2.0/tests/test_resources.py
--- old/xmlschema-2.1.1/tests/test_resources.py 2022-07-18 16:19:15.000000000
+0200
+++ new/xmlschema-2.2.0/tests/test_resources.py 2023-02-06 07:20:42.000000000
+0100
@@ -43,6 +43,10 @@
DRIVE_REGEX = '/[a-zA-Z]:' if platform.system() == 'Windows' else ''
+XML_WITH_NAMESPACES = '<pfa:root xmlns:pfa="http://xmlschema.test/nsa">\n' \
+ ' <pfb:elem xmlns:pfb="http://xmlschema.test/nsb"/>\n' \
+ '</pfa:root>'
+
def casepath(relative_path):
return str(pathlib.Path(TEST_CASES_DIR).joinpath(relative_path))
@@ -456,7 +460,7 @@
self.assertIsNone(resource.text)
with self.assertRaises(XMLResourceError) as ctx:
resource.load()
- self.assertIn('cannot load a lazy resource', str(ctx.exception))
+ self.assertIn('cannot load a lazy XML resource', str(ctx.exception))
self.assertIsNone(resource.text)
resource = XMLResource(self.vh_xml_file, lazy=False)
@@ -492,7 +496,7 @@
self.assertIsNone(resource.text)
with self.assertRaises(XMLResourceError) as ctx:
resource.load()
- self.assertIn('cannot load a lazy resource', str(ctx.exception))
+ self.assertIn('cannot load a lazy XML resource', str(ctx.exception))
self.assertIsNone(resource.text)
resource = XMLResource(path, lazy=False)
@@ -605,7 +609,7 @@
with self.assertRaises(XMLResourceError) as ctx:
resource.load()
- self.assertEqual("cannot load a lazy resource", str(ctx.exception))
+ self.assertEqual("cannot load a lazy XML resource",
str(ctx.exception))
self.assertFalse(schema_file.closed)
for _ in resource.iter():
@@ -962,7 +966,24 @@
resource = XMLResource(self.vh_xml_file, lazy=True)
with self.assertRaises(XMLResourceError) as ctx:
resource.tostring()
- self.assertEqual("cannot serialize a lazy resource",
str(ctx.exception))
+ self.assertEqual("cannot serialize a lazy XML resource",
str(ctx.exception))
+
+ resource = XMLResource(XML_WITH_NAMESPACES)
+ result = resource.tostring()
+ self.assertNotEqual(result, XML_WITH_NAMESPACES)
+
+ # With xml.etree.ElementTree namespace declarations are serialized
+ # with a loss of information (all collapsed into the root element).
+ self.assertEqual(result, '<pfa:root
xmlns:pfa="http://xmlschema.test/nsa" '
+ 'xmlns:pfb="http://xmlschema.test/nsb">\n'
+ ' <pfb:elem />\n</pfa:root>')
+
+ if lxml_etree is not None:
+ root = lxml_etree.XML(XML_WITH_NAMESPACES)
+ resource = XMLResource(root)
+
+ # With lxml.etree there is no information loss.
+ self.assertEqual(resource.tostring(), XML_WITH_NAMESPACES)
def test_xml_resource_open(self):
resource = XMLResource(self.vh_xml_file)
@@ -1459,7 +1480,8 @@
resource = XMLResource(StringIO('<a><b1><c1/><c2/></b1><b2/></a>'),
lazy=True)
with self.assertRaises(XMLResourceError) as ctx:
_ = resource.parent_map
- self.assertEqual("cannot create the parent map of a lazy resource",
str(ctx.exception))
+ self.assertEqual("cannot create the parent map of a lazy XML resource",
+ str(ctx.exception))
def test_get_nsmap(self):
source = '<a xmlns="uri1"><b1 xmlns:x="uri2"><c1/><c2/></b1><b2
xmlns="uri3"/></a>'
@@ -1502,7 +1524,8 @@
resource = XMLResource(self.vh_xml_file, lazy=True)
with self.assertRaises(XMLResourceError) as ctx:
resource.subresource(resource.root)
- self.assertEqual("cannot create a subresource from a lazy resource",
str(ctx.exception))
+ self.assertEqual("cannot create a subresource from a lazy XML
resource",
+ str(ctx.exception))
resource = XMLResource(self.vh_xml_file)
root = resource.root
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/tests/validation/test_decoding.py
new/xmlschema-2.2.0/tests/validation/test_decoding.py
--- old/xmlschema-2.1.1/tests/validation/test_decoding.py 2022-08-26
17:33:28.000000000 +0200
+++ new/xmlschema-2.2.0/tests/validation/test_decoding.py 2023-02-06
07:20:42.000000000 +0100
@@ -866,8 +866,8 @@
self.assertIsInstance(obj, str)
obj = xs.decode('<hex> 9AFD </hex>', binary_types=True)
- self.assertEqual(obj, '9AFD')
self.assertIsInstance(obj, datatypes.HexBinary)
+ self.assertEqual(obj.value, b'9AFD')
xs = self.get_schema('<xs:attribute name="hex" type="xs:hexBinary"/>')
@@ -876,8 +876,8 @@
self.assertIsInstance(obj, str)
obj = xs.attributes['hex'].decode(' 9AFD ', binary_types=True)
- self.assertEqual(obj, '9AFD')
self.assertIsInstance(obj, datatypes.HexBinary)
+ self.assertEqual(obj.value, b'9AFD')
def test_base64_binary_type(self):
base64_code_type = self.st_schema.types['base64Code']
@@ -891,7 +891,7 @@
xs = self.get_schema('<xs:attribute name="b64"
type="xs:base64Binary"/>')
obj = xs.attributes['b64'].decode(base64_value.decode())
- self.assertEqual(obj, expected_value)
+ self.assertEqual(obj, str(expected_value))
self.assertIsInstance(obj, str)
obj = xs.attributes['b64'].decode(base64_value.decode(),
binary_types=True)
@@ -902,7 +902,7 @@
xs = self.get_schema('<xs:element name="b64" type="xs:base64Binary"/>')
obj = xs.decode('<b64>{}</b64>'.format(base64_value.decode()))
- self.assertEqual(obj, expected_value)
+ self.assertEqual(obj, str(expected_value))
self.assertIsInstance(obj, str)
obj = xs.decode('<b64>{}</b64>'.format(base64_value.decode()),
binary_types=True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/tests/validators/test_identities.py
new/xmlschema-2.2.0/tests/validators/test_identities.py
--- old/xmlschema-2.1.1/tests/validators/test_identities.py 2022-07-18
16:19:15.000000000 +0200
+++ new/xmlschema-2.2.0/tests/validators/test_identities.py 2023-02-06
07:20:42.000000000 +0100
@@ -122,7 +122,7 @@
</xs:key>
</xs:element>""")
- self.assertIn("a QName cannot contains spaces", ctx.exception.message)
+ self.assertIn("XPST0003", ctx.exception.message)
def test_selector_target_namespace(self):
schema = self.check_schema("""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/tox.ini new/xmlschema-2.2.0/tox.ini
--- old/xmlschema-2.1.1/tox.ini 2022-10-01 15:42:01.000000000 +0200
+++ new/xmlschema-2.2.0/tox.ini 2023-02-06 07:20:42.000000000 +0100
@@ -1,28 +1,28 @@
[tox]
-envlist = py{37,38,39,310,311}, pypy3, ep{300}, docs,
+envlist = py{37,38,39,310,311}, pypy3, ep{40}, docs,
flake8, mypy-py{37,38,39,310,311}, coverage, pytest
skip_missing_interpreters = true
-toxworkdir = {homedir}/.tox/xmlschema
+work_dir = {tox_root}/../.tox/xmlschema
[testenv]
deps =
- elementpath>=3.0.0, <4.0.0
+ elementpath>=4.0.0, <5.0.0
lxml
jinja2
- py{39,310}: memory_profiler
+ py{310,311}: memory_profiler
docs: Sphinx
docs: sphinx_rtd_theme
coverage: coverage
commands =
python -m unittest
-whitelist_externals = make
+allowlist_externals = make
[testenv:pypy3]
commands = python -m unittest
-[testenv:ep300]
+[testenv:ep40]
deps =
- elementpath~=3.0.0
+ elementpath~=4.0.0
lxml
[testenv:docs]
@@ -44,8 +44,8 @@
[testenv:mypy-py37]
deps =
- mypy==0.981
- elementpath==3.0.1
+ mypy==0.991
+ elementpath==4.0.1
lxml-stubs
jinja2
commands =
@@ -53,8 +53,8 @@
[testenv:mypy-py{38,39,310,311}]
deps =
- mypy==0.981
- elementpath==3.0.1
+ mypy==0.991
+ elementpath==4.0.1
lxml-stubs
jinja2
commands =
@@ -71,10 +71,10 @@
deps =
pytest
pytest-randomly
- elementpath>=3.0.0, <4.0.0
+ elementpath>=4.0.0, <5.0.0
lxml
jinja2
- mypy==0.981
+ mypy==0.991
lxml-stubs
commands =
pytest tests -ra
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/xmlschema/__init__.py
new/xmlschema-2.2.0/xmlschema/__init__.py
--- old/xmlschema-2.1.1/xmlschema/__init__.py 2022-10-01 15:42:01.000000000
+0200
+++ new/xmlschema-2.2.0/xmlschema/__init__.py 2023-02-06 07:20:42.000000000
+0100
@@ -31,10 +31,10 @@
XsdComponent, XsdType, XsdElement, XsdAttribute
)
-__version__ = '2.1.1'
+__version__ = '2.2.0'
__author__ = "Davide Brunato"
__contact__ = "[email protected]"
-__copyright__ = "Copyright 2016-2022, SISSA"
+__copyright__ = "Copyright 2016-2023, SISSA"
__license__ = "MIT"
__status__ = "Production/Stable"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/xmlschema/dataobjects.py
new/xmlschema-2.2.0/xmlschema/dataobjects.py
--- old/xmlschema-2.1.1/xmlschema/dataobjects.py 2022-07-21
11:40:50.000000000 +0200
+++ new/xmlschema-2.2.0/xmlschema/dataobjects.py 2023-02-06
09:54:57.000000000 +0100
@@ -7,7 +7,9 @@
#
# @author Davide Brunato <[email protected]>
#
+import re
from abc import ABCMeta
+from copy import copy
from itertools import count
from typing import TYPE_CHECKING, cast, overload, Any, Dict, List, Iterator, \
Optional, Union, Tuple, Type, MutableMapping, MutableSequence
@@ -188,6 +190,71 @@
"""The local part of the tag."""
return local_name(self.tag)
+ def iter(self, tag: Optional[str] = None) -> Iterator['DataElement']:
+ """
+ Creates an iterator for the data element and its subelements. If tag
+ is not `None` or '*', only data elements whose matches tag are returned
+ from the iterator.
+ """
+ if tag == '*':
+ tag = None
+ if tag is None or tag == self.tag:
+ yield self
+ for child in self._children:
+ yield from child.iter(tag)
+
+ def iterchildren(self, tag: Optional[str] = None) ->
Iterator['DataElement']:
+ """
+ Creates an iterator for the child data elements. If *tag* is not
`None` or '*',
+ only data elements whose name matches tag are returned from the
iterator.
+ """
+ if tag == '*':
+ tag = None
+ for child in self:
+ if tag is None or tag == child.tag:
+ yield child
+
+ def get_namespaces(self, namespaces: Optional[NamespacesType] = None) ->
NamespacesType:
+ """
+ Returns an overall namespace map for DetaElement and its descendants,
+ resolving prefix redefinitions.
+
+ :param namespaces: builds the namespace map starting over the
dictionary provided.
+ """
+ namespaces = copy(namespaces) if namespaces is not None else {}
+ nsmap = None
+
+ for elem in self.iter():
+ if nsmap is elem.nsmap:
+ continue
+ else:
+ nsmap = elem.nsmap
+ for prefix, uri in nsmap.items():
+ if not prefix:
+ if not uri:
+ continue
+ elif '' not in namespaces:
+ if self.namespace:
+ namespaces[prefix] = uri
+ continue
+ elif namespaces[''] == uri:
+ continue
+ prefix = 'default'
+
+ while prefix in namespaces:
+ if namespaces[prefix] == uri:
+ break
+ match = re.search(r'(\d+)$', prefix)
+ if match:
+ index = int(match.group()) + 1
+ prefix = prefix[:match.span()[0]] + str(index)
+ else:
+ prefix += '0'
+ else:
+ namespaces[prefix] = uri
+
+ return namespaces
+
def validate(self, use_defaults: bool = True,
namespaces: Optional[NamespacesType] = None,
max_depth: Optional[int] = None) -> None:
@@ -228,11 +295,10 @@
raise XMLSchemaValueError("%r has no schema bindings" % self)
kwargs: Dict[str, Any] = {
+ 'namespaces': self.get_namespaces(namespaces),
'converter': DataElementConverter,
'use_defaults': use_defaults,
}
- if namespaces:
- kwargs['namespaces'] = namespaces
if isinstance(max_depth, int) and max_depth >= 0:
kwargs['max_depth'] = max_depth
@@ -256,6 +322,7 @@
:raises: :exc:`XMLSchemaValidationError` if the object is invalid \
and ``validation='strict'``.
"""
+ kwargs['namespaces'] = self.get_namespaces(kwargs.get('namespaces'))
if 'converter' not in kwargs:
kwargs['converter'] = DataElementConverter
@@ -271,11 +338,44 @@
to_etree = encode
- def tostring(self, indent: str = '', max_lines: Optional[int] = None,
- spaces_for_tab: int = 4) -> Any:
- """Serializes the data element tree to an XML source string."""
- root, errors = self.encode(validation='lax')
- return etree_tostring(root, self.nsmap, indent, max_lines,
spaces_for_tab)
+ def tostring(self, namespaces: Optional[MutableMapping[str, str]] = None,
+ indent: str = '', max_lines: Optional[int] = None,
+ spaces_for_tab: int = 4, xml_declaration: bool = False,
+ encoding: str = 'unicode', method: str = 'xml') -> str:
+ """
+ Serializes the data element tree to an XML source string.
+
+ :param namespaces: is an optional mapping from namespace prefix to
URI. \
+ Provided namespaces are registered before serialization. Ignored if
the \
+ provided *elem* argument is a lxml Element instance.
+ :param indent: the base line indentation.
+ :param max_lines: if truncate serialization after a number of lines \
+ (default: do not truncate).
+ :param spaces_for_tab: number of spaces for replacing tab characters.
For \
+ default tabs are replaced with 4 spaces, provide `None` to keep tab
characters.
+ :param xml_declaration: if set to `True` inserts the XML declaration
at the head.
+ :param encoding: if "unicode" (the default) the output is a string, \
+ otherwise itâs binary.
+ :param method: is either "xml" (the default), "html" or "text".
+ :return: a Unicode string.
+ """
+ root, _ = self.encode(validation='lax')
+ if not hasattr(root, 'nsmap'):
+ namespaces = self.get_namespaces(namespaces)
+
+ _string = etree_tostring(
+ elem=root,
+ namespaces=namespaces,
+ indent=indent,
+ max_lines=max_lines,
+ spaces_for_tab=spaces_for_tab,
+ xml_declaration=xml_declaration,
+ encoding=encoding,
+ method=method
+ )
+ if isinstance(_string, bytes):
+ return _string.decode('utf-8')
+ return _string
def _get_xpath_context(self) -> XPathContext:
xpath_root = build_node_tree(cast(protocols.ElementProtocol, self))
@@ -326,30 +426,6 @@
results = parser.parse(path).select_results(context)
yield from filter(lambda x: isinstance(x, DataElement), results)
- def iter(self, tag: Optional[str] = None) -> Iterator['DataElement']:
- """
- Creates an iterator for the data element and its subelements. If tag
- is not `None` or '*', only data elements whose matches tag are returned
- from the iterator.
- """
- if tag == '*':
- tag = None
- if tag is None or tag == self.tag:
- yield self
- for child in self._children:
- yield from child.iter(tag)
-
- def iterchildren(self, tag: Optional[str] = None) ->
Iterator['DataElement']:
- """
- Creates an iterator for the child data elements. If *tag* is not
`None` or '*',
- only data elements whose name matches tag are returned from the
iterator.
- """
- if tag == '*':
- tag = None
- for child in self:
- if tag is None or tag == child.tag:
- yield child
-
class DataBindingMeta(ABCMeta):
"""Metaclass for creating classes with bindings to XSD elements."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/xmlschema/documents.py
new/xmlschema-2.2.0/xmlschema/documents.py
--- old/xmlschema-2.1.1/xmlschema/documents.py 2022-09-25 09:58:42.000000000
+0200
+++ new/xmlschema-2.2.0/xmlschema/documents.py 2023-02-06 07:20:42.000000000
+0100
@@ -8,6 +8,7 @@
# @author Davide Brunato <[email protected]>
#
import json
+import copy
from io import IOBase, TextIOBase
from typing import Any, Dict, List, Optional, Type, Union, Tuple, \
IO, BinaryIO, TextIO, Iterator
@@ -616,7 +617,7 @@
def parse(self, source: XMLSourceType, lazy: LazyType = False) -> None:
super(XmlDocument, self).parse(source, lazy)
- self.namespaces = self.get_namespaces(self._namespaces)
+ self.namespaces = self.get_namespaces()
if self.schema is None:
pass
@@ -625,40 +626,38 @@
elif self.validation == 'lax':
self.errors = [e for e in self.schema.iter_errors(self,
namespaces=self.namespaces)]
+ def get_namespaces(self, namespaces: Optional[NamespacesType] = None,
+ root_only: Optional[bool] = None) -> NamespacesType:
+ if not self._namespaces:
+ _namespaces = namespaces
+ elif not namespaces:
+ _namespaces = self._namespaces
+ else:
+ _namespaces = copy.copy(self._namespaces)
+ _namespaces.update(namespaces)
+
+ return super().get_namespaces(_namespaces, root_only)
+
def getroot(self) -> ElementType:
"""Get the root element of the XML document."""
return self._root
def get_etree_document(self) -> Any:
"""
- The resource as ElementTree XML document. If the resource is lazy
raises a resource error.
+ The resource as ElementTree XML document. If the resource is lazy
+ raises a resource error.
"""
if is_etree_document(self._source):
return self._source
elif self._lazy:
- raise XMLResourceError("cannot create an ElementTree from a lazy
resource")
+ raise XMLResourceError(
+ "cannot create an ElementTree instance from a lazy XML
resource"
+ )
elif hasattr(self._root, 'nsmap'):
return self._root.getroottree() # type: ignore[attr-defined]
else:
return ElementTree.ElementTree(self._root)
- def tostring(self, indent: str = '', max_lines: Optional[int] = None,
- spaces_for_tab: int = 4, xml_declaration: bool = False,
- encoding: str = 'unicode', method: str = 'xml') -> str:
- if self._lazy:
- raise XMLResourceError("cannot serialize a lazy XML document")
-
- _string = etree_tostring(
- elem=self._root,
- namespaces=self.namespaces,
- xml_declaration=xml_declaration,
- encoding=encoding,
- method=method
- )
- if isinstance(_string, bytes):
- return _string.decode('utf-8')
- return _string
-
def decode(self, **kwargs: Any) -> DecodeType[Any]:
"""
Decode the XML document to a nested Python dictionary.
@@ -731,7 +730,7 @@
default_namespace: Optional[str] = None, method: str = "xml") ->
None:
"""Serialize an XML resource to a file. Cannot be used with lazy
resources."""
if self._lazy:
- raise XMLResourceError("cannot serialize a lazy XML document")
+ raise XMLResourceError("cannot serialize a lazy XML resource")
kwargs: Dict[str, Any] = {
'xml_declaration': xml_declaration,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/xmlschema/resources.py
new/xmlschema-2.2.0/xmlschema/resources.py
--- old/xmlschema-2.1.1/xmlschema/resources.py 2022-09-08 12:16:11.000000000
+0200
+++ new/xmlschema-2.2.0/xmlschema/resources.py 2023-02-06 07:20:42.000000000
+0100
@@ -27,7 +27,7 @@
from .exceptions import XMLSchemaTypeError, XMLSchemaValueError,
XMLResourceError
from .names import XML_NAMESPACE
-from .aliases import ElementType, ElementTreeType, NamespacesType,
XMLSourceType, \
+from .aliases import ElementType, NamespacesType, XMLSourceType, \
NormalizedLocationsType, LocationsType, NsmapType, ParentMapType
from .helpers import get_namespace, is_etree_document,
etree_iter_location_hints
@@ -536,15 +536,15 @@
if self._allow == 'all':
return
elif self._allow == 'none':
- raise XMLResourceError("block access to resource {}".format(url))
+ raise XMLResourceError(f"block access to resource {url}")
elif self._allow == 'remote':
if is_local_url(url):
- raise XMLResourceError("block access to local resource
{}".format(url))
+ raise XMLResourceError(f"block access to local resource {url}")
elif is_remote_url(url):
- raise XMLResourceError("block access to remote resource
{}".format(url))
+ raise XMLResourceError(f"block access to remote resource {url}")
elif self._allow == 'sandbox' and self._base_url is not None:
if not url.startswith(normalize_url(self._base_url)):
- raise XMLResourceError("block access to out of sandbox file
{}".format(url))
+ raise XMLResourceError(f"block access to out of sandbox file
{url}")
def _track_nsmap(self, elements: Iterator[ElementType],
nsmap: NsmapType) -> Iterator[ElementType]:
@@ -793,7 +793,7 @@
self._root = cast(ElementType, source)
elif is_etree_document(source):
# Could be only an ElementTree object at last
- self._root = cast(ElementTreeType, source).getroot()
+ self._root = source.getroot()
else:
raise XMLSchemaTypeError(
"wrong type %r for 'source' attribute: an ElementTree
object or "
@@ -827,7 +827,7 @@
@property
def parent_map(self) -> Dict[ElementType, Optional[ElementType]]:
if self._lazy:
- raise XMLResourceError("cannot create the parent map of a lazy
resource")
+ raise XMLResourceError("cannot create the parent map of a lazy XML
resource")
if self._parent_map is None:
assert self._root is not None
self._parent_map = {child: elem for elem in self._root.iter() for
child in elem}
@@ -917,23 +917,51 @@
return self.tostring(xml_declaration=True)
- def tostring(self, indent: str = '', max_lines: Optional[int] = None,
- spaces_for_tab: int = 4, xml_declaration: bool = False) ->
str:
- """Generates a string representation of the XML resource."""
+ def tostring(self, namespaces: Optional[MutableMapping[str, str]] = None,
+ indent: str = '', max_lines: Optional[int] = None,
+ spaces_for_tab: int = 4, xml_declaration: bool = False,
+ encoding: str = 'unicode', method: str = 'xml') -> str:
+ """
+ Serialize an XML resource to a string.
+
+ :param namespaces: is an optional mapping from namespace prefix to
URI. \
+ Provided namespaces are registered before serialization. Ignored if
the \
+ provided *elem* argument is a lxml Element instance.
+ :param indent: the base line indentation.
+ :param max_lines: if truncate serialization after a number of lines \
+ (default: do not truncate).
+ :param spaces_for_tab: number of spaces for replacing tab characters.
For \
+ default tabs are replaced with 4 spaces, provide `None` to keep tab
characters.
+ :param xml_declaration: if set to `True` inserts the XML declaration
at the head.
+ :param encoding: if "unicode" (the default) the output is a string, \
+ otherwise itâs binary.
+ :param method: is either "xml" (the default), "html" or "text".
+ :return: a Unicode string.
+ """
if self._lazy:
- raise XMLResourceError("cannot serialize a lazy resource")
+ raise XMLResourceError("cannot serialize a lazy XML resource")
- elem = self._root
- namespaces = self.get_namespaces(root_only=False)
- _string = etree_tostring(elem, namespaces, indent, max_lines,
- spaces_for_tab, xml_declaration)
+ if not hasattr(self._root, 'nsmap'):
+ namespaces = self.get_namespaces(namespaces)
- return _string.decode('utf-8') if isinstance(_string, bytes) else
_string
+ _string = etree_tostring(
+ elem=self._root,
+ namespaces=namespaces,
+ indent=indent,
+ max_lines=max_lines,
+ spaces_for_tab=spaces_for_tab,
+ xml_declaration=xml_declaration,
+ encoding=encoding,
+ method=method
+ )
+ if isinstance(_string, bytes):
+ return _string.decode('utf-8')
+ return _string
def subresource(self, elem: ElementType) -> 'XMLResource':
"""Create an XMLResource instance from a subelement of a non-lazy XML
tree."""
if self._lazy:
- raise XMLResourceError("cannot create a subresource from a lazy
resource")
+ raise XMLResourceError("cannot create a subresource from a lazy
XML resource")
for e in self._root.iter(): # pragma: no cover
if e is elem:
@@ -969,7 +997,7 @@
if self.seek(0) == 0:
return cast(IO[AnyStr], self._source)
elif self._url is None:
- raise XMLResourceError("can't open, the resource has no URL
associated.")
+ raise XMLResourceError(f"can't open, {self!r} has no URL
associated")
try:
return cast(IO[AnyStr], urlopen(self._url, timeout=self._timeout))
@@ -1013,7 +1041,7 @@
if self._url is None and not hasattr(self._source, 'read'):
return # Created from Element or text source --> already loaded
elif self._lazy:
- raise XMLResourceError("cannot load a lazy resource")
+ raise XMLResourceError("cannot load a lazy XML resource")
resource = self.open()
try:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/xmlschema-2.1.1/xmlschema/validators/complex_types.py
new/xmlschema-2.2.0/xmlschema/validators/complex_types.py
--- old/xmlschema-2.1.1/xmlschema/validators/complex_types.py 2022-09-25
09:58:42.000000000 +0200
+++ new/xmlschema-2.2.0/xmlschema/validators/complex_types.py 2023-02-06
07:20:42.000000000 +0100
@@ -15,12 +15,12 @@
from ..names import XSD_GROUP, XSD_ATTRIBUTE_GROUP, XSD_SEQUENCE,
XSD_OVERRIDE, \
XSD_ALL, XSD_CHOICE, XSD_ANY_ATTRIBUTE, XSD_ATTRIBUTE,
XSD_COMPLEX_CONTENT, \
XSD_RESTRICTION, XSD_COMPLEX_TYPE, XSD_EXTENSION, XSD_ANY_TYPE,
XSD_ASSERT, \
- XSD_UNTYPED_ATOMIC, XSD_SIMPLE_CONTENT, XSD_OPEN_CONTENT, XSD_ANNOTATION
+ XSD_SIMPLE_CONTENT, XSD_OPEN_CONTENT, XSD_ANNOTATION
from ..aliases import ElementType, NamespacesType, SchemaType,
ComponentClassType, \
DecodeType, IterDecodeType, IterEncodeType, BaseXsdType, AtomicValueType, \
ExtraValidatorType
from ..translation import gettext as _
-from ..helpers import get_prefixed_qname, get_qname, local_name
+from ..helpers import get_qname, local_name
from .exceptions import XMLSchemaDecodeError
from .helpers import get_xsd_derivation_attribute
@@ -537,15 +537,14 @@
if self.is_empty():
return 'empty-sequence()'
elif not self.has_simple_content():
- st = get_prefixed_qname(XSD_UNTYPED_ATOMIC, self.namespaces)
+ st = 'xs:untypedAtomic'
else:
try:
- st = self.content.primitive_type.prefixed_name # type:
ignore[union-attr]
+ name = self.content.primitive_type.local_name # type:
ignore[union-attr]
except AttributeError:
- st = get_prefixed_qname(XSD_UNTYPED_ATOMIC, self.namespaces)
+ st = 'xs:untypedAtomic'
else:
- if st is None:
- st = 'item()'
+ st = 'item()' if name is None else f'xs:{name}'
return f"{st}{'*' if self.is_emptiable() else '+'}"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/xmlschema/validators/elements.py
new/xmlschema-2.2.0/xmlschema/validators/elements.py
--- old/xmlschema-2.1.1/xmlschema/validators/elements.py 2022-10-01
12:20:15.000000000 +0200
+++ new/xmlschema-2.2.0/xmlschema/validators/elements.py 2023-02-06
07:20:42.000000000 +0100
@@ -37,7 +37,8 @@
ElementPathMixin, XPathElement
from ..resources import XMLResource
-from .exceptions import XMLSchemaValidationError, XMLSchemaTypeTableWarning
+from .exceptions import XMLSchemaNotBuiltError, XMLSchemaValidationError, \
+ XMLSchemaTypeTableWarning
from .helpers import get_xsd_derivation_attribute
from .xsdbase import XSD_TYPE_DERIVATIONS, XSD_ELEMENT_DERIVATIONS, \
XsdComponent, ValidationMixin
@@ -472,15 +473,6 @@
dataobjects.DataBindingMeta(class_name, bases,
attrs))
return self.binding
- def get_attribute(self, name: str) -> Optional[XsdAttribute]:
- if name[0] != '{':
- name = get_qname(self.type.target_namespace, name)
- if not isinstance(self.type, XsdSimpleType):
- xsd_attribute = self.type.attributes[name]
- assert isinstance(xsd_attribute, XsdAttribute)
- return xsd_attribute
- return None
-
def get_type(self, elem: Union[ElementType, ElementData],
inherited: Optional[Dict[str, Any]] = None) -> BaseXsdType:
return self._head_type or self.type
@@ -675,8 +667,13 @@
if self.identities:
xpath_element = XPathElement(self.name, xsd_type)
for identity in self.identities.values():
- if isinstance(identity.elements, tuple):
- continue # Skip unbuilt identities
+ if isinstance(identity.elements, tuple) \
+ or identity.selector is None:
+ continue # Skip unbuilt or incomplete identities
+ elif identity.selector.token is None:
+ raise XMLSchemaNotBuiltError(
+ identity, "identity selector is not built"
+ )
context = XPathContext(
root=self.schema.xpath_node,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/xmlschema/validators/exceptions.py
new/xmlschema-2.2.0/xmlschema/validators/exceptions.py
--- old/xmlschema-2.1.1/xmlschema/validators/exceptions.py 2022-07-18
16:19:15.000000000 +0200
+++ new/xmlschema-2.2.0/xmlschema/validators/exceptions.py 2023-02-06
07:20:42.000000000 +0100
@@ -240,7 +240,7 @@
msg.append('Reason: %s\n' % self.reason)
if hasattr(self.validator, 'tostring'):
- chunk = self.validator.tostring(' ', 20) # type:
ignore[union-attr]
+ chunk = self.validator.tostring(' ', 20)
msg.append("Schema:\n\n%s\n" % chunk)
if self.elem is not None and is_etree_element(self.elem):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/xmlschema/validators/identities.py
new/xmlschema-2.2.0/xmlschema/validators/identities.py
--- old/xmlschema-2.1.1/xmlschema/validators/identities.py 2022-07-18
16:19:15.000000000 +0200
+++ new/xmlschema-2.2.0/xmlschema/validators/identities.py 2023-02-06
07:20:42.000000000 +0100
@@ -22,6 +22,7 @@
from ..translation import gettext as _
from ..helpers import get_qname, get_extended_qname
from ..aliases import ElementType, SchemaType, NamespacesType, AtomicValueType
+from .exceptions import XMLSchemaNotBuiltError
from .xsdbase import XsdComponent
from .attributes import XsdAttribute
@@ -68,8 +69,8 @@
lazy_quantifiers=False,
anchors=False
)
- token = None # type: XPathToken
- parser = None # type: IdentityXPathParser
+ token: Optional[XPathToken] = None
+ parser: Optional[IdentityXPathParser] = None
def __init__(self, elem: ElementType, schema: SchemaType,
parent: Optional['XsdIdentity']) -> None:
@@ -161,8 +162,8 @@
parent: 'XsdElement'
ref: Optional['XsdIdentity']
- selector = None # type: XsdSelector
- fields = () # type: Union[Tuple[()], List[XsdFieldSelector]]
+ selector: Optional[XsdSelector] = None
+ fields: Union[Tuple[()], List[XsdFieldSelector]] = ()
# XSD elements bound by selector (for speed-up and for lazy mode)
elements: Union[Tuple[()], Dict['XsdElement',
Optional[IdentityCounterType]]] = ()
@@ -206,34 +207,37 @@
self.fields = ref.fields
self.ref = ref
+ if self.selector is None:
+ return # Do not raise, already found by meta-schema validation.
+ elif self.selector.token is None:
+ raise XMLSchemaNotBuiltError(self, "identity selector is not
built")
+
context = XPathContext(self.schema.xpath_node,
item=self.parent.xpath_node)
self.elements = {}
- try:
- for e in self.selector.token.select_results(context):
- if not isinstance(e, XsdComponent) or isinstance(e,
XsdAttribute):
- msg = _("selector xpath expression can only select
elements")
- self.parse_error(msg)
- elif e.name is not None:
- if TYPE_CHECKING:
- assert isinstance(e, XsdElement) # for mypy checks
with Python 3.7
- self.elements[e] = None
- except AttributeError:
- pass
- else:
- if not self.elements:
- # Try to detect target XSD elements extracting QNames
- # of the leaf elements from the XPath expression and
- # use them to match global elements.
-
- qname: Any
- for qname in self.selector.token.iter_leaf_elements():
- xsd_element = self.maps.elements.get(
- get_extended_qname(qname, self.namespaces)
- )
- if xsd_element is not None and \
- not isinstance(xsd_element, tuple) and \
- xsd_element not in self.elements:
- self.elements[xsd_element] = None
+
+ for e in self.selector.token.select_results(context):
+ if not isinstance(e, XsdComponent) or isinstance(e, XsdAttribute):
+ msg = _("selector xpath expression can only select elements")
+ self.parse_error(msg)
+ elif e.name is not None:
+ if TYPE_CHECKING:
+ assert isinstance(e, XsdElement) # for mypy checks with
Python 3.7
+ self.elements[e] = None
+
+ if not self.elements:
+ # Try to detect target XSD elements extracting QNames
+ # of the leaf elements from the XPath expression and
+ # use them to match global elements.
+
+ qname: Any
+ for qname in self.selector.token.iter_leaf_elements():
+ xsd_element = self.maps.elements.get(
+ get_extended_qname(qname, self.namespaces)
+ )
+ if xsd_element is not None and \
+ not isinstance(xsd_element, tuple) and \
+ xsd_element not in self.elements:
+ self.elements[xsd_element] = None
@property
def built(self) -> bool:
@@ -268,6 +272,10 @@
value: Union[AtomicValueType, None]
for k, field in enumerate(self.fields):
+ if field.token is None:
+ msg = f"identity field {field} is not built"
+ raise XMLSchemaNotBuiltError(self, msg)
+
context = XPathContext(element_node)
result = field.token.get_results(context)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/xmlschema/validators/schemas.py
new/xmlschema-2.2.0/xmlschema/validators/schemas.py
--- old/xmlschema-2.1.1/xmlschema/validators/schemas.py 2022-10-01
15:42:01.000000000 +0200
+++ new/xmlschema-2.2.0/xmlschema/validators/schemas.py 2023-02-06
07:20:42.000000000 +0100
@@ -208,7 +208,6 @@
belong the declarations/definitions of the schema. If it's empty no
namespace is associated \
with the schema. In this case the schema declarations can be reused from
other namespaces as \
*chameleon* definitions.
- :ivar validation: validation mode, can be 'strict', 'lax' or 'skip'.
:ivar maps: XSD global declarations/definitions maps. This is an instance
of \
:class:`XsdGlobals`, that stores the *global_maps* argument or a new
object \
when this argument is not provided.
@@ -350,7 +349,7 @@
self.imports = {}
self.includes = {}
self.warnings = []
- self._root_elements = None # type: Optional[Set[str]]
+ self._root_elements: Optional[Set[str]] = None
self.name = self.source.name
root = self.source.root
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/xmlschema/validators/simple_types.py
new/xmlschema-2.2.0/xmlschema/validators/simple_types.py
--- old/xmlschema-2.1.1/xmlschema/validators/simple_types.py 2022-09-25
09:58:42.000000000 +0200
+++ new/xmlschema-2.2.0/xmlschema/validators/simple_types.py 2023-02-06
07:20:42.000000000 +0100
@@ -12,7 +12,7 @@
"""
from decimal import DecimalException
from typing import cast, Any, Callable, Dict, Iterator, List, \
- Optional, Pattern, Set, Union, Tuple, Type
+ Optional, Set, Union, Tuple, Type
from xml.etree import ElementTree
from ..aliases import ElementType, AtomicValueType, ComponentClassType, \
@@ -25,9 +25,9 @@
XSD_LENGTH, XSD_MIN_LENGTH, XSD_MAX_LENGTH, XSD_WHITE_SPACE,
XSD_ENUMERATION,\
XSD_LIST, XSD_ANY_SIMPLE_TYPE, XSD_UNION, XSD_RESTRICTION, XSD_ANNOTATION,
\
XSD_ASSERTION, XSD_ID, XSD_IDREF, XSD_FRACTION_DIGITS, XSD_TOTAL_DIGITS, \
- XSD_EXPLICIT_TIMEZONE, XSD_ERROR, XSD_ASSERT, XSD_QNAME, XSD_UNTYPED_ATOMIC
+ XSD_EXPLICIT_TIMEZONE, XSD_ERROR, XSD_ASSERT, XSD_QNAME
from ..translation import gettext as _
-from ..helpers import get_prefixed_qname, local_name
+from ..helpers import local_name
from .exceptions import XMLSchemaValidationError, XMLSchemaEncodeError, \
XMLSchemaDecodeError, XMLSchemaParseError
@@ -96,7 +96,6 @@
if white_space is not None:
self.white_space = white_space
- p: Pattern[str]
patterns = self.get_facet(XSD_PATTERN)
if isinstance(patterns, XsdPatternFacets):
self.patterns = patterns
@@ -353,16 +352,16 @@
root_type = self.root_type
if root_type.name is not None:
- sequence_type = cast(str, root_type.prefixed_name)
+ sequence_type = f'xs:{root_type.local_name}'
else:
- sequence_type = get_prefixed_qname(XSD_UNTYPED_ATOMIC,
self.namespaces)
+ sequence_type = 'xs:untypedAtomic'
if not self.is_list():
return sequence_type
elif self.is_emptiable():
- return '{}*'.format(sequence_type)
+ return f'{sequence_type}*'
else:
- return '{}+'.format(sequence_type)
+ return f'{sequence_type}+'
def is_empty(self) -> bool:
return self.max_length == 0 or \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/xmlschema/validators/xsdbase.py
new/xmlschema-2.2.0/xmlschema/validators/xsdbase.py
--- old/xmlschema-2.1.1/xmlschema/validators/xsdbase.py 2022-09-08
12:16:11.000000000 +0200
+++ new/xmlschema-2.2.0/xmlschema/validators/xsdbase.py 2023-02-06
07:20:42.000000000 +0100
@@ -768,6 +768,7 @@
@staticmethod
def is_complex() -> bool:
"""Returns `True` if the instance is a complexType, `False`
otherwise."""
+ return False
def is_atomic(self) -> bool:
"""Returns `True` if the instance is an atomic simpleType, `False`
otherwise."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/xmlschema.egg-info/PKG-INFO
new/xmlschema-2.2.0/xmlschema.egg-info/PKG-INFO
--- old/xmlschema-2.1.1/xmlschema.egg-info/PKG-INFO 2022-10-01
19:02:18.000000000 +0200
+++ new/xmlschema-2.2.0/xmlschema.egg-info/PKG-INFO 2023-02-06
10:06:40.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: xmlschema
-Version: 2.1.1
+Version: 2.2.0
Summary: An XML Schema validator and decoder
Home-page: https://github.com/sissaschool/xmlschema
Author: Davide Brunato
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-2.1.1/xmlschema.egg-info/requires.txt
new/xmlschema-2.2.0/xmlschema.egg-info/requires.txt
--- old/xmlschema-2.1.1/xmlschema.egg-info/requires.txt 2022-10-01
19:02:18.000000000 +0200
+++ new/xmlschema-2.2.0/xmlschema.egg-info/requires.txt 2023-02-06
10:06:40.000000000 +0100
@@ -1,14 +1,14 @@
-elementpath<4.0.0,>=3.0.0
+elementpath<5.0.0,>=4.0.0
[codegen]
-elementpath<4.0.0,>=3.0.0
+elementpath<5.0.0,>=4.0.0
jinja2
[dev]
tox
coverage
lxml
-elementpath<4.0.0,>=3.0.0
+elementpath<5.0.0,>=4.0.0
memory_profiler
Sphinx
sphinx_rtd_theme
@@ -18,7 +18,7 @@
lxml-stubs
[docs]
-elementpath<4.0.0,>=3.0.0
+elementpath<5.0.0,>=4.0.0
Sphinx
sphinx_rtd_theme
jinja2