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 2021-07-10 22:53:34
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-xmlschema (Old)
and /work/SRC/openSUSE:Factory/.python-xmlschema.new.2625 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-xmlschema"
Sat Jul 10 22:53:34 2021 rev:14 rq:900664 version:1.6.4
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-xmlschema/python-xmlschema.changes
2021-05-20 19:23:55.542224931 +0200
+++
/work/SRC/openSUSE:Factory/.python-xmlschema.new.2625/python-xmlschema.changes
2021-07-10 22:53:37.500164889 +0200
@@ -1,0 +2,14 @@
+Thu Jun 17 21:22:48 UTC 2021 - Dirk M??ller <[email protected]>
+
+- update to 1.6.4:
+ * Add testing config for Python 3.10 (Tox and CI)
+ * Fix internal _PurePath class with Python 3.10 (issue #251)
+ * Remove redundant xmlns="" declaration when encoding with lxml (issue #252)
+ * Refactor normalize_url() using pathlib.PurePath
+ * Support UNC paths (issue #246)
+ * Fix API docs (issue #248)
+ * Fix for issue #245 (key/keyref with dynamic types)
+ * Change default decoding of mixed content with only text to a string
+ instead of a dictionary (issue #242)
+
+-------------------------------------------------------------------
Old:
----
xmlschema-1.6.1.tar.gz
New:
----
xmlschema-1.6.4.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-xmlschema.spec ++++++
--- /var/tmp/diff_new_pack.f9GNJ7/_old 2021-07-10 22:53:38.012160938 +0200
+++ /var/tmp/diff_new_pack.f9GNJ7/_new 2021-07-10 22:53:38.012160938 +0200
@@ -19,7 +19,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%define skip_python2 1
Name: python-xmlschema
-Version: 1.6.1
+Version: 1.6.4
Release: 0
Summary: An XML Schema validator and decoder
License: MIT
++++++ xmlschema-1.6.1.tar.gz -> xmlschema-1.6.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/CHANGELOG.rst
new/xmlschema-1.6.4/CHANGELOG.rst
--- old/xmlschema-1.6.1/CHANGELOG.rst 2021-04-11 22:19:21.000000000 +0200
+++ new/xmlschema-1.6.4/CHANGELOG.rst 2021-06-09 19:22:21.000000000 +0200
@@ -2,6 +2,24 @@
CHANGELOG
*********
+`v1.6.4`_ (2021-06-09)
+======================
+* Add testing config for Python 3.10 (Tox and CI)
+* Fix internal _PurePath class with Python 3.10 (issue #251)
+* Remove redundant xmlns="" declaration when encoding with lxml (issue #252)
+
+`v1.6.3`_ (2021-06-07)
+======================
+* Refactor normalize_url() using pathlib.PurePath
+* Support UNC paths (issue #246)
+* Fix API docs (issue #248)
+
+`v1.6.2`_ (2021-05-03)
+======================
+* Fix for issue #245 (key/keyref with dynamic types)
+* Change default decoding of mixed content with only text to a string
+ instead of a dictionary (issue #242)
+
`v1.6.1`_ (2021-04-11)
======================
* Add multi-source initialization and add_schema() to schema class
@@ -436,3 +454,6 @@
.. _v1.5.3: https://github.com/brunato/xmlschema/compare/v1.5.2...v1.5.3
.. _v1.6.0: https://github.com/brunato/xmlschema/compare/v1.5.3...v1.6.0
.. _v1.6.1: https://github.com/brunato/xmlschema/compare/v1.6.0...v1.6.1
+.. _v1.6.2: https://github.com/brunato/xmlschema/compare/v1.6.1...v1.6.2
+.. _v1.6.3: https://github.com/brunato/xmlschema/compare/v1.6.2...v1.6.3
+.. _v1.6.4: https://github.com/brunato/xmlschema/compare/v1.6.3...v1.6.4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/PKG-INFO new/xmlschema-1.6.4/PKG-INFO
--- old/xmlschema-1.6.1/PKG-INFO 2021-04-11 23:17:40.207514000 +0200
+++ new/xmlschema-1.6.4/PKG-INFO 2021-06-09 19:41:05.674031300 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: xmlschema
-Version: 1.6.1
+Version: 1.6.4
Summary: An XML Schema validator and decoder
Home-page: https://github.com/sissaschool/xmlschema
Author: Davide Brunato
@@ -181,6 +181,7 @@
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Software Development :: Libraries
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/doc/api.rst
new/xmlschema-1.6.4/doc/api.rst
--- old/xmlschema-1.6.1/doc/api.rst 2021-04-06 13:18:03.000000000 +0200
+++ new/xmlschema-1.6.4/doc/api.rst 2021-06-07 09:43:37.000000000 +0200
@@ -59,7 +59,9 @@
.. autoattribute:: root
.. automethod:: get_text
+ .. autoattribute:: name
.. autoattribute:: url
+ .. autoattribute:: base_url
.. autoattribute:: tag
.. autoattribute:: id
@@ -69,9 +71,6 @@
.. autoattribute:: no_namespace_schema_location
.. autoattribute:: target_prefix
.. autoattribute:: default_namespace
- .. autoattribute:: name
- .. autoattribute:: url
- .. autoattribute:: base_url
.. autoattribute:: root_elements
.. autoattribute:: simple_types
.. autoattribute:: complex_types
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/doc/conf.py
new/xmlschema-1.6.4/doc/conf.py
--- old/xmlschema-1.6.1/doc/conf.py 2021-04-11 22:19:21.000000000 +0200
+++ new/xmlschema-1.6.4/doc/conf.py 2021-06-09 19:22:21.000000000 +0200
@@ -65,7 +65,7 @@
# The short X.Y version.
version = '1.6'
# The full version, including alpha/beta/rc tags.
-release = '1.6.1'
+release = '1.6.4'
# 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.6.1/requirements-dev.txt
new/xmlschema-1.6.4/requirements-dev.txt
--- old/xmlschema-1.6.1/requirements-dev.txt 2021-04-05 23:38:16.000000000
+0200
+++ new/xmlschema-1.6.4/requirements-dev.txt 2021-05-03 13:37:57.000000000
+0200
@@ -2,7 +2,7 @@
setuptools
tox
coverage
-elementpath>=2.2.1, <3.0.0
+elementpath>=2.2.2, <3.0.0
lxml
memory_profiler
Sphinx
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/setup.py new/xmlschema-1.6.4/setup.py
--- old/xmlschema-1.6.1/setup.py 2021-04-11 22:19:21.000000000 +0200
+++ new/xmlschema-1.6.4/setup.py 2021-06-09 19:22:21.000000000 +0200
@@ -9,14 +9,16 @@
# @author Davide Brunato <[email protected]>
#
from setuptools import setup, find_packages
+from pathlib import Path
-with open("README.rst") as readme:
+
+with Path(__file__).parent.joinpath('README.rst').open() as readme:
long_description = readme.read()
setup(
name='xmlschema',
- version='1.6.1',
+ version='1.6.4',
packages=find_packages(include=['xmlschema', 'xmlschema.*']),
include_package_data=True,
entry_points={
@@ -27,12 +29,12 @@
]
},
python_requires='>=3.6',
- install_requires=['elementpath>=2.2.1, <3.0.0'],
+ install_requires=['elementpath>=2.2.2, <3.0.0'],
extras_require={
- 'codegen': ['elementpath>=2.2.1, <3.0.0', 'jinja2'],
- 'dev': ['tox', 'coverage', 'lxml', 'elementpath>=2.2.1, <3.0.0',
+ 'codegen': ['elementpath>=2.2.2, <3.0.0', 'jinja2'],
+ 'dev': ['tox', 'coverage', 'lxml', 'elementpath>=2.2.2, <3.0.0',
'memory_profiler', 'Sphinx', 'sphinx_rtd_theme', 'jinja2'],
- 'docs': ['elementpath>=2.1.2, <3.0.0', 'Sphinx', 'sphinx_rtd_theme',
'jinja2']
+ 'docs': ['elementpath>=2.2.2, <3.0.0', 'Sphinx', 'sphinx_rtd_theme',
'jinja2']
},
author='Davide Brunato',
author_email='[email protected]',
@@ -55,6 +57,7 @@
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Software Development :: Libraries',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/xmlschema-1.6.1/tests/test_cases/issues/issue_243/issue_243.xml
new/xmlschema-1.6.4/tests/test_cases/issues/issue_243/issue_243.xml
--- old/xmlschema-1.6.1/tests/test_cases/issues/issue_243/issue_243.xml
1970-01-01 01:00:00.000000000 +0100
+++ new/xmlschema-1.6.4/tests/test_cases/issues/issue_243/issue_243.xml
2021-05-03 13:37:57.000000000 +0200
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<manifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.test.com/XMLSchema/manifest/2021">
+ <session anonymous="true">
+ <userId xsi:nil="true"/>
+ <sessionId xsi:nil="true"/>
+ </session>
+</manifest>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/xmlschema-1.6.1/tests/test_cases/issues/issue_243/issue_243.xsd
new/xmlschema-1.6.4/tests/test_cases/issues/issue_243/issue_243.xsd
--- old/xmlschema-1.6.1/tests/test_cases/issues/issue_243/issue_243.xsd
1970-01-01 01:00:00.000000000 +0100
+++ new/xmlschema-1.6.4/tests/test_cases/issues/issue_243/issue_243.xsd
2021-05-03 13:37:57.000000000 +0200
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
elementFormDefault="qualified"
+ attributeFormDefault="unqualified" vc:minVersion="1.1"
+ xmlns:am="http://www.test.com/XMLSchema/manifest/2021"
+ targetNamespace="http://www.test.com/XMLSchema/manifest/2021"
+ xmlns="http://www.test.com/XMLSchema/manifest/2021">
+ <xs:element name="manifest">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="session">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="userId" nillable="true">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ <xs:element name="sessionId" nillable="true">
+ <xs:simpleType>
+ <xs:restriction base="xs:integer">
+ <xs:minInclusive value="0"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="anonymous" type="xs:boolean"
use="required">
+ </xs:attribute>
+ <xs:assert
+ test="((@anonymous eq true()) and
am:userId[@xsi:nil] and am:sessionId[@xsi:nil]) or ((@anonymous eq false()) and
am:userId[node()] and am:sessionId[node()])"
+ />
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/xmlschema-1.6.1/tests/test_cases/issues/issue_245/issue_245-valid.xml
new/xmlschema-1.6.4/tests/test_cases/issues/issue_245/issue_245-valid.xml
--- old/xmlschema-1.6.1/tests/test_cases/issues/issue_245/issue_245-valid.xml
1970-01-01 01:00:00.000000000 +0100
+++ new/xmlschema-1.6.4/tests/test_cases/issues/issue_245/issue_245-valid.xml
2021-05-03 13:37:57.000000000 +0200
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<assessment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
+ xmlns="http://www.test.com/XMLSchema/data/2021"
+ xsi:schemaLocation="http://www.test.com/XMLSchema/data/2021 issue_245.xsd">
+ <part xsi:type="ContrastVisionTest">
+ <screen_elements>
+ <contrast_circles>
+ <circle circle_id="1"/>
+ <circle circle_id="0"/>
+ <circle circle_id="2"/>
+ </contrast_circles>
+ </screen_elements>
+ <events>
+ <circle_pressed circle_id="0"/>
+ <circle_pressed circle_id="1"/>
+ <circle_pressed circle_id="2"/>
+ </events>
+ </part>
+</assessment>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/xmlschema-1.6.1/tests/test_cases/issues/issue_245/issue_245.xml
new/xmlschema-1.6.4/tests/test_cases/issues/issue_245/issue_245.xml
--- old/xmlschema-1.6.1/tests/test_cases/issues/issue_245/issue_245.xml
1970-01-01 01:00:00.000000000 +0100
+++ new/xmlschema-1.6.4/tests/test_cases/issues/issue_245/issue_245.xml
2021-05-03 13:37:57.000000000 +0200
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<assessment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
+ xmlns="http://www.test.com/XMLSchema/data/2021"
+ xsi:schemaLocation="http://www.test.com/XMLSchema/data/2021 issue_245.xsd">
+ <part xsi:type="ContrastVisionTest">
+ <screen_elements>
+ <contrast_circles>
+ <circle circle_id="1"/>
+ <circle circle_id="1"/>
+ <circle circle_id="2"/>
+ </contrast_circles>
+ </screen_elements>
+ <events>
+ <circle_pressed circle_id="0"/>
+ <circle_pressed circle_id="1"/>
+ <circle_pressed circle_id="2"/>
+ </events>
+ </part>
+</assessment>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/xmlschema-1.6.1/tests/test_cases/issues/issue_245/issue_245.xsd
new/xmlschema-1.6.4/tests/test_cases/issues/issue_245/issue_245.xsd
--- old/xmlschema-1.6.1/tests/test_cases/issues/issue_245/issue_245.xsd
1970-01-01 01:00:00.000000000 +0100
+++ new/xmlschema-1.6.4/tests/test_cases/issues/issue_245/issue_245.xsd
2021-05-03 13:37:57.000000000 +0200
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
elementFormDefault="qualified"
+ attributeFormDefault="unqualified" vc:minVersion="1.1"
+ targetNamespace="http://www.test.com/XMLSchema/data/2021"
+ xmlns="http://www.test.com/XMLSchema/data/2021"
+ xmlns:ad="http://www.test.com/XMLSchema/data/2021">
+ <xs:element name="assessment">
+ <xs:annotation>
+ <xs:documentation>Data about the performed
tests.</xs:documentation>
+ </xs:annotation>
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element maxOccurs="unbounded" minOccurs="0" name="part"
type="AssessmentPart">
+ <xs:key name="circle_id_key">
+ <xs:annotation>
+ <xs:documentation>For ContrastVisionTest.
+
+Since all parts are types we can not add keys and keyrefs to them. As such, we
add the constraints here.</xs:documentation>
+ </xs:annotation>
+ <xs:selector
xpath="ad:screen_elements/ad:contrast_circles/ad:circle"/>
+ <xs:field xpath="@circle_id"/>
+ </xs:key>
+ <xs:keyref name="circle_id_keyref" refer="circle_id_key">
+ <xs:selector xpath="ad:events/ad:circle_pressed"/>
+ <xs:field xpath="@circle_id"/>
+ </xs:keyref>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:complexType abstract="true" name="AssessmentPart">
+ <xs:annotation>
+ <xs:documentation>Base type for the assessment
element.</xs:documentation>
+ </xs:annotation>
+ </xs:complexType>
+ <xs:complexType abstract="true" name="AssessmentTest">
+ <xs:annotation>
+ <xs:documentation>Base type for a test.</xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="AssessmentPart"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="ContrastVisionTest">
+ <xs:complexContent>
+ <xs:extension base="AssessmentTest">
+ <xs:sequence>
+ <xs:element name="screen_elements">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="contrast_circles">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element maxOccurs="3"
name="circle" minOccurs="3">
+ <xs:complexType>
+ <xs:attribute
name="circle_id" use="required">
+ <xs:annotation>
+ <xs:documentation>The id of
this circle, used to reference the circle presses.</xs:documentation>
+ </xs:annotation>
+ <xs:simpleType>
+ <xs:restriction
base="xs:integer">
+ <xs:minInclusive value="0"/>
+ <xs:maxInclusive value="9"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="events">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element maxOccurs="unbounded" minOccurs="0"
+ name="circle_pressed">
+ <xs:complexType>
+ <xs:attribute name="circle_id"
type="xs:integer"
+ use="required"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+</xs:schema>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/tests/test_cases/testfiles
new/xmlschema-1.6.4/tests/test_cases/testfiles
--- old/xmlschema-1.6.1/tests/test_cases/testfiles 2021-04-06
13:18:03.000000000 +0200
+++ new/xmlschema-1.6.4/tests/test_cases/testfiles 2021-05-03
13:37:57.000000000 +0200
@@ -122,3 +122,6 @@
issues/issue_222/issue_222.xml -L '' issue_222.xsd
issues/issue_223/issue_223.xsd
issues/issue_223/issue_223.xml -L '' issue_223.xsd --errors=1 # pattern
matching with \n ending
+issues/issue_243/issue_243.xml --version=1.1 -L '' issue_243.xsd
+issues/issue_245/issue_245.xml --version=1.1 --errors=2 # duplicated key
value with xsi:type
+issues/issue_245/issue_245-valid.xml --version=1.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/tests/test_resources.py
new/xmlschema-1.6.4/tests/test_resources.py
--- old/xmlschema-1.6.1/tests/test_resources.py 2021-04-11 22:40:23.000000000
+0200
+++ new/xmlschema-1.6.4/tests/test_resources.py 2021-06-09 19:22:21.000000000
+0200
@@ -31,6 +31,7 @@
fetch_schema, fetch_schema_locations, XMLResource, XMLResourceError,
XMLSchema
from xmlschema.etree import ElementTree, etree_element, py_etree_element,
is_etree_element
from xmlschema.names import XSD_NAMESPACE
+import xmlschema.resources
from xmlschema.resources import is_url, is_local_url, is_remote_url, \
url_path_is_file, normalize_locations, LazySelector
from xmlschema.testing import SKIP_REMOTE_TESTS
@@ -38,6 +39,8 @@
TEST_CASES_DIR =
str(pathlib.Path(__file__).absolute().parent.joinpath('test_cases'))
+DRIVE_PATH = '/C:' if platform.system() == 'Windows' else ''
+
def casepath(relative_path):
return str(pathlib.Path(TEST_CASES_DIR).joinpath(relative_path))
@@ -97,6 +100,46 @@
expected_path = PurePath(expected_parts.path)
self.assertEqual(path, expected_path, "%r: Paths differ." % url)
+ def test_path_from_uri(self):
+ _PurePath = xmlschema.resources._PurePath
+ _PosixPurePath = xmlschema.resources._PosixPurePath
+ _WindowsPurePath = xmlschema.resources._WindowsPurePath
+
+ with self.assertRaises(ValueError) as ec:
+ _PurePath.from_uri('')
+ self.assertEqual(str(ec.exception), 'Empty URI provided!')
+
+ path = _PurePath.from_uri('https://example.com/names/?name=foo')
+ self.assertIsInstance(path, _PosixPurePath)
+ self.assertEqual(str(path), '/names')
+
+ path = _PosixPurePath.from_uri('file:///home/foo/names/?name=foo')
+ self.assertIsInstance(path, _PosixPurePath)
+ self.assertEqual(str(path), '/home/foo/names')
+
+ path = _PosixPurePath.from_uri('file:///home/foo/names#foo')
+ self.assertIsInstance(path, _PosixPurePath)
+ self.assertEqual(str(path), '/home/foo/names')
+
+ path = _PosixPurePath.from_uri('file:///home\\foo\\names#foo')
+ self.assertIsInstance(path, _WindowsPurePath)
+ self.assertTrue(path.as_posix().endswith('/home/foo/names'))
+
+ path = _PosixPurePath.from_uri('file:///c:/home/foo/names/')
+ self.assertIsInstance(path, _WindowsPurePath)
+ self.assertEqual(str(path), r'c:\home\foo\names')
+ self.assertEqual(path.as_uri(), 'file:///c:/home/foo/names')
+
+ path = _PosixPurePath.from_uri('file:c:/home/foo/names/')
+ self.assertIsInstance(path, _WindowsPurePath)
+ self.assertEqual(str(path), r'c:\home\foo\names')
+ self.assertEqual(path.as_uri(), 'file:///c:/home/foo/names')
+
+ with self.assertRaises(ValueError) as ec:
+ _PurePath.from_uri('file://c:/home/foo/names/')
+ self.assertEqual(str(ec.exception), "Invalid URI
'file://c:/home/foo/names/'")
+
+ @unittest.skipIf(platform.system() == 'Windows', "Run only on posix
systems")
def test_normalize_url_posix(self):
url1 = "https://example.com/xsd/other_schema.xsd"
self.check_url(normalize_url(url1,
base_url="/path_my_schema/schema.xsd"), url1)
@@ -114,19 +157,20 @@
cwd = os.getcwd()
cwd_url = 'file://{}/'.format(cwd) if cwd.startswith('/') else
'file:///{}/'.format(cwd)
+ self.check_url(normalize_url('other.xsd', keep_relative=True),
'file:other.xsd')
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')
+ self.check_url(normalize_url('file:other.xsd', 'https://site/base',
True), 'file:other.xsd')
self.check_url(normalize_url('file:other.xsd', 'http://site/base'),
cwd_url + 'other.xsd')
- self.check_url(normalize_url('dummy path.xsd'), cwd_url + 'dummy
path.xsd')
+ self.check_url(normalize_url('dummy path.xsd'), cwd_url +
'dummy%20path.xsd')
self.check_url(normalize_url('dummy path.xsd', 'http://site/base'),
'http://site/base/dummy%20path.xsd')
self.check_url(normalize_url('dummy path.xsd', 'file://host/home/'),
- 'file://host/home/dummy path.xsd')
+ PurePath('//host/home/dummy path.xsd').as_uri())
- url = "file://c:/Downloads/file.xsd"
- self.check_url(normalize_url(url, base_url="file://d:/Temp/"), url)
+ url = "file:///c:/Downloads/file.xsd"
+ self.check_url(normalize_url(url, base_url="file:///d:/Temp/"), url)
def test_normalize_url_windows(self):
win_abs_path1 = 'z:\\Dir_1_0\\Dir2-0\\schemas/XSD_1.0/XMLSchema.xsd'
@@ -134,42 +178,58 @@
self.check_url(normalize_url(win_abs_path1), win_abs_path1)
self.check_url(normalize_url('k:\\Dir3\\schema.xsd', win_abs_path1),
- 'file:///k:\\Dir3\\schema.xsd')
+ 'file:///k:/Dir3/schema.xsd')
self.check_url(normalize_url('k:\\Dir3\\schema.xsd', win_abs_path2),
- 'file:///k:\\Dir3\\schema.xsd')
+ 'file:///k:/Dir3/schema.xsd')
+
self.check_url(normalize_url('schema.xsd', win_abs_path2),
- 'file:///z:\\Dir-1.0\\Dir-2_0/schema.xsd')
+ 'file:///z:/Dir-1.0/Dir-2_0/schema.xsd')
self.check_url(normalize_url('xsd1.0/schema.xsd', win_abs_path2),
- 'file:///z:\\Dir-1.0\\Dir-2_0/xsd1.0/schema.xsd')
- self.check_url(normalize_url('file:///\\k:\\Dir A\\schema.xsd'),
- 'file:///k:\\Dir A\\schema.xsd')
+ 'file:///z:/Dir-1.0/Dir-2_0/xsd1.0/schema.xsd')
+
+ with self.assertRaises(ValueError) as ec:
+ normalize_url('file:///\\k:\\Dir A\\schema.xsd')
+ self.assertIn("Invalid URI", str(ec.exception))
+
+ def test_normalize_url_unc_paths__issue_246(self):
+ url = PureWindowsPath(r'\\host\share\file.xsd').as_uri()
+ self.assertEqual(normalize_url(r'\\host\share\file.xsd'), url) #
file://host/share/file.xsd
def test_normalize_url_slashes(self):
# Issue #116
- self.assertEqual(
- normalize_url('//anaconda/envs/testenv/lib/python3.6/'
- 'site-packages/xmlschema/validators/schemas/'),
- 'file:///anaconda/envs/testenv/lib/python3.6/'
- 'site-packages/xmlschema/validators/schemas/'
- )
- self.assertEqual(normalize_url('/root/dir1/schema.xsd'),
'file:///root/dir1/schema.xsd')
- self.assertEqual(normalize_url('//root/dir1/schema.xsd'),
'file:///root/dir1/schema.xsd')
- self.assertEqual(normalize_url('////root/dir1/schema.xsd'),
'file:///root/dir1/schema.xsd')
-
- self.assertEqual(normalize_url('dir2/schema.xsd', '//root/dir1/'),
- 'file:///root/dir1/dir2/schema.xsd')
- self.assertEqual(normalize_url('dir2/schema.xsd', '//root/dir1'),
- 'file:///root/dir1/dir2/schema.xsd')
+ url =
'//anaconda/envs/testenv/lib/python3.6/site-packages/xmlschema/validators/schemas/'
+ self.assertEqual(normalize_url(url), pathlib.PurePath(url).as_uri())
+ self.assertEqual(normalize_url('/root/dir1/schema.xsd'),
+ f'file://{DRIVE_PATH}/root/dir1/schema.xsd')
+
+ self.assertEqual(normalize_url('////root/dir1/schema.xsd'),
+ f'file://{DRIVE_PATH}/root/dir1/schema.xsd')
self.assertEqual(normalize_url('dir2/schema.xsd', '////root/dir1'),
- 'file:///root/dir1/dir2/schema.xsd')
+ f'file://{DRIVE_PATH}/root/dir1/dir2/schema.xsd')
+
+ if platform.system() == 'Windows':
+ # On Windows // is interpreted as a network share UNC path
+ self.assertEqual(normalize_url('//root/dir1/schema.xsd'),
+ 'file://root/dir1/schema.xsd')
+ self.assertEqual(normalize_url('dir2/schema.xsd', '//root/dir1/'),
+ f'file://root/dir1/dir2/schema.xsd')
+ self.assertEqual(normalize_url('dir2/schema.xsd', '//root/dir1'),
+ f'file://root/dir1/dir2/schema.xsd')
+ else:
+ self.assertEqual(normalize_url('//root/dir1/schema.xsd'),
+ 'file:////root/dir1/schema.xsd')
+ self.assertEqual(normalize_url('dir2/schema.xsd', '//root/dir1/'),
+ f'file:////root/dir1/dir2/schema.xsd')
+ self.assertEqual(normalize_url('dir2/schema.xsd', '//root/dir1'),
+ f'file:////root/dir1/dir2/schema.xsd')
def test_normalize_url_hash_character(self):
self.check_url(normalize_url('issue #000.xml', 'file:///dir1/dir2/'),
- 'file:///dir1/dir2/issue %23000.xml')
- self.check_url(normalize_url('data.xml', 'file:///dir1/dir2/issue
000'),
- 'file:///dir1/dir2/issue 000/data.xml')
- self.check_url(normalize_url('data.xml', '/dir1/dir2/issue #000'),
- '/dir1/dir2/issue %23000/data.xml')
+ f'file://{DRIVE_PATH}/dir1/dir2/issue%20%23000.xml')
+ self.check_url(normalize_url('data.xml',
'file:///dir1/dir2/issue%20001'),
+ f'file://{DRIVE_PATH}/dir1/dir2/issue%20001/data.xml')
+ self.check_url(normalize_url('data.xml', '/dir1/dir2/issue #002'),
+ f'{DRIVE_PATH}/dir1/dir2/issue%20%23002/data.xml')
def test_is_url_function(self):
self.assertTrue(is_url(self.col_xsd_file))
@@ -209,20 +269,20 @@
locations = normalize_locations(
[('tns0', 'alpha'), ('tns1', 'http://example.com/beta')],
base_url='/home/user'
)
- self.assertListEqual(locations, [('tns0', 'file:///home/user/alpha'),
+ self.assertListEqual(locations, [('tns0',
f'file://{DRIVE_PATH}/home/user/alpha'),
('tns1', 'http://example.com/beta')])
locations = normalize_locations(
{'tns0': 'alpha', 'tns1': 'http://example.com/beta'},
base_url='/home/user'
)
- self.assertListEqual(locations, [('tns0', 'file:///home/user/alpha'),
+ self.assertListEqual(locations, [('tns0',
f'file://{DRIVE_PATH}/home/user/alpha'),
('tns1', 'http://example.com/beta')])
locations = normalize_locations(
{'tns0': ['alpha', 'beta'], 'tns1': 'http://example.com/beta'},
base_url='/home/user'
)
- self.assertListEqual(locations, [('tns0', 'file:///home/user/alpha'),
- ('tns0', 'file:///home/user/beta'),
+ self.assertListEqual(locations, [('tns0',
f'file://{DRIVE_PATH}/home/user/alpha'),
+ ('tns0',
f'file://{DRIVE_PATH}/home/user/beta'),
('tns1', 'http://example.com/beta')])
locations = normalize_locations(
@@ -243,16 +303,16 @@
self.assertRaises(XMLResourceError, fetch_resource, wrong_path)
right_path = casepath('resources/dummy file.txt')
- self.assertTrue(fetch_resource(right_path).endswith('dummy file.txt'))
+
self.assertTrue(fetch_resource(right_path).endswith('dummy%20file.txt'))
right_path = Path(casepath('resources/dummy
file.txt')).relative_to(os.getcwd())
- self.assertTrue(fetch_resource(str(right_path),
'/home').endswith('dummy file.txt'))
+ self.assertTrue(fetch_resource(str(right_path),
'/home').endswith('dummy%20file.txt'))
with self.assertRaises(XMLResourceError):
fetch_resource(str(right_path.parent.joinpath('dummy_file.txt')),
'/home')
ambiguous_path = casepath('resources/dummy file #2.txt')
- self.assertTrue(fetch_resource(ambiguous_path).endswith('dummy file
%232.txt'))
+
self.assertTrue(fetch_resource(ambiguous_path).endswith('dummy%20file%20%232.txt'))
with urlopen(fetch_resource(ambiguous_path)) as res:
self.assertEqual(res.read(), b'DUMMY CONTENT')
@@ -736,7 +796,10 @@
resource = XMLResource(self.vh_xml_file)
resource.close()
xml_file = resource.open()
- self.assertTrue(callable(xml_file.read))
+ try:
+ self.assertTrue(callable(xml_file.read))
+ finally:
+ resource.close()
with open(self.vh_xml_file) as xml_file:
resource = XMLResource(source=xml_file)
@@ -1082,11 +1145,11 @@
resource = XMLResource(source)
locations = resource.get_locations()
- self.assertListEqual(locations, [('http://example.com/ns1',
'file:///loc1'),
- ('http://example.com/ns2',
'file:///loc2')])
+ self.assertListEqual(locations, [('http://example.com/ns1',
f'file://{DRIVE_PATH}/loc1'),
+ ('http://example.com/ns2',
f'file://{DRIVE_PATH}/loc2')])
locations = resource.get_locations(root_only=True)
- self.assertListEqual(locations, [('http://example.com/ns1',
'file:///loc1')])
+ self.assertListEqual(locations, [('http://example.com/ns1',
f'file://{DRIVE_PATH}/loc1')])
@unittest.skipIf(SKIP_REMOTE_TESTS or platform.system() == 'Windows',
"Remote networks are not accessible or avoid SSL "
@@ -1251,10 +1314,10 @@
self.assertIs(subresource.root, resource.root[0])
def test_loading_from_unrelated_dirs__issue_237(self):
- relpath = str(pathlib.Path(__file__).parent.joinpath(
+ relative_path = str(pathlib.Path(__file__).parent.joinpath(
'test_cases/issues/issue_237/dir1/issue_237.xsd'
))
- schema = XMLSchema(relpath)
+ schema = XMLSchema(relative_path)
self.assertEqual(schema.maps.namespaces[''][1].name, 'issue_237a.xsd')
self.assertEqual(schema.maps.namespaces[''][2].name, 'issue_237b.xsd')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/tests/validation/test_decoding.py
new/xmlschema-1.6.4/tests/validation/test_decoding.py
--- old/xmlschema-1.6.1/tests/validation/test_decoding.py 2021-04-11
22:19:21.000000000 +0200
+++ new/xmlschema-1.6.4/tests/validation/test_decoding.py 2021-05-03
13:37:57.000000000 +0200
@@ -1034,7 +1034,7 @@
data = schema.decode(self.casepath('issues/issue_204/issue_204_3.xml'),
validation='lax', keep_unknown=True)
self.assertEqual(set(x for x in data[0] if x[0] != '@'), {'child2',
'unknown', 'child5'})
- self.assertEqual(data[0]['unknown'], {'a': [{'$': '1'}], 'b': [None]})
+ self.assertEqual(data[0]['unknown'], {'a': ['1'], 'b': [None]})
data =
schema.decode(self.casepath('issues/issue_204/issue_204_2.xml'),
validation='skip')
self.assertEqual(set(x for x in data if x[0] != '@'), {'child2',
'child5'})
@@ -1042,7 +1042,7 @@
data = schema.decode(self.casepath('issues/issue_204/issue_204_3.xml'),
validation='skip', keep_unknown=True)
self.assertEqual(set(x for x in data if x[0] != '@'), {'child2',
'unknown', 'child5'})
- self.assertEqual(data['unknown'], {'a': [{'$': '1'}], 'b': [None]})
+ self.assertEqual(data['unknown'], {'a': ['1'], 'b': [None]})
def test_error_message__issue_115(self):
schema =
self.schema_class(self.casepath('issues/issue_115/Rotation.xsd'))
@@ -1111,7 +1111,7 @@
schema =
self.schema_class(self.casepath('issues/issue_190/issue_190.xsd'))
self.assertEqual(
schema.to_dict(self.casepath('issues/issue_190/issue_190.xml')),
- {'a': {'c': [{'$': '1'}]}, 'b': {'c': [{'$': '1'}], 'e': [{'$':
'1'}]}}
+ {'a': {'c': ['1']}, 'b': {'c': ['1'], 'e': ['1']}}
)
def test_issue_200(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/tests/validation/test_encoding.py
new/xmlschema-1.6.4/tests/validation/test_encoding.py
--- old/xmlschema-1.6.1/tests/validation/test_encoding.py 2021-02-11
15:32:40.000000000 +0100
+++ new/xmlschema-1.6.4/tests/validation/test_encoding.py 2021-06-09
19:22:21.000000000 +0200
@@ -13,6 +13,11 @@
import unittest
from textwrap import dedent
+try:
+ import lxml.etree as lxml_etree
+except ImportError:
+ lxml_etree = None
+
from elementpath import datatypes
from xmlschema import XMLSchemaEncodeError, XMLSchemaValidationError
@@ -568,6 +573,85 @@
self.assertIsNone(elem.text)
self.assertEqual(elem.attrib, {'b1': 'false', 'b2': 'false', 'b3':
'false'})
+ def test_encode_sub_tree(self):
+ """Test encoding data of a non-root element"""
+ data = {
+ "@id": "PAR",
+ "name": "Pierre-Auguste Renoir",
+ "born": "1841-02-25",
+ "dead": "1919-12-03",
+ "qualification": "painter",
+ }
+ elem = self.col_schema.encode(
+ data,
+ path=".//author",
+ namespaces=self.col_namespaces,
+ )
+ self.assertEqual(
+ etree_tostring(elem),
+ dedent(
+ """\
+ <author id="PAR">
+ <name>Pierre-Auguste Renoir</name>
+ <born>1841-02-25</born>
+ <dead>1919-12-03</dead>
+ <qualification>painter</qualification>
+ </author>"""
+ )
+ )
+
+ @unittest.skipIf(lxml_etree is None, "The lxml library is not available.")
+ def test_lxml_encode(self):
+ """Test encode with etree_element_class=lxml.etree.Element"""
+ xd = {
+ "@xmlns:col": "http://example.com/ns/collection",
+ "@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
+ "@xsi:schemaLocation": "http://example.com/ns/collection
collection.xsd",
+ "object": [
+ {
+ "@id": "b0836217463",
+ "@available": True,
+ "position": 2,
+ "title": None,
+ "year": "1925",
+ "author": {
+ "@id": "JM",
+ "name": "Joan Mir??",
+ "born": "1893-04-20",
+ "dead": "1983-12-25",
+ "qualification": "painter, sculptor and ceramicist",
+ },
+ },
+ ],
+ }
+
+ elem = self.col_schema.encode(
+ xd,
+ path="./col:collection",
+ namespaces=self.col_namespaces,
+ etree_element_class=lxml_etree.Element,
+ )
+
+ self.assertEqual(
+ etree_tostring(elem, namespaces=self.col_namespaces),
+ dedent(
+ """\
+ <col:collection xmlns:col="http://example.com/ns/collection"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://example.com/ns/collection collection.xsd">
+ <object id="b0836217463" available="true">
+ <position>2</position>
+ <title/>
+ <year>1925</year>
+ <author id="JM">
+ <name>Joan Mir??</name>
+ <born>1893-04-20</born>
+ <dead>1983-12-25</dead>
+ <qualification>painter, sculptor and
ceramicist</qualification>
+ </author>
+ </object>
+ </col:collection>"""
+ )
+ )
+
class TestEncoding11(TestEncoding):
schema_class = XMLSchema11
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/tox.ini new/xmlschema-1.6.4/tox.ini
--- old/xmlschema-1.6.1/tox.ini 2021-04-05 23:38:16.000000000 +0200
+++ new/xmlschema-1.6.4/tox.ini 2021-06-08 11:20:00.000000000 +0200
@@ -4,16 +4,16 @@
# and then run "tox" from this directory.
[tox]
-envlist = py{36,37,38,39}, pypy3, ep221, docs, flake8, coverage
+envlist = py{36,37,38,39,310}, pypy3, ep222, docs, flake8, coverage
skip_missing_interpreters = true
toxworkdir = {homedir}/.tox/xmlschema
[testenv]
deps =
- elementpath>=2.2.1, <3.0.0
+ elementpath>=2.2.2, <3.0.0
lxml
jinja2
- py{37,38,39}: memory_profiler
+ py{38,39}: memory_profiler
docs: Sphinx
docs: sphinx_rtd_theme
flake8: flake8
@@ -35,9 +35,9 @@
[testenv:pypy3]
commands = python -m unittest
-[testenv:ep221]
+[testenv:ep222]
deps =
- elementpath==2.2.1
+ elementpath==2.2.2
lxml
[testenv:docs]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/xmlschema/__init__.py
new/xmlschema-1.6.4/xmlschema/__init__.py
--- old/xmlschema-1.6.1/xmlschema/__init__.py 2021-04-11 22:19:21.000000000
+0200
+++ new/xmlschema-1.6.4/xmlschema/__init__.py 2021-06-09 19:22:21.000000000
+0200
@@ -30,7 +30,7 @@
XsdComponent, XsdType, XsdElement, XsdAttribute
)
-__version__ = '1.6.1'
+__version__ = '1.6.4'
__author__ = "Davide Brunato"
__contact__ = "[email protected]"
__copyright__ = "Copyright 2016-2021, SISSA"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/xmlschema/converters/abdera.py
new/xmlschema-1.6.4/xmlschema/converters/abdera.py
--- old/xmlschema-1.6.1/xmlschema/converters/abdera.py 2021-02-11
15:32:40.000000000 +0100
+++ new/xmlschema-1.6.4/xmlschema/converters/abdera.py 2021-06-07
11:47:24.000000000 +0200
@@ -24,6 +24,8 @@
:param dict_class: Dictionary class to use for decoded data. Default is
`dict`.
:param list_class: List class to use for decoded data. Default is `list`.
"""
+ __slots__ = ()
+
def __init__(self, namespaces=None, dict_class=None, list_class=None,
**kwargs):
kwargs.update(attr_prefix='', text_key='', cdata_prefix=None)
super(AbderaConverter, self).__init__(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/xmlschema/converters/badgerfish.py
new/xmlschema-1.6.4/xmlschema/converters/badgerfish.py
--- old/xmlschema-1.6.1/xmlschema/converters/badgerfish.py 2021-02-11
15:32:40.000000000 +0100
+++ new/xmlschema-1.6.4/xmlschema/converters/badgerfish.py 2021-06-07
11:47:24.000000000 +0200
@@ -23,6 +23,8 @@
:param dict_class: Dictionary class to use for decoded data. Default is
`dict`.
:param list_class: List class to use for decoded data. Default is `list`.
"""
+ __slots__ = ()
+
def __init__(self, namespaces=None, dict_class=None, list_class=None,
**kwargs):
kwargs.update(attr_prefix='@', text_key='$', cdata_prefix='$')
super(BadgerFishConverter, self).__init__(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/xmlschema/converters/columnar.py
new/xmlschema-1.6.4/xmlschema/converters/columnar.py
--- old/xmlschema-1.6.1/xmlschema/converters/columnar.py 2021-02-11
15:32:40.000000000 +0100
+++ new/xmlschema-1.6.4/xmlschema/converters/columnar.py 2021-06-07
11:47:24.000000000 +0200
@@ -23,6 +23,8 @@
:param attr_prefix: used as separator string for renaming the decoded
attributes. \
Can be the empty string (the default) or a single/double underscore.
"""
+ __slots__ = ()
+
def __init__(self, namespaces=None, dict_class=None, list_class=None,
attr_prefix='', **kwargs):
kwargs.update(text_key=None, cdata_prefix=None)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/xmlschema/converters/default.py
new/xmlschema-1.6.4/xmlschema/converters/default.py
--- old/xmlschema-1.6.1/xmlschema/converters/default.py 2021-02-11
15:32:40.000000000 +0100
+++ new/xmlschema-1.6.4/xmlschema/converters/default.py 2021-06-09
11:27:09.000000000 +0200
@@ -55,12 +55,13 @@
:param strip_namespaces: if set to `True` removes namespace declarations
from data and \
namespace information from names, during decoding or encoding. Defaults to
`False`.
:param preserve_root: if set to `True` the root element is preserved,
wrapped into a \
- single-item dictionary. Applicable only to default converter and to
:class:`ParkerConverter`.
+ single-item dictionary. Applicable only to default converter, to \
+ :class:`UnorderedConverter` and to :class:`ParkerConverter`.
:param force_dict: if set to `True` complex elements with simple content
are decoded \
- with a dictionary also if there are no decoded attributes. Applicable to
default converter \
- only. Defaults to `False`.
+ with a dictionary also if there are no decoded attributes. Applicable only
to default \
+ converter and to :class:`UnorderedConverter`. Defaults to `False`.
:param force_list: if set to `True` child elements are decoded within a
list in any case. \
- Applicable to default converter only. Defaults to `False`.
+ Applicable only to default converter and to :class:`UnorderedConverter`.
Defaults to `False`.
:ivar dict: dictionary class to use for decoded data.
:ivar list: list class to use for decoded data.
@@ -77,7 +78,9 @@
dict = dict
list = list
etree_element_class = etree_element
- ns_prefix = None
+
+ __slots__ = ('text_key', 'ns_prefix', 'attr_prefix', 'cdata_prefix',
+ 'indent', 'preserve_root', 'force_dict', 'force_list')
def __init__(self, namespaces=None, dict_class=None, list_class=None,
etree_element_class=None, text_key='$', attr_prefix='@',
@@ -93,6 +96,7 @@
if etree_element_class is not None:
self.etree_element_class = etree_element_class
+ self.ns_prefix = None
self.text_key = text_key
self.attr_prefix = attr_prefix
self.cdata_prefix = cdata_prefix
@@ -221,7 +225,8 @@
else:
elem = self.etree_element_class(tag, self.dict(attrib))
else:
- nsmap = {prefix if prefix else None: uri for prefix, uri in
self._namespaces.items()}
+ nsmap = {prefix if prefix else None: uri
+ for prefix, uri in self._namespaces.items() if uri}
elem = self.etree_element_class(tag, nsmap=nsmap)
elem.attrib.update(attrib)
@@ -294,7 +299,12 @@
return self.dict(
[(self.map_qname(data.tag), result_dict if result_dict
else None)]
)
- return result_dict if result_dict else None
+
+ if not result_dict:
+ return None
+ elif len(result_dict) == 1 and self.text_key in result_dict:
+ return result_dict[self.text_key]
+ return result_dict
def element_encode(self, obj, xsd_element, level=0):
"""
@@ -308,7 +318,10 @@
if level != 0:
tag = xsd_element.name
else:
- tag = xsd_element.qualified_name
+ if xsd_element.is_global():
+ tag = xsd_element.qualified_name
+ else:
+ tag = xsd_element.name
if self.preserve_root and isinstance(obj, MutableMapping):
match_local_name = self.strip_namespaces or
self.default_namespace
match = xsd_element.get_matching_item(obj, self.ns_prefix,
match_local_name)
@@ -318,8 +331,8 @@
if not isinstance(obj, MutableMapping):
if xsd_element.type.simple_type is not None:
return ElementData(tag, obj, None, {})
- elif xsd_element.type.mixed and not isinstance(obj,
MutableSequence):
- return ElementData(tag, obj, None, {})
+ elif xsd_element.type.mixed and isinstance(obj, (str, bytes)):
+ return ElementData(tag, None, [(1, obj)], {})
else:
return ElementData(tag, None, obj, {})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/xmlschema/converters/jsonml.py
new/xmlschema-1.6.4/xmlschema/converters/jsonml.py
--- old/xmlschema-1.6.1/xmlschema/converters/jsonml.py 2021-02-11
15:32:40.000000000 +0100
+++ new/xmlschema-1.6.4/xmlschema/converters/jsonml.py 2021-06-07
11:47:24.000000000 +0200
@@ -24,6 +24,8 @@
:param dict_class: Dictionary class to use for decoded data. Default is
`dict`.
:param list_class: List class to use for decoded data. Default is `list`.
"""
+ __slots__ = ()
+
def __init__(self, namespaces=None, dict_class=None, list_class=None,
**kwargs):
kwargs.update(attr_prefix='', text_key='', cdata_prefix='')
super(JsonMLConverter, self).__init__(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/xmlschema/converters/parker.py
new/xmlschema-1.6.4/xmlschema/converters/parker.py
--- old/xmlschema-1.6.1/xmlschema/converters/parker.py 2021-02-11
15:32:40.000000000 +0100
+++ new/xmlschema-1.6.4/xmlschema/converters/parker.py 2021-06-07
11:47:24.000000000 +0200
@@ -25,6 +25,8 @@
:param preserve_root: If `True` the root element will be preserved. For
default \
the Parker convention remove the document root element, returning only the
value.
"""
+ __slots__ = ()
+
def __init__(self, namespaces=None, dict_class=None, list_class=None,
preserve_root=False, **kwargs):
kwargs.update(attr_prefix=None, text_key='', cdata_prefix=None)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/xmlschema/converters/unordered.py
new/xmlschema-1.6.4/xmlschema/converters/unordered.py
--- old/xmlschema-1.6.1/xmlschema/converters/unordered.py 2021-02-11
15:32:40.000000000 +0100
+++ new/xmlschema-1.6.4/xmlschema/converters/unordered.py 2021-06-07
11:47:24.000000000 +0200
@@ -22,6 +22,8 @@
As the order of the input dictionary is not preserved, character data
between sibling elements are interleaved between tags.
"""
+ __slots__ = ()
+
def element_encode(self, obj, xsd_element, level=0):
"""
Extracts XML decoded data from a data structure for encoding into an
ElementTree.
@@ -31,7 +33,7 @@
:param level: the level related to the encoding process (0 means the
root).
:return: an ElementData instance.
"""
- if level != 0:
+ if level:
tag = xsd_element.name
else:
tag = xsd_element.qualified_name
@@ -44,6 +46,8 @@
if not isinstance(obj, MutableMapping):
if xsd_element.type.simple_type is not None:
return ElementData(tag, obj, None, {})
+ elif xsd_element.type.mixed and isinstance(obj, (str, bytes)):
+ return ElementData(tag, None, [(1, obj)], {})
else:
return ElementData(tag, None, obj, {})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/xmlschema/dataobjects.py
new/xmlschema-1.6.4/xmlschema/dataobjects.py
--- old/xmlschema-1.6.1/xmlschema/dataobjects.py 2021-04-05
23:38:16.000000000 +0200
+++ new/xmlschema-1.6.4/xmlschema/dataobjects.py 2021-06-07
11:47:24.000000000 +0200
@@ -329,11 +329,10 @@
:param data_element_class: MutableSequence subclass to use for decoded
data. \
Default is `DataElement`.
"""
- data_element_class = DataElement
+ __slots__ = 'data_element_class',
def __init__(self, namespaces=None, data_element_class=None, **kwargs):
- if data_element_class is not None:
- self.data_element_class = data_element_class
+ self.data_element_class = data_element_class or DataElement
kwargs.update(attr_prefix='', text_key='', cdata_prefix='')
super(DataElementConverter, self).__init__(namespaces, **kwargs)
@@ -404,6 +403,8 @@
*data_element_class* is used for define the base for creating the missing
XML binding classes.
"""
+ __slots__ = ()
+
def element_decode(self, data, xsd_element, xsd_type=None, level=0):
cls = xsd_element.get_binding(self.data_element_class)
data_element = cls(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/xmlschema/documents.py
new/xmlschema-1.6.4/xmlschema/documents.py
--- old/xmlschema-1.6.1/xmlschema/documents.py 2021-01-23 11:58:27.000000000
+0100
+++ new/xmlschema-1.6.4/xmlschema/documents.py 2021-05-03 13:37:57.000000000
+0200
@@ -289,7 +289,8 @@
:param converter: an :class:`XMLSchemaConverter` subclass or instance to
use \
for the encoding.
:param json_options: a dictionary with options for the JSON deserializer.
- :param kwargs: Keyword arguments containing options for converter and
encoding.
+ :param kwargs: other optional arguments of :meth:`XMLSchema.iter_encode`
and \
+ options for converter.
:return: An element tree's Element instance. If ``validation='lax'``
keyword argument is \
provided the validation errors are collected and returned coupled in a
tuple with the \
Element instance.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/xmlschema/namespaces.py
new/xmlschema-1.6.4/xmlschema/namespaces.py
--- old/xmlschema-1.6.1/xmlschema/namespaces.py 2021-02-11 15:32:40.000000000
+0100
+++ new/xmlschema-1.6.4/xmlschema/namespaces.py 2021-06-07 11:47:24.000000000
+0200
@@ -26,6 +26,8 @@
lists of strings. Setting an existing value appends the string to the
value.
Setting a value with a list sets/replaces the value.
"""
+ __slots__ = ('_store',)
+
def __init__(self, *args, **kwargs):
self._store = dict()
self.update(*args, **kwargs)
@@ -70,6 +72,8 @@
:param strip_namespaces: if set to `True` uses name mapping methods that
strip \
namespace information.
"""
+ __slots__ = '_namespaces', 'strip_namespaces', '__dict__'
+
def __init__(self, namespaces=None, strip_namespaces=False):
if namespaces is None:
self._namespaces = {}
@@ -230,6 +234,8 @@
A read-only map for filtered access to a dictionary that stores
objects mapped from QNames in extended format.
"""
+ __slots__ = 'target_dict', 'namespace', '_key_fmt'
+
def __init__(self, qname_dict, namespace_uri):
self.target_dict = qname_dict
self.namespace = namespace_uri
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/xmlschema/resources.py
new/xmlschema-1.6.4/xmlschema/resources.py
--- old/xmlschema-1.6.1/xmlschema/resources.py 2021-04-11 22:19:21.000000000
+0200
+++ new/xmlschema-1.6.4/xmlschema/resources.py 2021-06-09 19:22:22.000000000
+0200
@@ -8,13 +8,14 @@
# @author Davide Brunato <[email protected]>
#
import os.path
+import pathlib
import platform
import re
-from string import ascii_letters
+import string
from elementpath import iter_select, XPath1Parser, XPathContext, XPath2Parser
from io import StringIO, BytesIO
-from urllib.request import urlopen, pathname2url
-from urllib.parse import uses_relative, urlsplit, urljoin, urlunsplit, unquote
+from urllib.request import urlopen
+from urllib.parse import urlsplit, urlunsplit, unquote, quote_from_bytes
from urllib.error import URLError
from .exceptions import XMLSchemaTypeError, XMLSchemaValueError,
XMLResourceError
@@ -35,6 +36,8 @@
'(string)', '(float)', '(decimal)', '(integer)', '@'
}
+DRIVE_LETTERS = frozenset(string.ascii_letters)
+
class LazyXPath2Parser(XPath2Parser):
symbol_table = {
@@ -73,94 +76,120 @@
###
# URL normalization (that fixes many headaches :)
+class _PurePath(pathlib.PurePath):
+ """
+ A version of pathlib.PurePath adapted for managing the creation
+ from URIs and the simple normalization of paths.
+ """
+ def __new__(cls, *args):
+ if cls is _PurePath:
+ cls = _WindowsPurePath if os.name == 'nt' else _PosixPurePath
+ return cls._from_parts(args)
+
+ @classmethod
+ def from_uri(cls, uri):
+ uri = uri.strip()
+ if not uri:
+ raise XMLSchemaValueError("Empty URI provided!")
+
+ if uri.startswith(r'\\'):
+ return _WindowsPurePath(uri) # UNC path
+ elif uri.startswith('/'):
+ return cls(uri)
+
+ parts = urlsplit(uri)
+ if not parts.scheme:
+ return cls(uri)
+ elif parts.scheme in DRIVE_LETTERS and len(parts.scheme) == 1:
+ return _WindowsPurePath(uri) # Eg. k:/Python/lib/....
+ elif parts.scheme != 'file':
+ return _PosixPurePath(unquote(parts.path))
+
+ # Get file URI path because urlsplit does not parse it well
+ start = 7 if uri.startswith('file:///') else 5
+ if parts.query:
+ path = uri[start:uri.index('?')]
+ elif parts.fragment:
+ path = uri[start:uri.index('#')]
+ else:
+ path = uri[start:]
+
+ if ':' in path:
+ # Windows path with a drive
+ pos = path.index(':')
+ if pos == 2 and path[0] == '/' and path[1] in DRIVE_LETTERS:
+ return _WindowsPurePath(unquote(path[1:]))
+
+ obj = _WindowsPurePath(unquote(path))
+ if len(obj.drive) != 2 or obj.drive[1] != ':':
+ raise XMLSchemaValueError("Invalid URI {!r}".format(uri))
+ return obj
+
+ if '\\' in path:
+ return _WindowsPurePath(unquote(path))
+ return cls(unquote(path))
+
+ def as_uri(self):
+ if not self.is_absolute():
+ uri = self._flavour.make_uri(self)
+ while uri.startswith('file:/'):
+ uri = uri.replace('file:/', 'file:', 1)
+ return uri
+ return self._flavour.make_uri(self)
+
+ def normalize(self):
+ normalized_path = self._flavour.pathmod.normpath(str(self))
+ return self._from_parts((normalized_path,))
+
+
+class _PosixPurePath(_PurePath, pathlib.PurePosixPath):
+ __slots__ = ()
+
+
+class _WindowsPurePath(_PurePath, pathlib.PureWindowsPath):
+ __slots__ = ()
+
def normalize_url(url, base_url=None, keep_relative=False):
"""
- Returns a normalized URL doing a join with a base URL. URL scheme defaults
to 'file' and
- backslashes are replaced with slashes. For file paths the os.path.join is
used instead of
- urljoin.
+ Returns a normalized URL eventually joining it to a base URL if it's a
relative path.
+ Path names are converted to 'file' scheme URLs.
:param url: a relative or absolute URL.
- :param base_url: the reference base URL for construct the normalized URL
from \
- the argument. For compatibility between "os.path.join" and "urljoin" a
trailing \
- '/' is added to not empty paths.
+ :param base_url: a reference base URL.
:param keep_relative: if set to `True` keeps relative file paths, which
would \
- not strictly conformant to URL format specification.
- :return: A normalized URL.
- """
- def add_trailing_slash(x):
- return urlunsplit(
- (x[0], x[1], x[2] + '/' if x[2] and x[2][-1] != '/' else x[2],
x[3], x[4])
- )
-
- def filter_url(x):
- x = x.strip().replace('\\', '/')
- while x.startswith('//'):
- x = x.replace('//', '/', 1)
- while x.startswith('file:////'):
- x = x.replace('file:////', 'file:///', 1)
- if urlsplit(x).scheme in {'', 'file'}:
- x = x.replace('#', '%23')
- return x
-
- url = filter_url(url)
+ not strictly conformant to specification (RFC 8089), because *urlopen()*
doesn't \
+ accept a simple pathname.
+ :return: a normalized URL string.
+ """
+ url_parts = urlsplit(url)
+ if not is_local_scheme(url_parts.scheme):
+ return url_parts.geturl()
+
+ path = _PurePath.from_uri(url)
+ if path.is_absolute():
+ return path.normalize().as_uri()
if base_url is not None:
- base_url = filter_url(base_url)
base_url_parts = urlsplit(base_url)
- base_url = add_trailing_slash(base_url_parts)
- if base_url_parts.scheme not in uses_relative:
- base_url_parts = urlsplit('file:///{}'.format(base_url))
- else:
- base_url_parts = urlsplit(base_url)
+ base_path = _PurePath.from_uri(base_url)
+ if is_local_scheme(base_url_parts.scheme):
+ path = base_path.joinpath(path)
+ elif not url_parts.scheme:
+ path = base_path.joinpath(path).normalize()
+ return urlunsplit((
+ base_url_parts.scheme,
+ base_url_parts.netloc,
+ quote_from_bytes(bytes(path)),
+ url_parts.query,
+ url_parts.fragment
+ ))
- if base_url_parts.scheme not in ('', 'file'):
- url = urljoin(base_url, url)
- else:
- url_parts = urlsplit(url)
- if url_parts.scheme not in ('', 'file'):
- url = urljoin(base_url, url)
- elif not url_parts.netloc or base_url_parts.netloc ==
url_parts.netloc:
- # Join paths only if host parts (netloc) are equal, using the
os.path.join
- # instead of urljoin for path normalization.
- url = urlunsplit((
- '',
- base_url_parts.netloc,
- os.path.normpath(os.path.join(base_url_parts.path,
url_parts.path)),
- url_parts.query,
- url_parts.fragment,
- ))
-
- # Add 'file' scheme if '//' prefix is added
- if base_url_parts.netloc and not
url.startswith(base_url_parts.netloc) \
- and url.startswith('//'):
- url = 'file:' + url
-
- url_parts = urlsplit(url, scheme='file')
- if url_parts.scheme not in uses_relative:
- normalized_url = 'file:///{}'.format(url_parts.geturl()) # Eg.
k:/Python/lib/....
- elif url_parts.scheme != 'file':
- normalized_url = urlunsplit((
- url_parts.scheme,
- url_parts.netloc,
- pathname2url(url_parts.path),
- url_parts.query,
- url_parts.fragment,
- ))
- elif os.path.isabs(url_parts.path):
- normalized_url = url_parts.geturl()
- elif keep_relative:
- # Can't use urlunsplit with a scheme because it converts relative
paths to absolute ones.
- normalized_url = 'file:{}'.format(urlunsplit(('',) + url_parts[1:]))
- else:
- normalized_url = urlunsplit((
- url_parts.scheme,
- url_parts.netloc,
- os.path.abspath(url_parts.path),
- url_parts.query,
- url_parts.fragment,
- ))
- return filter_url(normalized_url)
+ if path.is_absolute() or keep_relative:
+ return path.normalize().as_uri()
+
+ base_path = _PurePath(os.getcwd())
+ return base_path.joinpath(path).normalize().as_uri()
###
@@ -186,18 +215,16 @@
return True
+def is_local_scheme(scheme):
+ return not scheme or scheme == 'file' or scheme in DRIVE_LETTERS
+
+
def is_remote_url(url):
- if not is_url(url):
- return False
- scheme = urlsplit(normalize_url(url)).scheme
- return scheme not in ('', 'file') and (len(scheme) > 1 or scheme not in
ascii_letters)
+ return is_url(url) and not is_local_scheme(urlsplit(url.strip()).scheme)
def is_local_url(url):
- if not is_url(url):
- return False
- scheme = urlsplit(normalize_url(url)).scheme
- return scheme in ('', 'file') or len(scheme) == 1 and scheme in
ascii_letters
+ return is_url(url) and is_local_scheme(urlsplit(url.strip()).scheme)
def url_path_is_file(url):
@@ -433,7 +460,7 @@
@property
def filepath(self):
"""
- The resource filepath if the intance is created from a local file,
`None` otherwise.
+ The resource filepath if the instance is created from a local file,
`None` otherwise.
"""
if self._url:
url_parts = urlsplit(self._url)
@@ -759,7 +786,7 @@
msg = "{!r} is not an element or the XML resource tree"
raise XMLResourceError(msg.format(elem))
- resource = XMLResource(elem, self._base_url, self._allow,
self._defuse, self._timeout)
+ resource = XMLResource(elem, self.base_url, self._allow, self._defuse,
self._timeout)
if not hasattr(elem, 'nsmap'):
namespaces = {}
_nsmap = self._nsmap[elem]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/xmlschema/validators/elements.py
new/xmlschema-1.6.4/xmlschema/validators/elements.py
--- old/xmlschema-1.6.1/xmlschema/validators/elements.py 2021-04-05
23:38:16.000000000 +0200
+++ new/xmlschema-1.6.4/xmlschema/validators/elements.py 2021-05-03
13:37:57.000000000 +0200
@@ -26,7 +26,7 @@
raw_xml_encode, strictly_equal
from .. import dataobjects
from ..converters import ElementData, XMLSchemaConverter
-from ..xpath import XMLSchemaProxy, ElementPathMixin
+from ..xpath import XMLSchemaProxy, ElementPathMixin, XPathElement
from .exceptions import XMLSchemaValidationError, XMLSchemaTypeTableWarning
from .helpers import get_xsd_derivation_attribute
@@ -34,7 +34,7 @@
XsdComponent, XsdType, ValidationMixin
from .particles import ParticleMixin
from .models import OccursCounter
-from .identities import XsdIdentity, XsdKeyref
+from .identities import IdentityXPathContext, XsdIdentity, XsdKeyref
from .wildcards import XsdAnyElement
@@ -577,6 +577,14 @@
xsd_type = self.maps.get_instance_type(type_name, xsd_type,
namespaces)
except (KeyError, TypeError) as err:
yield self.validation_error(validation, err, elem, **kwargs)
+ else:
+ if self.identities:
+ xpath_element = XPathElement(self.name, xsd_type)
+ for identity in self.identities.values():
+ context = IdentityXPathContext(self.schema,
item=xpath_element)
+ for e in
identity.selector.token.select_results(context):
+ if e not in identity.elements:
+ identity.elements[e] = None
if xsd_type.is_blocked(self):
reason = "usage of %r is blocked" % xsd_type
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/xmlschema/validators/schema.py
new/xmlschema-1.6.4/xmlschema/validators/schema.py
--- old/xmlschema-1.6.1/xmlschema/validators/schema.py 2021-04-11
22:19:21.000000000 +0200
+++ new/xmlschema-1.6.4/xmlschema/validators/schema.py 2021-06-06
12:53:20.000000000 +0200
@@ -1826,7 +1826,7 @@
:param unordered: a flag for explicitly activating unordered encoding
mode for \
content model data. This mode uses content models for a
reordered-by-model \
iteration of the child elements.
- :param kwargs: Keyword arguments containing options for converter and
encoding.
+ :param kwargs: keyword arguments containing options for converter.
:return: yields an Element instance/s or validation/encoding errors.
"""
self.check_validator(validation)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/xmlschema/validators/xsdbase.py
new/xmlschema-1.6.4/xmlschema/validators/xsdbase.py
--- old/xmlschema-1.6.1/xmlschema/validators/xsdbase.py 2021-04-05
23:38:16.000000000 +0200
+++ new/xmlschema-1.6.4/xmlschema/validators/xsdbase.py 2021-06-09
19:22:22.000000000 +0200
@@ -120,7 +120,7 @@
def copy(self):
validator = object.__new__(self.__class__)
validator.__dict__.update(self.__dict__)
- validator.errors = self.errors[:]
+ validator.errors = self.errors[:] # shallow copy duplicates errors
list
return validator
__copy__ = copy
@@ -610,7 +610,7 @@
is the primitive type. For a list is the primitive type of the item.
For a union is the base union type. For a complex type is xs:anyType.
"""
- if self.is_complex() and self.attributes:
+ if getattr(self, 'attributes', None):
return self.maps.types[XSD_ANY_TYPE]
elif self.base_type is None:
return self if self.is_simple() else self.maps.types[XSD_ANY_TYPE]
@@ -853,7 +853,7 @@
Element for other components.
:param with_bindings: if `True` is provided the decoding is done using
\
:class:`DataBindingConverter` that used XML data binding classes. For \
- default the objects are intances of :class:`DataElement` and uses the \
+ default the objects are instances of :class:`DataElement` and uses the
\
:class:`DataElementConverter`.
:param kwargs: other optional keyword arguments for the method \
:func:`iter_decode`, except the argument *converter*.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/xmlschema/xpath.py
new/xmlschema-1.6.4/xmlschema/xpath.py
--- old/xmlschema-1.6.1/xmlschema/xpath.py 2021-04-05 23:38:16.000000000
+0200
+++ new/xmlschema-1.6.4/xmlschema/xpath.py 2021-05-03 13:37:57.000000000
+0200
@@ -18,6 +18,7 @@
XPathSchemaContext, AbstractSchemaProxy
from .names import XSD_NAMESPACE
+from .helpers import get_qname, local_name, get_prefixed_qname
from .exceptions import XMLSchemaValueError, XMLSchemaTypeError
_REGEX_TAG_POSITION = re.compile(r'\b\[\d+]')
@@ -276,3 +277,49 @@
for child in self:
if tag is None or child.is_matching(tag):
yield child
+
+
+class XPathElement(ElementPathMixin):
+ """An element node for making XPath operations on schema types."""
+
+ parent = None
+
+ def __init__(self, name, xsd_type):
+ self.name = name
+ self.type = xsd_type
+ try:
+ self.attributes = xsd_type.attributes
+ except AttributeError:
+ pass
+
+ def __iter__(self):
+ if not self.type.has_simple_content():
+ yield from self.type.content.iter_elements()
+
+ @property
+ def xpath_proxy(self):
+ return XMLSchemaProxy(self.schema, self)
+
+ @property
+ def schema(self):
+ return self.type.schema
+
+ @property
+ def target_namespace(self):
+ return self.type.schema.target_namespace
+
+ @property
+ def namespaces(self):
+ return self.type.schema.namespaces
+
+ @property
+ def local_name(self):
+ return local_name(self.name)
+
+ @property
+ def qualified_name(self):
+ return get_qname(self.target_namespace, self.name)
+
+ @property
+ def prefixed_name(self):
+ return get_prefixed_qname(self.name, self.namespaces)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/xmlschema.egg-info/PKG-INFO
new/xmlschema-1.6.4/xmlschema.egg-info/PKG-INFO
--- old/xmlschema-1.6.1/xmlschema.egg-info/PKG-INFO 2021-04-11
23:17:40.000000000 +0200
+++ new/xmlschema-1.6.4/xmlschema.egg-info/PKG-INFO 2021-06-09
19:41:05.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: xmlschema
-Version: 1.6.1
+Version: 1.6.4
Summary: An XML Schema validator and decoder
Home-page: https://github.com/sissaschool/xmlschema
Author: Davide Brunato
@@ -181,6 +181,7 @@
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Software Development :: Libraries
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/xmlschema.egg-info/SOURCES.txt
new/xmlschema-1.6.4/xmlschema.egg-info/SOURCES.txt
--- old/xmlschema-1.6.1/xmlschema.egg-info/SOURCES.txt 2021-04-11
23:17:40.000000000 +0200
+++ new/xmlschema-1.6.4/xmlschema.egg-info/SOURCES.txt 2021-06-09
19:41:05.000000000 +0200
@@ -217,6 +217,11 @@
tests/test_cases/issues/issue_237/dir2/issue_237b.xsd
tests/test_cases/issues/issue_237/dir2/stockquote.wsdl
tests/test_cases/issues/issue_237/dir2/stockquote.xsd
+tests/test_cases/issues/issue_243/issue_243.xml
+tests/test_cases/issues/issue_243/issue_243.xsd
+tests/test_cases/issues/issue_245/issue_245-valid.xml
+tests/test_cases/issues/issue_245/issue_245.xml
+tests/test_cases/issues/issue_245/issue_245.xsd
tests/test_cases/resources/dummy file #2.txt
tests/test_cases/resources/dummy file.txt
tests/test_cases/resources/external_entity.xml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/xmlschema-1.6.1/xmlschema.egg-info/requires.txt
new/xmlschema-1.6.4/xmlschema.egg-info/requires.txt
--- old/xmlschema-1.6.1/xmlschema.egg-info/requires.txt 2021-04-11
23:17:40.000000000 +0200
+++ new/xmlschema-1.6.4/xmlschema.egg-info/requires.txt 2021-06-09
19:41:05.000000000 +0200
@@ -1,21 +1,21 @@
-elementpath<3.0.0,>=2.2.1
+elementpath<3.0.0,>=2.2.2
[codegen]
-elementpath<3.0.0,>=2.2.1
+elementpath<3.0.0,>=2.2.2
jinja2
[dev]
tox
coverage
lxml
-elementpath<3.0.0,>=2.2.1
+elementpath<3.0.0,>=2.2.2
memory_profiler
Sphinx
sphinx_rtd_theme
jinja2
[docs]
-elementpath<3.0.0,>=2.1.2
+elementpath<3.0.0,>=2.2.2
Sphinx
sphinx_rtd_theme
jinja2