From 1ab9238795a5144b3f2bf648769681287b72bb56 Mon Sep 17 00:00:00 2001 From: g Date: Tue, 6 Dec 2016 17:11:10 -0800 Subject: [PATCH] Added support for OrderedDict validation, including as the return type --- .gitignore | 1 + voluptuous/schema_builder.py | 2 +- voluptuous/tests/tests.py | 32 ++++++++++++++++++++++---------- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index e1c2457..d437888 100755 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ MANIFEST .idea venv docs/_build +.vscode/ \ No newline at end of file diff --git a/voluptuous/schema_builder.py b/voluptuous/schema_builder.py index dda6b87..0bcd2c9 100644 --- a/voluptuous/schema_builder.py +++ b/voluptuous/schema_builder.py @@ -517,7 +517,7 @@ def validate_dict(path, data): if errors: raise er.MultipleInvalid(errors) - out = {} + out = data.__class__() return base_validate(path, iteritems(data), out) return validate_dict diff --git a/voluptuous/tests/tests.py b/voluptuous/tests/tests.py index 8af39a1..ccfe4e3 100644 --- a/voluptuous/tests/tests.py +++ b/voluptuous/tests/tests.py @@ -1,6 +1,7 @@ import copy import collections from nose.tools import assert_equal, assert_raises, assert_true +import numpy from voluptuous import ( Schema, Required, Optional, Extra, Invalid, In, Remove, Literal, @@ -644,7 +645,7 @@ def test_unicode_key_is_converted_to_utf8_when_in_marker(): def test_number_validation_with_string(): """ test with Number with string""" - schema = Schema({"number" : Number(precision=6, scale=2)}) + schema = Schema({"number": Number(precision=6, scale=2)}) try: schema({"number": 'teststr'}) except MultipleInvalid as e: @@ -667,7 +668,7 @@ def test_unicode_key_is_converted_to_utf8_when_plain_text(): def test_number_validation_with_invalid_precision_invalid_scale(): """ test with Number with invalid precision and scale""" - schema = Schema({"number" : Number(precision=6, scale=2)}) + schema = Schema({"number": Number(precision=6, scale=2)}) try: schema({"number": '123456.712'}) except MultipleInvalid as e: @@ -679,28 +680,28 @@ def test_number_validation_with_invalid_precision_invalid_scale(): def test_number_validation_with_valid_precision_scale_yield_decimal_true(): """ test with Number with valid precision and scale""" - schema = Schema({"number" : Number(precision=6, scale=2, yield_decimal=True)}) + schema = Schema({"number": Number(precision=6, scale=2, yield_decimal=True)}) out_ = schema({"number": '1234.00'}) assert_equal(float(out_.get("number")), 1234.00) def test_number_when_precision_scale_none_yield_decimal_true(): """ test with Number with no precision and scale""" - schema = Schema({"number" : Number(yield_decimal=True)}) + schema = Schema({"number": Number(yield_decimal=True)}) out_ = schema({"number": '12345678901234'}) assert_equal(out_.get("number"), 12345678901234) def test_number_when_precision_none_n_valid_scale_case1_yield_decimal_true(): """ test with Number with no precision and valid scale case 1""" - schema = Schema({"number" : Number(scale=2, yield_decimal=True)}) + schema = Schema({"number": Number(scale=2, yield_decimal=True)}) out_ = schema({"number": '123456789.34'}) assert_equal(float(out_.get("number")), 123456789.34) def test_number_when_precision_none_n_valid_scale_case2_yield_decimal_true(): """ test with Number with no precision and valid scale case 2 with zero in decimal part""" - schema = Schema({"number" : Number(scale=2, yield_decimal=True)}) + schema = Schema({"number": Number(scale=2, yield_decimal=True)}) out_ = schema({"number": '123456789012.00'}) assert_equal(float(out_.get("number")), 123456789012.00) @@ -712,7 +713,7 @@ def test_to_utf8(): def test_number_when_precision_none_n_invalid_scale_yield_decimal_true(): """ test with Number with no precision and invalid scale""" - schema = Schema({"number" : Number(scale=2, yield_decimal=True)}) + schema = Schema({"number": Number(scale=2, yield_decimal=True)}) try: schema({"number": '12345678901.234'}) except MultipleInvalid as e: @@ -724,14 +725,14 @@ def test_number_when_precision_none_n_invalid_scale_yield_decimal_true(): def test_number_when_valid_precision_n_scale_none_yield_decimal_true(): """ test with Number with no precision and valid scale""" - schema = Schema({"number" : Number(precision=14, yield_decimal=True)}) + schema = Schema({"number": Number(precision=14, yield_decimal=True)}) out_ = schema({"number": '1234567.8901234'}) assert_equal(float(out_.get("number")), 1234567.8901234) def test_number_when_invalid_precision_n_scale_none_yield_decimal_true(): """ test with Number with no precision and invalid scale""" - schema = Schema({"number" : Number(precision=14, yield_decimal=True)}) + schema = Schema({"number": Number(precision=14, yield_decimal=True)}) try: schema({"number": '12345674.8901234'}) except MultipleInvalid as e: @@ -743,7 +744,7 @@ def test_number_when_invalid_precision_n_scale_none_yield_decimal_true(): def test_number_validation_with_valid_precision_scale_yield_decimal_false(): """ test with Number with valid precision, scale and no yield_decimal""" - schema = Schema({"number" : Number(precision=6, scale=2, yield_decimal=False)}) + schema = Schema({"number": Number(precision=6, scale=2, yield_decimal=False)}) out_ = schema({"number": '1234.00'}) assert_equal(out_.get("number"), '1234.00') @@ -770,3 +771,14 @@ def test_date(): schema({"date": "2016-10-24"}) assert_raises(MultipleInvalid, schema, {"date": "2016-10-2"}) assert_raises(MultipleInvalid, schema, {"date": "2016-10-24Z"}) + + +def test_ordered_dict(): + if not hasattr(collections, 'OrderedDict'): + # collections.OrderedDict was added in Python2.7; only run if present + return + schema = Schema({Number(): Number()}) # x, y pairs (for interpolation or something) + data = collections.OrderedDict(zip(numpy.linspace(5, 100, 11), numpy.random.random(11))) + out = schema(data) + assert isinstance(out, collections.OrderedDict), 'Collection is no longer ordered' + assert data.keys() == out.keys(), 'Order is not consistent'