You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
calculate-utils-3-lib/pym/calculate/contrib/spyne/model/primitive/string.py

308 lines
9.3 KiB

#
# spyne - Copyright (C) Spyne contributors.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
#
from __future__ import unicode_literals
import decimal
import uuid
from spyne.model.primitive import NATIVE_MAP
from spyne.util import six
from spyne.model._base import SimpleModel
from spyne.model.primitive._base import re_match_with_span
UUID_PATTERN = "%(x)s{8}-%(x)s{4}-%(x)s{4}-%(x)s{4}-%(x)s{12}" % \
{'x': '[a-fA-F0-9]'}
LTREE_PATTERN = r"\w+(\.\w+)*"
# Actual ltree max size is 65536 but it's advised to keep it under 2048.
LTREE_OPTIMAL_SIZE = 2048
LTREE_MAXIMUM_SIZE = 65536
def _gen_mime_type_pattern(strict, with_params):
ows = "[ \\t]*" # Optional WhiteSpace
token = "[0-9A-Za-z!#$%&'*+.^_`|~-]+"
quotedString = "\"(?:[^\"\\\\]|\\.)*\""
if strict:
main_type = "(" \
"application|audio|font|example|image|message|model|multipart" \
"|text|video|x-(?:" + token + ")" \
")"
else:
main_type = token
param = token + "=" + "(?:" + token + "|" + quotedString + ");?" + ows
params = ";" + ows + param + "(" + param + ")*"
if not with_params:
return main_type + "/" + "(" + token + ")"
else:
return main_type + "/" + "(" + token + ")" + params
MIME_TYPE_PATTERN_STRICT = \
_gen_mime_type_pattern(strict=True, with_params=False)
MIME_TYPE_PATTERN_PERMISSIVE = \
_gen_mime_type_pattern(strict=False, with_params=False)
MEDIA_TYPE_PATTERN_STRICT = \
_gen_mime_type_pattern(strict=True, with_params=True)
MEDIA_TYPE_PATTERN_PERMISSIVE = \
_gen_mime_type_pattern(strict=False, with_params=True)
class Unicode(SimpleModel):
"""The type to represent human-readable data. Its native format is `unicode`
or `str` with given encoding.
"""
__type_name__ = 'string'
Value = six.text_type
class Attributes(SimpleModel.Attributes):
"""Customizable attributes of the :class:`spyne.model.primitive.Unicode`
type."""
min_len = 0
"""Minimum length of string. Can be set to any positive integer"""
max_len = decimal.Decimal('inf')
"""Maximum length of string. Can be set to ``decimal.Decimal('inf')`` to
accept strings of arbitrary length. You may also need to adjust
:const:`spyne.server.wsgi.MAX_CONTENT_LENGTH`."""
pattern = None
"""A regular expression that matches the whole string. See here for more
info: http://www.regular-expressions.info/xml.html"""
unicode_pattern = None
"""Same as ``pattern``, but, will be compiled with ``re.UNICODE``.
See: https://docs.python.org/2/library/re.html#re.UNICODE"""
encoding = None
"""The encoding of binary data this class may have to deal with."""
unicode_errors = 'strict'
"""The argument to the ``unicode`` builtin; one of 'strict', 'replace'
or 'ignore'."""
format = None
"""A regular python string formatting string. See here:
http://docs.python.org/library/stdtypes.html#string-formatting"""
cast = None
"""Type override callable for casting non-unicode input to unicode."""
def __new__(cls, *args, **kwargs):
assert len(args) <= 1
if len(args) == 1:
kwargs['max_len'] = args[0]
retval = SimpleModel.__new__(cls, ** kwargs)
return retval
@staticmethod
def is_default(cls):
return ( SimpleModel.is_default(cls)
and cls.Attributes.min_len == Unicode.Attributes.min_len
and cls.Attributes.max_len == Unicode.Attributes.max_len
and cls.Attributes.pattern == Unicode.Attributes.pattern
)
@staticmethod
def validate_string(cls, value):
return ( SimpleModel.validate_string(cls, value)
and (value is None or (
cls.Attributes.min_len <= len(value) <= cls.Attributes.max_len
)))
@staticmethod
def validate_native(cls, value):
return (SimpleModel.validate_native(cls, value)
and (value is None or (
re_match_with_span(cls.Attributes, value)
)))
class String(Unicode):
pass
if not six.PY2:
String = Unicode
class AnyUri(Unicode):
"""A special kind of String type designed to hold an uri."""
__type_name__ = 'anyURI'
class Attributes(String.Attributes):
text = None
"""The text shown in link."""
anchor_class = None
"""The class of the generated <a> tag."""
class Value(object):
"""A special object that is just a better way of carrying the
information carried with a link.
:param href: The uri string.
:param text: The text data that goes with the link. This is a
``str`` or a ``unicode`` instance.
:param content: The structured data that goes with the link. This is an
`lxml.etree.Element` instance.
"""
def __init__(self, href, text=None, content=None):
self.href = href
self.text = text
self.content = content
def __repr__(self):
return "Uri(href={0!r}, text={1!r}, content={2!r})" \
.format(self.href, self.text, self.content)
class ImageUri(AnyUri):
"""A special kind of String that holds the uri of an image."""
def _uuid_validate_string(cls, value):
return ( SimpleModel.validate_string(cls, value)
and (value is None or (
cls.Attributes.min_len <= len(value) <= cls.Attributes.max_len
and re_match_with_span(cls.Attributes, value)
)))
def _Tuuid_validate(key):
from uuid import UUID
def _uvalid(cls, v):
try:
UUID(**{key:v})
except ValueError:
return False
return True
return _uvalid
_uuid_validate = {
None: _uuid_validate_string,
'hex': _Tuuid_validate('hex'),
'urn': _Tuuid_validate('urn'),
six.binary_type: _Tuuid_validate('bytes'),
'bytes': _Tuuid_validate('bytes'),
'bytes_le': _Tuuid_validate('bytes_le'),
'fields': _Tuuid_validate('fields'),
int: _Tuuid_validate('int'),
'int': _Tuuid_validate('int'),
}
class Uuid(Unicode(pattern=UUID_PATTERN)):
"""Unicode subclass for Universially-Unique Identifiers."""
__namespace__ = 'http://spyne.io/schema'
__type_name__ = 'uuid'
Value = uuid.UUID
class Attributes(Unicode(pattern=UUID_PATTERN).Attributes):
serialize_as = None
@staticmethod
def validate_string(cls, value):
return _uuid_validate[cls.Attributes.serialize_as](cls, value)
@staticmethod
def validate_native(cls, value):
return SimpleModel.validate_native(cls, value)
class Ltree(Unicode(LTREE_OPTIMAL_SIZE, unicode_pattern=LTREE_PATTERN)):
"""A special kind of String type designed to hold the Ltree type from
Postgresql."""
__namespace__ = 'http://spyne.io/schema'
__type_name__ = 'ltreeString'
class LtreeLarge(Unicode(LTREE_MAXIMUM_SIZE, unicode_pattern=LTREE_PATTERN)):
"""A special kind of String type designed to hold the Ltree type from
Postgresql."""
__namespace__ = 'http://spyne.io/schema'
__type_name__ = 'largeLtreeString'
class MimeTypeStrict(Unicode(unicode_pattern=MIME_TYPE_PATTERN_STRICT)):
"""A special kind of String type designed to hold a mime type as defined
by IANA."""
__namespace__ = 'http://spyne.io/schema'
__type_name__ = 'strictMimeTypeString'
class MimeType(Unicode(unicode_pattern=MIME_TYPE_PATTERN_PERMISSIVE)):
"""A special kind of String type designed to hold a forward-compatible
mime type that can have any string as main type."""
__namespace__ = 'http://spyne.io/schema'
__type_name__ = 'mimeTypeString'
class MediaTypeStrict(Unicode(unicode_pattern=MEDIA_TYPE_PATTERN_STRICT)):
"""A special kind of String type designed to hold a mime type as defined
by IANA followed by arbitrary parameters.
See: https://tools.ietf.org/html/rfc7231#section-3.1.1.1"""
__namespace__ = 'http://spyne.io/schema'
__type_name__ = 'strictMediaTypeString'
class MediaType(Unicode(unicode_pattern=MEDIA_TYPE_PATTERN_PERMISSIVE)):
"""A special kind of String type designed to hold a forward-compatible
media type that can have any string as main type. A media type is
essentially a mime type plus parameters.
See: https://tools.ietf.org/html/rfc7231#section-3.1.1.1"""
__namespace__ = 'http://spyne.io/schema'
__type_name__ = 'mediaTypeString'
if not six.PY2:
NATIVE_MAP.update({
str: Unicode,
})
else:
NATIVE_MAP.update({
str: String,
unicode: Unicode,
})