diff options
Diffstat (limited to 'bin/reportlab/lib/validators.py')
| -rw-r--r-- | bin/reportlab/lib/validators.py | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/bin/reportlab/lib/validators.py b/bin/reportlab/lib/validators.py new file mode 100644 index 00000000000..3f7f06edb79 --- /dev/null +++ b/bin/reportlab/lib/validators.py @@ -0,0 +1,324 @@ +#Copyright ReportLab Europe Ltd. 2000-2004 +#see license.txt for license details +#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/lib/validators.py +__version__=''' $Id: validators.py 2875 2006-05-18 07:00:16Z andy $ ''' +""" +This module contains some standard verifying functions which can be +used in an attribute map. +""" + +import string, sys, codecs +from types import * +_SequenceTypes = (ListType,TupleType) +_NumberTypes = (FloatType,IntType) +from reportlab.lib import colors +if sys.hexversion<0x2030000: + True = 1 + False = 0 + +class Validator: + "base validator class" + def __call__(self,x): + return self.test(x) + + def __str__(self): + return getattr(self,'_str',self.__class__.__name__) + + def normalize(self,x): + return x + + def normalizeTest(self,x): + try: + self.normalize(x) + return True + except: + return False + +class _isAnything(Validator): + def test(self,x): + return True + +class _isNothing(Validator): + def test(self,x): + return False + +class _isBoolean(Validator): + if sys.hexversion>=0x2030000: + def test(self,x): + if type(x) in (IntType,BooleanType): return x in (0,1) + return self.normalizeTest(x) + else: + def test(self,x): + if type(x) is IntType: return x in (0,1) + return self.normalizeTest(x) + + def normalize(self,x): + if x in (0,1): return x + try: + S = string.upper(x) + except: + raise ValueError, 'Must be boolean' + if S in ('YES','TRUE'): return True + if S in ('NO','FALSE',None): return False + raise ValueError, 'Must be boolean' + +class _isString(Validator): + def test(self,x): + return type(x) in (StringType, UnicodeType) + +class _isCodec(Validator): + def test(self,x): + if type(x) not in (StringType, UnicodeType): + return False + try: + a,b,c,d = codecs.lookup(x) + return True + except LookupError: + return False + +class _isNumber(Validator): + def test(self,x): + if type(x) in _NumberTypes: return True + return self.normalizeTest(x) + + def normalize(self,x): + try: + return float(x) + except: + return int(x) + +class _isInt(Validator): + def test(self,x): + if type(x) not in (IntType,StringType): return False + return self.normalizeTest(x) + + def normalize(self,x): + return int(x) + +class _isNumberOrNone(_isNumber): + def test(self,x): + return x is None or isNumber(x) + + def normalize(self,x): + if x is None: return x + return _isNumber.normalize(x) + +class _isListOfNumbersOrNone(Validator): + "ListOfNumbersOrNone validator class." + def test(self, x): + if x is None: return True + return isListOfNumbers(x) + +class _isListOfShapes(Validator): + "ListOfShapes validator class." + def test(self, x): + from reportlab.graphics.shapes import Shape + if type(x) in _SequenceTypes: + answer = 1 + for element in x: + if not isinstance(x, Shape): + answer = 0 + return answer + else: + return False + +class _isListOfStringsOrNone(Validator): + "ListOfStringsOrNone validator class." + + def test(self, x): + if x is None: return True + return isListOfStrings(x) + +class _isTransform(Validator): + "Transform validator class." + def test(self, x): + if type(x) in _SequenceTypes: + if len(x) == 6: + for element in x: + if not isNumber(element): + return False + return True + else: + return False + else: + return False + +class _isColor(Validator): + "Color validator class." + def test(self, x): + return isinstance(x, colors.Color) + +class _isColorOrNone(Validator): + "ColorOrNone validator class." + def test(self, x): + if x is None: return True + return isColor(x) + +class _isValidChild(Validator): + "ValidChild validator class." + def test(self, x): + """Is this child allowed in a drawing or group? + I.e. does it descend from Shape or UserNode? + """ + + from reportlab.graphics.shapes import UserNode, Shape + return isinstance(x, UserNode) or isinstance(x, Shape) + +class _isValidChildOrNone(_isValidChild): + def test(self,x): + return _isValidChild.test(self,x) or x is None + +class _isCallable(Validator): + def test(self, x): + return callable(x) + +class OneOf(Validator): + """Make validator functions for list of choices. + + Usage: + f = reportlab.lib.validators.OneOf('happy','sad') + or + f = reportlab.lib.validators.OneOf(('happy','sad')) + f('sad'),f('happy'), f('grumpy') + (1,1,0) + """ + def __init__(self, enum,*args): + if type(enum) in [ListType,TupleType]: + if args!=(): + raise ValueError, "Either all singleton args or a single sequence argument" + self._enum = tuple(enum)+args + else: + self._enum = (enum,)+args + + def test(self, x): + return x in self._enum + +class SequenceOf(Validator): + def __init__(self,elemTest,name=None,emptyOK=1, NoneOK=0, lo=0,hi=0x7fffffff): + self._elemTest = elemTest + self._emptyOK = emptyOK + self._NoneOK = NoneOK + self._lo, self._hi = lo, hi + if name: self._str = name + + def test(self, x): + if type(x) not in _SequenceTypes: + if x is None: return self._NoneOK + return False + if x==[] or x==(): + return self._emptyOK + elif not self._lo<=len(x)<=self._hi: return False + for e in x: + if not self._elemTest(e): return False + return True + +class EitherOr(Validator): + def __init__(self,tests,name=None): + if type(tests) not in _SequenceTypes: tests = (tests,) + self._tests = tests + if name: self._str = name + + def test(self, x): + for t in self._tests: + if t(x): return True + return False + +class NoneOr(Validator): + def __init__(self,elemTest,name=None): + self._elemTest = elemTest + if name: self._str = name + + def test(self, x): + if x is None: return True + return self._elemTest(x) + +class Auto(Validator): + def __init__(self,**kw): + self.__dict__.update(kw) + + def test(self,x): + return x is self.__class__ or isinstance(x,self.__class__) + +class AutoOr(NoneOr): + def test(self,x): + return isAuto(x) or self._elemTest(x) + +class isInstanceOf(Validator): + def __init__(self,klass=None): + self._klass = klass + def test(self,x): + return isinstance(x,self._klass) + +class matchesPattern(Validator): + """Matches value, or its string representation, against regex""" + def __init__(self, pattern): + self._pattern = re.compile(pattern) + + def test(self,x): + print 'testing %s against %s' % (x, self._pattern) + if type(x) is StringType: + text = x + else: + text = str(x) + return (self._pattern.match(text) <> None) + +class DerivedValue: + """This is used for magic values which work themselves out. + An example would be an "inherit" property, so that one can have + + drawing.chart.categoryAxis.labels.fontName = inherit + + and pick up the value from the top of the drawing. + Validators will permit this provided that a value can be pulled + in which satisfies it. And the renderer will have special + knowledge of these so they can evaluate themselves. + """ + def getValue(self, renderer, attr): + """Override this. The renderers will pass the renderer, + and the attribute name. Algorithms can then backtrack up + through all the stuff the renderer provides, including + a correct stack of parent nodes.""" + return None + +class Inherit(DerivedValue): + def __repr__(self): + return "inherit" + + def getValue(self, renderer, attr): + return renderer.getStateValue(attr) + +inherit = Inherit() + + +isAuto = Auto() +isBoolean = _isBoolean() +isString = _isString() +isCodec = _isCodec() +isNumber = _isNumber() +isInt = _isInt() +isNoneOrInt = NoneOr(isInt,'isNoneOrInt') +isNumberOrNone = _isNumberOrNone() +isTextAnchor = OneOf('start','middle','end','boxauto') +isListOfNumbers = SequenceOf(isNumber,'isListOfNumbers') +isListOfNumbersOrNone = _isListOfNumbersOrNone() +isListOfShapes = _isListOfShapes() +isListOfStrings = SequenceOf(isString,'isListOfStrings') +isListOfStringsOrNone = _isListOfStringsOrNone() +isTransform = _isTransform() +isColor = _isColor() +isListOfColors = SequenceOf(isColor,'isListOfColors') +isColorOrNone = _isColorOrNone() +isShape = isValidChild = _isValidChild() +isNoneOrShape = isValidChildOrNone = _isValidChildOrNone() +isAnything = _isAnything() +isNothing = _isNothing() +isXYCoord = SequenceOf(isNumber,lo=2,hi=2,emptyOK=0) +isBoxAnchor = OneOf('nw','n','ne','w','c','e','sw','s','se', 'autox', 'autoy') +isNoneOrString = NoneOr(isString,'NoneOrString') +isNoneOrListOfNoneOrStrings=SequenceOf(isNoneOrString,'isNoneOrListOfNoneOrStrings',NoneOK=1) +isListOfNoneOrString=SequenceOf(isNoneOrString,'isListOfNoneOrString',NoneOK=0) +isNoneOrListOfNoneOrNumbers=SequenceOf(isNumberOrNone,'isNoneOrListOfNoneOrNumbers',NoneOK=1) +isCallable = _isCallable() +isStringOrCallable=EitherOr((isString,isCallable),'isStringOrCallable') +isStringOrCallableOrNone=NoneOr(isStringOrCallable,'isStringOrCallableNone') +isStringOrNone=NoneOr(isString,'isStringOrNone') |
