From 497daab72ee7ed8ac451c2a1998c9f66d8cf713e Mon Sep 17 00:00:00 2001 From: tusharmakkar08 Date: Tue, 18 Apr 2017 23:41:59 +0530 Subject: [PATCH] fixed issue 270 --- voluptuous/schema_builder.py | 1 + voluptuous/tests/tests.py | 24 ++++++++++++++-- voluptuous/validators.py | 54 ++++++++++++++++++++++-------------- 3 files changed, 56 insertions(+), 23 deletions(-) diff --git a/voluptuous/schema_builder.py b/voluptuous/schema_builder.py index da3b31d..671c99e 100644 --- a/voluptuous/schema_builder.py +++ b/voluptuous/schema_builder.py @@ -1072,6 +1072,7 @@ def __repr__(self): def __hash__(self): return object.__hash__(self) + def message(default=None, cls=None): """Convenience decorator to allow functions to provide a message. diff --git a/voluptuous/tests/tests.py b/voluptuous/tests/tests.py index 09fea5d..2148acb 100644 --- a/voluptuous/tests/tests.py +++ b/voluptuous/tests/tests.py @@ -1,6 +1,8 @@ import copy import collections +import os import sys + from nose.tools import assert_equal, assert_raises, assert_true from voluptuous import ( @@ -8,7 +10,7 @@ Url, MultipleInvalid, LiteralInvalid, TypeInvalid, NotIn, Match, Email, Replace, Range, Coerce, All, Any, Length, FqdnUrl, ALLOW_EXTRA, PREVENT_EXTRA, validate, ExactSequence, Equal, Unordered, Number, Maybe, Datetime, Date, - Contains, Marker) + Contains, Marker, IsDir, IsFile, PathExists) from voluptuous.humanize import humanize_error from voluptuous.util import u @@ -849,7 +851,7 @@ def __call__(self, *args, **kwargs): for i in range(num_of_keys): schema_dict[CounterMarker(str(i))] = str data[str(i)] = str(i) - data_extra_keys[str(i*2)] = str(i) # half of the keys are present, and half aren't + data_extra_keys[str(i * 2)] = str(i) # half of the keys are present, and half aren't schema = Schema(schema_dict, extra=ALLOW_EXTRA) @@ -861,3 +863,21 @@ def __call__(self, *args, **kwargs): schema(data_extra_keys) assert counter[0] <= num_of_keys, "Validation complexity is not linear! %s > %s" % (counter[0], num_of_keys) + + +def test_IsDir(): + schema = Schema(IsDir()) + assert_raises(MultipleInvalid, schema, 3) + schema(os.path.dirname(os.path.abspath(__file__))) + + +def test_IsFile(): + schema = Schema(IsFile()) + assert_raises(MultipleInvalid, schema, 3) + schema(os.path.abspath(__file__)) + + +def test_PathExists(): + schema = Schema(PathExists()) + assert_raises(MultipleInvalid, schema, 3) + schema(os.path.abspath(__file__)) diff --git a/voluptuous/validators.py b/voluptuous/validators.py index 2318dd6..c281f14 100644 --- a/voluptuous/validators.py +++ b/voluptuous/validators.py @@ -18,9 +18,9 @@ PathInvalid, ExactSequenceInvalid, LengthInvalid, DatetimeInvalid, DateInvalid, InInvalid, TypeInvalid, NotInInvalid, ContainsInvalid) - if sys.version_info >= (3,): import urllib.parse as urlparse + basestring = str else: import urlparse @@ -419,9 +419,13 @@ def IsFile(v): >>> with raises(FileInvalid, 'Not a file'): ... IsFile()(None) """ - if v: - return os.path.isfile(v) - else: + try: + if v: + v = str(v) + return os.path.isfile(v) + else: + raise FileInvalid('Not a file') + except TypeError: raise FileInvalid('Not a file') @@ -435,9 +439,13 @@ def IsDir(v): >>> with raises(DirInvalid, 'Not a directory'): ... IsDir()(None) """ - if v: - return os.path.isdir(v) - else: + try: + if v: + v = str(v) + return os.path.isdir(v) + else: + raise DirInvalid("Not a directory") + except TypeError: raise DirInvalid("Not a directory") @@ -453,9 +461,13 @@ def PathExists(v): >>> with raises(PathInvalid, 'Not a Path'): ... PathExists()(None) """ - if v: - return os.path.exists(v) - else: + try: + if v: + v = str(v) + return os.path.exists(v) + else: + raise PathInvalid("Not a Path") + except TypeError: raise PathInvalid("Not a Path") @@ -471,6 +483,7 @@ class Maybe(object): ... s("string") """ + def __init__(self, kind, msg=None): if not isinstance(kind, type): raise TypeError("kind has to be a type") @@ -704,7 +717,7 @@ def __call__(self, v): return v def __repr__(self): - return 'Contains(%s)' % (self.item, ) + return 'Contains(%s)' % (self.item,) class ExactSequence(object): @@ -866,10 +879,8 @@ def __call__(self, v): el = missing[0] raise Invalid(self.msg or 'Element #{} ({}) is not valid against any validator'.format(el[0], el[1])) elif missing: - raise MultipleInvalid([ - Invalid(self.msg or 'Element #{} ({}) is not valid against any validator'.format(el[0], el[1])) - for el in missing - ]) + raise MultipleInvalid([Invalid(self.msg or 'Element #{} ({}) is not valid against any validator'.format( + el[0], el[1])) for el in missing]) return v def __repr__(self): @@ -904,15 +915,16 @@ def __call__(self, v): """ precision, scale, decimal_num = self._get_precision_scale(v) - if self.precision is not None and self.scale is not None and\ - precision != self.precision and scale != self.scale: - raise Invalid(self.msg or "Precision must be equal to %s, and Scale must be equal to %s" %(self.precision, self.scale)) + if self.precision is not None and self.scale is not None and precision != self.precision\ + and scale != self.scale: + raise Invalid(self.msg or "Precision must be equal to %s, and Scale must be equal to %s" % (self.precision, + self.scale)) else: if self.precision is not None and precision != self.precision: - raise Invalid(self.msg or "Precision must be equal to %s"%self.precision) + raise Invalid(self.msg or "Precision must be equal to %s" % self.precision) - if self.scale is not None and scale != self.scale : - raise Invalid(self.msg or "Scale must be equal to %s"%self.scale) + if self.scale is not None and scale != self.scale: + raise Invalid(self.msg or "Scale must be equal to %s" % self.scale) if self.yield_decimal: return decimal_num