Skip to content

Commit

Permalink
Update docs and bump minor release
Browse files Browse the repository at this point in the history
  - Clean facets module
  • Loading branch information
brunato committed Mar 25, 2024
1 parent 45c799d commit 3608106
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 27 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
CHANGELOG
*********

`v3.2.0`_ (2024-03-25)
======================
* Add *download_schemas()* to package API (#387)
* Fix issue with facets on list types (#396)

`v3.1.0`_ (2024-03-13)
======================
* Add GData converter (issue #388/PR #391)
Expand Down Expand Up @@ -679,3 +684,4 @@ v0.9.6 (2017-05-05)
.. _v3.0.1: https://github.com/brunato/xmlschema/compare/v3.0.0...v3.0.1
.. _v3.0.2: https://github.com/brunato/xmlschema/compare/v3.0.1...v3.0.2
.. _v3.1.0: https://github.com/brunato/xmlschema/compare/v3.0.2...v3.1.0
.. _v3.2.0: https://github.com/brunato/xmlschema/compare/v3.1.0...v3.2.0
1 change: 1 addition & 0 deletions doc/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ XML resources API
.. autofunction:: xmlschema.fetch_resource
.. autofunction:: xmlschema.fetch_schema_locations
.. autofunction:: xmlschema.fetch_schema
.. autofunction:: xmlschema.download_schemas

.. autoclass:: xmlschema.XMLResource

Expand Down
4 changes: 2 additions & 2 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@
# built documents.
#
# The short X.Y version.
version = '3.1'
version = '3.2'
# The full version, including alpha/beta/rc tags.
release = '3.1.0'
release = '3.2.0'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
2 changes: 1 addition & 1 deletion doc/features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ alternative classes or module parameters.
XSD 1.0 and 1.1 support
=======================

From release v1.0.14 XSD 1.1 support has been added to the library through the class
Since release v1.0.14 XSD 1.1 support has been added to the library through the class
:class:`xmlschema.XMLSchema11`. You have to use this class for XSD 1.1 schemas instead the default
class :class:`xmlschema.XMLSchema`, that is linked to XSD 1.0 validator :class:`xmlschema.XMLSchema10`.

Expand Down
14 changes: 14 additions & 0 deletions doc/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ Sometimes, it is advantageous to validate XML files using an XSD schema located
at a remote location while also having the option to store the same schema
locally for offline use.

The first option is to build a schema and then export the XSD sources to a local
directory:

.. code-block:: py
import xmlschema
Expand All @@ -157,6 +160,17 @@ becomes
<xsd:import namespace="http://www.w3.org/1999/xhtml" schemaLocation="my_schemas/www.omg.org/spec/ReqIF/20110402/driver.xsd"/>
The alternative option is to download the XSD resources directly:

.. code-block:: py
from xmlschema import download_schemas
download_schemas("https://www.omg.org/spec/ReqIF/20110401/reqif.xsd", target='my_schemas')
For default the original XSD schemas are not changed and a location map is returned. This map
is also written to a LOCATION_MAP dictionary in the target directory as the module `__init__.py`,
so can be used after as *uri_mapper* argument for building the schema instance.

.. note::

Since release v2.5.0 the ``schemaLocation`` attributes are rewritten with
Expand Down
4 changes: 2 additions & 2 deletions publiccode.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ publiccodeYmlVersion: '0.2'
name: xmlschema
url: 'https://github.com/sissaschool/xmlschema'
landingURL: 'https://github.com/sissaschool/xmlschema'
releaseDate: '2024-03-13'
softwareVersion: v3.1.0
releaseDate: '2024-03-25'
softwareVersion: v3.2.0
developmentStatus: stable
platforms:
- linux
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

setup(
name='xmlschema',
version='3.1.0',
version='3.2.0',
packages=find_packages(include=['xmlschema*']),
package_data={
'xmlschema': ['py.typed', 'locale/**/*.mo', 'locale/**/*.po', 'schemas/*/*.xsd'],
Expand Down
2 changes: 1 addition & 1 deletion xmlschema/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
XMLSchema, XMLSchema10, XMLSchema11, XsdComponent, XsdType, XsdElement, XsdAttribute
)

__version__ = '3.1.0'
__version__ = '3.2.0'
__author__ = "Davide Brunato"
__contact__ = "brunato@sissa.it"
__copyright__ = "Copyright 2016-2024, SISSA"
Expand Down
40 changes: 20 additions & 20 deletions xmlschema/validators/facets.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
import math
import operator
from abc import abstractmethod
from typing import TYPE_CHECKING, cast, Any, List, Optional, Pattern, Union, \
MutableSequence, overload, Tuple, Type, Dict
from typing import TYPE_CHECKING, cast, overload, Any, Dict, List, \
MutableSequence, Optional, Pattern, Union, Tuple, Type
from xml.etree.ElementTree import Element

from elementpath import XPathContext, ElementPathError, \
Expand Down Expand Up @@ -54,6 +54,7 @@ def __init__(self, elem: ElementType,
parent: Union['XsdList', 'XsdAtomicRestriction'],
base_type: Optional[BaseXsdType]) -> None:
self.base_type = base_type
self._validator = self._skip_validation
super(XsdFacet, self).__init__(elem, schema, parent)

def __repr__(self) -> str:
Expand All @@ -66,8 +67,7 @@ def __call__(self, value: Any) -> None:
reason = _("invalid type {!r} provided").format(type(value))
raise XMLSchemaValidationError(self, value, reason) from None

@staticmethod
def _validator(_: Any) -> None:
def _skip_validation(self, value: Any) -> None:
return

def _parse(self) -> None:
Expand Down Expand Up @@ -102,16 +102,16 @@ def base_facet(self) -> Optional['XsdFacet']:
"""
base_type: Optional[BaseXsdType] = self.base_type
tag = self.elem.tag
while True:
if base_type is None:
return None
while base_type is not None:
try:
base_facet = base_type.facets[tag] # type: ignore[union-attr]
except (AttributeError, KeyError):
base_type = base_type.base_type
else:
assert isinstance(base_facet, self.__class__)
assert isinstance(base_facet, XsdFacet)
return base_facet
else:
return None


class XsdWhiteSpaceFacet(XsdFacet):
Expand All @@ -132,11 +132,11 @@ class XsdWhiteSpaceFacet(XsdFacet):
def _parse_value(self, elem: ElementType) -> None:
self.value = elem.attrib['value']
if self.value == 'collapse':
self._validator = self.collapse_white_space_validator # type: ignore[assignment]
self._validator = self.collapse_white_space_validator
elif self.value == 'replace':
if self.base_value == 'collapse':
self.parse_error(_("facet value can be only 'collapse'"))
self._validator = self.replace_white_space_validator # type: ignore[assignment]
self._validator = self.replace_white_space_validator
elif self.base_value == 'collapse':
self.parse_error(_("facet value can be only 'collapse'"))
elif self.base_value == 'replace':
Expand Down Expand Up @@ -181,9 +181,9 @@ def _parse_value(self, elem: ElementType) -> None:
primitive_type = getattr(self.base_type, 'primitive_type', None)
if primitive_type is None or primitive_type.name not in {XSD_QNAME, XSD_NOTATION_TYPE}:
# See: https://www.w3.org/Bugs/Public/show_bug.cgi?id=4009
self._validator = self._length_validator # type: ignore[assignment]
self._validator = self.length_validator

def _length_validator(self, value: Any) -> None:
def length_validator(self, value: Any) -> None:
if len(value) != self.value:
reason = _("length has to be {!r}").format(self.value)
raise XMLSchemaValidationError(self, value, reason)
Expand Down Expand Up @@ -215,9 +215,9 @@ def _parse_value(self, elem: ElementType) -> None:
primitive_type = getattr(self.base_type, 'primitive_type', None)
if primitive_type is None or primitive_type.name not in {XSD_QNAME, XSD_NOTATION_TYPE}:
# See: https://www.w3.org/Bugs/Public/show_bug.cgi?id=4009
self._validator = self._min_length_validator # type: ignore[assignment]
self._validator = self.min_length_validator

def _min_length_validator(self, value: Any) -> None:
def min_length_validator(self, value: Any) -> None:
if len(value) < self.value:
reason = _("value length cannot be lesser than {!r}").format(self.value)
raise XMLSchemaValidationError(self, value, reason)
Expand Down Expand Up @@ -249,9 +249,9 @@ def _parse_value(self, elem: ElementType) -> None:
primitive_type = getattr(self.base_type, 'primitive_type', None)
if primitive_type is None or primitive_type.name not in {XSD_QNAME, XSD_NOTATION_TYPE}:
# See: https://www.w3.org/Bugs/Public/show_bug.cgi?id=4009
self._validator = self._max_length_validator # type: ignore[assignment]
self._validator = self.max_length_validator

def _max_length_validator(self, value: Any) -> None:
def max_length_validator(self, value: Any) -> None:
if len(value) > self.value:
reason = _("value length cannot be greater than {!r}").format(self.value)
raise XMLSchemaValidationError(self, value, reason)
Expand Down Expand Up @@ -509,9 +509,9 @@ class XsdExplicitTimezoneFacet(XsdFacet):
def _parse_value(self, elem: ElementType) -> None:
self.value = elem.attrib['value']
if self.value == 'prohibited':
self._validator = self._prohibited_timezone_validator # type: ignore[assignment]
self._validator = self.prohibited_timezone_validator
elif self.value == 'required':
self._validator = self._required_timezone_validator # type: ignore[assignment]
self._validator = self.required_timezone_validator
elif self.value != 'optional':
self.value = 'optional' # Error already detected by meta-schema validation

Expand All @@ -520,12 +520,12 @@ def _parse_value(self, elem: ElementType) -> None:
msg = _("invalid restriction from {!r}")
self.parse_error(msg.format(facet.value))

def _required_timezone_validator(self, value: Any) -> None:
def required_timezone_validator(self, value: Any) -> None:
if value.tzinfo is None:
reason = _("time zone required for value {!r}").format(self.value)
raise XMLSchemaValidationError(self, value, reason)

def _prohibited_timezone_validator(self, value: Any) -> None:
def prohibited_timezone_validator(self, value: Any) -> None:
if value.tzinfo is not None:
reason = _("time zone prohibited for value {!r}").format(self.value)
raise XMLSchemaValidationError(self, value, reason)
Expand Down

0 comments on commit 3608106

Please sign in to comment.