The branch, frodo has been updated
via b17af2758099b21227e287487ccbda4c1cb4c5e0 (commit)
from f326f18940dbab3c31f1b82871830089c1eafaba (commit)
- Log -----------------------------------------------------------------
http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/scripts;a=commit;h=b17af2758099b21227e287487ccbda4c1cb4c5e0
commit b17af2758099b21227e287487ccbda4c1cb4c5e0
Author: ronie <[email protected]>
Date: Sun Feb 24 03:30:33 2013 +0100
[script.module.validictory] -v0.9.0
diff --git a/script.module.validictory/addon.xml
b/script.module.validictory/addon.xml
index 9c6ca8b..2668126 100644
--- a/script.module.validictory/addon.xml
+++ b/script.module.validictory/addon.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="script.module.validictory"
name="validictory"
- version="0.8.3"
- provider-name="Valentin-Costel HÄloiu">
+ version="0.9.0"
+ provider-name="vially">
<requires>
- <import addon="xbmc.python" version="2.0"/>
+ <import addon="xbmc.python" version="2.1.0"/>
</requires>
<extension point="xbmc.python.module"
library="lib" />
@@ -13,5 +13,6 @@
<description>Packed for XBMC from
https://github.com/sunlightlabs/validictory</description>
<license>MIT</license>
<platform>all</platform>
+ <source>https://github.com/vially/xbmc-validictory</source>
</extension>
</addon>
diff --git a/script.module.validictory/changelog.txt
b/script.module.validictory/changelog.txt
index 14e89ef..ec6c28e 100644
--- a/script.module.validictory/changelog.txt
+++ b/script.module.validictory/changelog.txt
@@ -1,2 +1,5 @@
+[B]0.9.0[/B]
+- update to upstream version: validictory 0.9.0
+
[B]0.8.3[/B]
- initial Release for XBMC
diff --git a/script.module.validictory/lib/validictory/__init__.py
b/script.module.validictory/lib/validictory/__init__.py
old mode 100644
new mode 100755
index 32ddeab..1121d55
--- a/script.module.validictory/lib/validictory/__init__.py
+++ b/script.module.validictory/lib/validictory/__init__.py
@@ -1,14 +1,14 @@
#!/usr/bin/env python
-from validictory.validator import SchemaValidator, ValidationError, SchemaError
+from validictory.validator import SchemaValidator, FieldValidationError,
ValidationError, SchemaError
-__all__ = ['validate', 'SchemaValidator', 'ValidationError', 'SchemaError']
-__version__ = '0.8.3'
+__all__ = ['validate', 'SchemaValidator', 'FieldValidationError',
'ValidationError', 'SchemaError']
+__version__ = '0.9.0'
def validate(data, schema, validator_cls=SchemaValidator,
format_validators=None, required_by_default=True,
- blank_by_default=False):
+ blank_by_default=False, disallow_unknown_properties=False):
'''
Validates a parsed json document against the provided schema. If an
error is found a :class:`ValidationError` is raised.
@@ -23,8 +23,11 @@ def validate(data, schema, validator_cls=SchemaValidator,
:param format_validators: optional dictionary of custom format validators
:param required_by_default: defaults to True, set to False to make
``required`` schema attribute False by default.
+ :param disallow_unknown_properties: defaults to False, set to True to
+ disallow properties not listed in the schema definition
'''
- v = validator_cls(format_validators, required_by_default, blank_by_default)
+ v = validator_cls(format_validators, required_by_default, blank_by_default,
+ disallow_unknown_properties)
return v.validate(data, schema)
if __name__ == '__main__':
diff --git a/script.module.validictory/lib/validictory/validator.py
b/script.module.validictory/lib/validictory/validator.py
old mode 100644
new mode 100755
index c990268..f735c49
--- a/script.module.validictory/lib/validictory/validator.py
+++ b/script.module.validictory/lib/validictory/validator.py
@@ -3,7 +3,7 @@ import sys
import copy
import socket
from datetime import datetime
-import warnings
+from decimal import Decimal
from collections import Mapping, Container
if sys.version_info[0] == 3:
@@ -27,14 +27,25 @@ class ValidationError(ValueError):
"""
+class FieldValidationError(ValidationError):
+ """
+ validation error that refers to a specific field
+ Includes `fieldname` and `value` attributes.
+ """
+ def __init__(self, message, fieldname, value):
+ super(FieldValidationError, self).__init__(message)
+ self.fieldname = fieldname
+ self.value = value
+
+
def _generate_datetime_validator(format_option, dateformat_string):
def validate_format_datetime(validator, fieldname, value, format_option):
try:
datetime.strptime(value, dateformat_string)
except ValueError:
- raise ValidationError(
+ raise FieldValidationError(
"Value %(value)r of field '%(fieldname)s' is not in "
- "'%(format_option)s' format" % locals())
+ "'%(format_option)s' format" % locals(), fieldname, value)
return validate_format_datetime
@@ -45,13 +56,13 @@ validate_format_time = _generate_datetime_validator('time',
'%H:%M:%S')
def validate_format_utc_millisec(validator, fieldname, value, format_option):
- if not isinstance(value, (int, float)):
- raise ValidationError("Value %(value)r of field '%(fieldname)s' is "
- "not a number" % locals())
+ if not isinstance(value, _int_types + (float, Decimal)):
+ raise FieldValidationError("Value %(value)r of field '%(fieldname)s'
is "
+ "not a number" % locals(), fieldname, value)
if not value > 0:
- raise ValidationError("Value %(value)r of field '%(fieldname)s' is "
- "not a positive number" % locals())
+ raise FieldValidationError("Value %(value)r of field '%(fieldname)s'
is "
+ "not a positive number" % locals(), fieldname,
value)
def validate_format_ip_address(validator, fieldname, value, format_option):
@@ -63,8 +74,8 @@ def validate_format_ip_address(validator, fieldname, value,
format_option):
except:
ip = False
if not ip:
- raise ValidationError("Value %(value)r of field '%(fieldname)s' is "
- "not a ip-address" % locals())
+ raise FieldValidationError("Value %(value)r of field '%(fieldname)s'
is "
+ "not a ip-address" % locals(), fieldname, value)
DEFAULT_FORMAT_VALIDATORS = {
@@ -86,16 +97,19 @@ class SchemaValidator(object):
``required`` schema attribute False by default.
:param blank_by_default: defaults to False, set to True to make ``blank``
schema attribute True by default.
+ :param disallow_unknown_properties: defaults to False, set to True to
+ disallow properties not listed in the schema definition
'''
def __init__(self, format_validators=None, required_by_default=True,
- blank_by_default=False):
+ blank_by_default=False, disallow_unknown_properties=False):
if format_validators is None:
format_validators = DEFAULT_FORMAT_VALIDATORS.copy()
self._format_validators = format_validators
self.required_by_default = required_by_default
self.blank_by_default = blank_by_default
+ self.disallow_unknown_properties = disallow_unknown_properties
def register_format_validator(self, format_name, format_validator_fun):
self._format_validators[format_name] = format_validator_fun
@@ -107,7 +121,7 @@ class SchemaValidator(object):
return type(val) in _int_types
def validate_type_number(self, val):
- return type(val) in _int_types + (float,)
+ return type(val) in _int_types + (float, Decimal,)
def validate_type_boolean(self, val):
return type(val) == bool
@@ -128,7 +142,20 @@ class SchemaValidator(object):
params['value'] = value
params['fieldname'] = fieldname
message = desc % params
- raise ValidationError(message)
+ raise FieldValidationError(message, fieldname, value)
+
+ def _validate_unknown_properties(self, schema, data, fieldname):
+ schema_properties = set(schema)
+ data_properties = set(data)
+ delta = data_properties - schema_properties
+ if delta:
+ unknowns = ''
+ for x in delta:
+ unknowns += '"%s", ' % x
+ unknowns = unknowns.rstrip(", ")
+ raise SchemaError('Unknown properties for field '
+ '"%(fieldname)s": %(unknowns)s' %
+ locals())
def validate_type(self, x, fieldname, schema, fieldtype=None):
'''
@@ -186,6 +213,11 @@ class SchemaValidator(object):
value = x.get(fieldname)
if isinstance(value, dict):
if isinstance(properties, dict):
+
+ if self.disallow_unknown_properties:
+ self._validate_unknown_properties(properties, value,
+ fieldname)
+
for eachProp in properties:
self.__validate(eachProp, value,
properties.get(eachProp))
@@ -203,7 +235,7 @@ class SchemaValidator(object):
if isinstance(value, (list, tuple)):
if isinstance(items, (list, tuple)):
if (not 'additionalItems' in schema and
- len(items) != len(value)):
+ len(items) != len(value)):
self._error("Length of list %(value)r for field "
"'%(fieldname)s' is not equal to length "
"of schema list", value, fieldname)
@@ -212,22 +244,26 @@ class SchemaValidator(object):
try:
self.validate(value[itemIndex],
items[itemIndex])
- except ValueError as e:
+ except FieldValidationError as e:
raise type(e)("Failed to validate field '%s' "
"list schema: %s" %
- (fieldname, e))
+ (fieldname, e), fieldname,
e.value)
elif isinstance(items, dict):
for eachItem in value:
+ if self.disallow_unknown_properties:
+ self._validate_unknown_properties(items, eachItem,
+ fieldname)
+
try:
self._validate(eachItem, items)
- except ValueError as e:
+ except FieldValidationError as e:
# a bit of a hack: replace reference to _data
# with 'list item' so error messages make sense
old_error = str(e).replace("field '_data'",
'list item')
raise type(e)("Failed to validate field '%s' list "
"schema: %s" %
- (fieldname, old_error))
+ (fieldname, old_error), fieldname,
e.value)
else:
raise SchemaError("Properties definition of field '%s' is "
"not a list or an object" % fieldname)
@@ -253,7 +289,7 @@ class SchemaValidator(object):
def validate_patternProperties(self, x, fieldname, schema,
patternproperties=None):
- if patternproperties == None:
+ if patternproperties is None:
patternproperties = {}
value_obj = x.get(fieldname, {})
@@ -274,7 +310,6 @@ class SchemaValidator(object):
if additionalItems or 'items' not in schema:
return
elif len(value) != len(schema['items']):
- #print locals(), value, len(value), len(schema['items'])
self._error("Length of list %(value)r for field "
"'%(fieldname)s' is not equal to length of schema "
"list", value, fieldname)
@@ -311,25 +346,18 @@ class SchemaValidator(object):
if eachProperty not in properties:
# If additionalProperties is the boolean value False
# then we don't accept any additional properties.
- if (isinstance(additionalProperties, bool) and
- not additionalProperties):
- self._error("additional properties not defined by "
- "'properties' are not allowed in field "
- "'%(fieldname)s'",
- None, fieldname)
+ if (isinstance(additionalProperties, bool) and not
+ additionalProperties):
+ self._error("additional property '%(prop)s' "
+ "not defined by 'properties' are not "
+ "allowed in field '%(fieldname)s'",
+ None, fieldname, prop=eachProperty)
self.__validate(eachProperty, value,
additionalProperties)
else:
raise SchemaError("additionalProperties schema definition for "
"field '%s' is not an object" % fieldname)
- def validate_requires(self, x, fieldname, schema, requires=None):
- warnings.warn('The "requires" attribute has been replaced by
"dependencies"', DeprecationWarning)
- if x.get(fieldname) is not None:
- if x.get(requires) is None:
- self._error("Field '%(requires)s' is required by field
'%(fieldname)s'",
- None, fieldname, requires=requires)
-
def validate_dependencies(self, x, fieldname, schema, dependencies=None):
if x.get(fieldname) is not None:
@@ -341,7 +369,7 @@ class SchemaValidator(object):
if dependency not in x:
self._error("Field '%(dependency)s' is required by "
"field '%(fieldname)s'",
- None, fieldname, dependency=dependency)
+ None, fieldname, dependency=dependency)
elif isinstance(dependencies, dict):
# NOTE: the version 3 spec is really unclear on what this means
# based on the meta-schema I'm assuming that it should check
@@ -367,7 +395,7 @@ class SchemaValidator(object):
if value is not None:
if (type(value) in (int, float) and
(not exclusive and value < minimum) or
- (exclusive and value <= minimum)):
+ (exclusive and value <= minimum)):
self._error("Value %(value)r for field '%(fieldname)s' is "
"less than minimum value: %(minimum)f",
value, fieldname, minimum=minimum)
@@ -385,7 +413,7 @@ class SchemaValidator(object):
if value is not None:
if (type(value) in (int, float) and
(not exclusive and value > maximum) or
- (exclusive and value >= maximum)):
+ (exclusive and value >= maximum)):
self._error("Value %(value)r for field '%(fieldname)s' is "
"greater than maximum value: %(maximum)f",
value, fieldname, maximum=maximum)
@@ -490,12 +518,12 @@ class SchemaValidator(object):
def validate_title(self, x, fieldname, schema, title=None):
if not isinstance(title, (_str_type, type(None))):
raise SchemaError("The title for field '%s' must be a string" %
- fieldname)
+ fieldname)
def validate_description(self, x, fieldname, schema, description=None):
if not isinstance(description, (_str_type, type(None))):
raise SchemaError("The description for field '%s' must be a string"
- % fieldname)
+ % fieldname)
def validate_divisibleBy(self, x, fieldname, schema, divisibleBy=None):
value = x.get(fieldname)
@@ -537,19 +565,21 @@ class SchemaValidator(object):
if schema is not None:
if not isinstance(schema, dict):
- raise SchemaError("Schema structure is invalid.")
+ raise SchemaError(
+ "Type for field '%s' must be 'dict', got: '%s'" %
+ (fieldname, type(schema).__name__))
newschema = copy.copy(schema)
- # handle 'optional', replace it with 'required'
- if 'required' in schema and 'optional' in schema:
- raise SchemaError('cannot specify optional and required')
- elif 'optional' in schema:
- warnings.warn('The "optional" attribute has been replaced by
"required"', DeprecationWarning)
- newschema['required'] = not schema['optional']
- elif 'required' not in schema:
- newschema['required'] = self.required_by_default
+ if 'optional' in schema:
+ raise SchemaError('The "optional" attribute has been replaced'
+ ' by "required"')
+ if 'requires' in schema:
+ raise SchemaError('The "requires" attribute has been replaced'
+ ' by "dependencies"')
+ if 'required' not in schema:
+ newschema['required'] = self.required_by_default
if 'blank' not in schema:
newschema['blank'] = self.blank_by_default
@@ -564,4 +594,4 @@ class SchemaValidator(object):
return data
-__all__ = ['SchemaValidator']
+__all__ = ['SchemaValidator', 'FieldValidationError']
-----------------------------------------------------------------------
Summary of changes:
script.module.validictory/addon.xml | 7 +-
script.module.validictory/changelog.txt | 3 +
.../lib/validictory/__init__.py | 13 ++-
.../lib/validictory/validator.py | 126 ++++++++++++--------
4 files changed, 93 insertions(+), 56 deletions(-)
mode change 100644 => 100755
script.module.validictory/lib/validictory/__init__.py
mode change 100644 => 100755
script.module.validictory/lib/validictory/validator.py
hooks/post-receive
--
Scripts
------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_feb
_______________________________________________
Xbmc-addons mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/xbmc-addons