Ic@s]dZddkZddkZdZdadaddkaddkTddk Tda a ei Z ei deddkZe e_ yeWnej oeiZnXddkZddkZy ddkZeieZWnej o eZnXddjddjZZdZdadadZd Zd Z d Z!d Z"d e#fdYZ$de#fdYZ%de#fdYZ&de#fdYZ'de#fdYZ(de#fdYZ)de#fdYZ*de#fdYZ+de+fdYZ,de#fd YZ-d!e#fd"YZ.d#e#fd$YZ/d%e#fd&YZ0d'e#fd(YZ1d)e#fd*YZ2d+e2fd,YZ3d-e2fd.YZ4d/e#fd0YZ5d1e5fd2YZ6d3e#fd4YZd5e#fd6YZ7d7e#fd8YZ8d9e#fd:YZ9d;e#fd<YZ:d=Z;d>Z<d?Z=d@e#fdAYZ>dBe#fdCYZ?dDe#fdEYZ@dFe#fdGYZAdHZBdIe#fdJYZCdKe#fdLYZDeDZEdMe#fdNYZFdOe#fdPYZGdQeGfdRYZHdSe#fdTYZIdUe#fdVYZJdWeJfdXYZKeKZLdYeJfdZYZMd[eJfd\YZNd]eJfd^YZOd_eJfd`YZPdagZQxNeRiSD]=\ZTZUeVeUeWo!eXeUeYoeQiZeTqqWdS(bs/ Validator/Converters for use with FormEncode. iN(t*tignoreiicCs|S(((ts((s9/usr/lib/python2.6/site-packages/formencode/validators.pyt?scCs|djoay%tdjoddkantSWqntj o)tdjoddklantSXn|i}|djo"tdjoddkantStdjoddklantSdS(Ni(tDateTimetdatetime(tNonetdatetime_moduleRt ImportErrortmxDateTime_moduletmxRtlower(t module_type((s9/usr/lib/python2.6/site-packages/formencode/validators.pytimport_datetimeJs"        cCs,|idjo|iiS|iSdS(NR(t__name__Rtnow(tmodule((s9/usr/lib/python2.6/site-packages/formencode/validators.pyt datetime_nowascCsl|idjo|i|||Sy|i|||SWn*|ij o}tt|nXdS(NR(RtdateRt RangeErrort ValueErrortstr(Rtyeartmonthtdayte((s9/usr/lib/python2.6/site-packages/formencode/validators.pytdatetime_makedategs cCs|idjo|iSdS(NR(Rttime(R((s9/usr/lib/python2.6/site-packages/formencode/validators.pyt datetime_timerscCs|idjo |iiSdS(NR(RRt isoformat(R((s9/usr/lib/python2.6/site-packages/formencode/validators.pytdatetime_isotimewst ConfirmTypecBsxeZdZd Zd Zhedd6edd6edd6edd6Zd Zd Z d Z d Z RS(s Confirms that the input/output is of the proper type. Uses the parameters: subclass: The class or a tuple of classes; the item must be an instance of the class or a subclass. type: A type or tuple of types (or classes); the item must be of the exact class or type. Subclasses are not allowed. Examples:: >>> cint = ConfirmType(subclass=int) >>> cint.to_python(True) True >>> cint.to_python('1') Traceback (most recent call last): ... Invalid: '1' is not a subclass of >>> cintfloat = ConfirmType(subclass=(float, int)) >>> cintfloat.to_python(1.0), cintfloat.from_python(1.0) (1.0, 1.0) >>> cintfloat.to_python(1), cintfloat.from_python(1) (1, 1) >>> cintfloat.to_python(None) Traceback (most recent call last): ... Invalid: None is not a subclass of one of the types , >>> cint2 = ConfirmType(type=int) >>> cint2(accept_python=False).from_python(True) Traceback (most recent call last): ... Invalid: True must be of the type s,%(object)r is not a subclass of %(subclass)stsubclasssA%(object)r is not a subclass of one of the types %(subclassList)st inSubclasss0%(object)r must be one of the types %(typeList)stinTypes'%(object)r must be of the type %(type)sttypecOsti||||io_t|itot|i|_n't|itp|if|_n|i|_n|io_t|itot|i|_n't|itp|if|_n|i |_ndS(N( tFancyValidatort__init__R t isinstancetlistttupletconfirm_subclasstvalidate_pythonR#t confirm_type(tselftargstkw((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR%s  cCst||ipt|idjo)|id|d|d|id}n:ditt|i}|id|d|d|}t|||ndS(NiR tobjectis, R!t subclassList(R&R tlentmessagetjointmapRtInvalid(R,tvaluetstatetmsgt subclass_list((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR)s c Csx|iD]}t||joPq q Wt|idjo)|id|d|d|id}n4|id|d|dditt|i}t||||S(NiR#R/iR"ttypeLists, (R#R1R2R3R4RR5(R,R6R7ttR8((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR+s  cCstS(N(tFalse(R,R6((s9/usr/lib/python2.6/site-packages/formencode/validators.pytis_emptysN( Rt __module__t__doc__RR R#t_tmessagesR%R)R+R=(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRs%     tWrappercBs8eZdZdZdZdZdZdZdZ RS(s Used to convert functions to validator/converters. You can give a simple function for `to_python`, `from_python`, `validate_python` or `validate_other`. If that function raises an exception, the value is considered invalid. Whatever value the function returns is considered the converted value. Unlike validators, the `state` argument is not used. Functions like `int` can be used here, that take a single argument. Examples:: >>> def downcase(v): ... return v.lower() >>> wrap = Wrapper(to_python=downcase) >>> wrap.to_python('This') 'this' >>> wrap.from_python('This') 'This' >>> wrap2 = Wrapper(from_python=downcase) >>> wrap2.from_python('This') 'this' >>> wrap2.from_python(1) Traceback (most recent call last): ... Invalid: 'int' object has no attribute 'lower' >>> wrap3 = Wrapper(validate_python=int) >>> wrap3.to_python('1') '1' >>> wrap3.to_python('a') # doctest: +ELLIPSIS Traceback (most recent call last): ... Invalid: invalid literal for int()... cOsxGddddgD]3}|i|o|||d|<||=qqWti||||i|i|_|i|i|_|i|i|_ |i|i |_ dS(Nt to_pythont from_pythonR*tvalidate_othersfunc_%s( thas_keyR$R%twraptfunc_to_pythont _to_pythontfunc_from_pythont _from_pythontfunc_validate_pythonR*tfunc_validate_otherRE(R,R-R.tn((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR%s cCs|pdS|d}|S(NcSsEy||SWn0tj o$}tt|h||nXdS(N(t ExceptionR5R(R6R7tfuncR((s9/usr/lib/python2.6/site-packages/formencode/validators.pytresults(R(R,RPRQ((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRGs N( RR>R?RRHRJRLRMR%RG(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRBs$ tConstantcBs#eZdZdZdZeZRS(sm This converter converts everything to the same thing. I.e., you pass in the constant value when initializing, then all values get converted to that constant value. This is only really useful for funny situations, like:: fromEmailValidator = ValidateAny( ValidEmailAddress(), Constant('unknown@localhost')) In this case, the if the email is not valid ``'unknown@localhost'`` will be used instead. Of course, you could use ``if_invalid`` instead. Examples:: >>> Constant('X').to_python('y') 'X' R6cCs|iS(N(R6(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRI8s(svalue(RR>R?t__unpackargs__RIRK(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRRs t MaxLengthcBs=eZdZdZhedd6edd6ZdZRS(s Invalid if the value is longer than `maxLength`. Uses len(), so it can work for strings, lists, or anything with length. Examples:: >>> max5 = MaxLength(5) >>> max5.to_python('12345') '12345' >>> max5.from_python('12345') '12345' >>> max5.to_python('123456') Traceback (most recent call last): ... Invalid: Enter a value less than 5 characters long >>> max5(accept_python=False).from_python('123456') Traceback (most recent call last): ... Invalid: Enter a value less than 5 characters long >>> max5.to_python([1, 2, 3]) [1, 2, 3] >>> max5.to_python([1, 2, 3, 4, 5, 6]) Traceback (most recent call last): ... Invalid: Enter a value less than 5 characters long >>> max5.to_python(5) Traceback (most recent call last): ... Invalid: Invalid value (value with length expected) t maxLengths5Enter a value less than %(maxLength)i characters longttooLongs*Invalid value (value with length expected)tinvalidc CsyP|oAt||ijo+t|id|d|i||ndSWn1tj o%t|id|||nXdS(NRVRURW(R1RUR5R2Rt TypeError(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR*hs (s maxLength(RR>R?RSR@RAR*(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRTAs  t MinLengthcBs=eZdZdZhedd6edd6ZdZRS(sb Invalid if the value is shorter than `minlength`. Uses len(), so it can work for strings, lists, or anything with length. Note that you **must** use ``not_empty=True`` if you don't want to accept empty values -- empty values are not tested for length. Examples:: >>> min5 = MinLength(5) >>> min5.to_python('12345') '12345' >>> min5.from_python('12345') '12345' >>> min5.to_python('1234') Traceback (most recent call last): ... Invalid: Enter a value at least 5 characters long >>> min5(accept_python=False).from_python('1234') Traceback (most recent call last): ... Invalid: Enter a value at least 5 characters long >>> min5.to_python([1, 2, 3, 4, 5]) [1, 2, 3, 4, 5] >>> min5.to_python([1, 2, 3]) Traceback (most recent call last): ... Invalid: Enter a value at least 5 characters long >>> min5.to_python(5) Traceback (most recent call last): ... Invalid: Invalid value (value with length expected) t minLengths4Enter a value at least %(minLength)i characters longttooShorts*Invalid value (value with length expected)RWc Cs}yEt||ijo+t|id|d|i||nWn1tj o%t|id|||nXdS(NR[RZRW(R1RZR5R2RX(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR*s (s minLength(RR>R?RSR@RAR*(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRYus " tNotEmptycBs0eZdZeZhedd6ZdZRS(s Invalid if value is empty (empty string, empty list, etc). Generally for objects that Python considers false, except zero which is not considered invalid. Examples:: >>> ne = NotEmpty(messages={'empty': 'enter something'}) >>> ne.to_python('') Traceback (most recent call last): ... Invalid: enter something >>> ne.to_python(0) 0 sPlease enter a valuetemptycCs?|djo|S|p"t|id|||ndS(NiR](R5R2(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR*s  (RR>R?tTruet not_emptyR@RAR*(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR\s tEmptycBs*eZdZhedd6ZdZRS(s Invalid unless the value is empty. Use cleverly, if at all. Examples:: >>> Empty.to_python(0) Traceback (most recent call last): ... Invalid: You cannot enter a value here sYou cannot enter a value heretnotEmptycCs:|p |djo"t|id|||ndS(NiRa(R5R2(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR*s(RR>R?R@RAR*(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR`s tRegexcBsTeZdZdZeZdZd Zhe dd6Z dZ dZ dZ RS( s Invalid if the value doesn't match the regular expression `regex`. The regular expression can be a compiled re object, or a string which will be compiled for you. Use strip=True if you want to strip the value before validation, and as a form of conversion (often useful). Examples:: >>> cap = Regex(r'^[A-Z]+$') >>> cap.to_python('ABC') 'ABC' Note that ``.from_python()`` calls (in general) do not validate the input:: >>> cap.from_python('abc') 'abc' >>> cap(accept_python=False).from_python('abc') Traceback (most recent call last): ... Invalid: The input is not valid >>> cap.to_python(1) Traceback (most recent call last): ... Invalid: The input must be a string (not a : 1) >>> Regex(r'^[A-Z]+$', strip=True).to_python(' ABC ') 'ABC' >>> Regex(r'this', regexOps=('I',)).to_python('THIS') 'THIS' tregexsThe input is not validRWcOsti|||t|itogd}xB|iD]7}t|to|tt|O}q6||O}q6Wti|i||_ndS(Ni( R$R%R&Rct basestringtregexOpstgetattrtretcompile(R,R-R.topstop((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR%s cCss|i|||io t|to|i}n|ii|p"t|id|||ndS(NRW(t assert_stringtstripR&RdRctsearchR5R2(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR*s cCs)|iot|to |iS|S(N(RlR&Rd(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRI$s (N(sregex(RR>R?ReR<RlRRcRSR@RAR%R*RI(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRbs"  t PlainTextcBs'eZdZdZhedd6ZRS(sK Test that the field contains only letters, numbers, underscore, and the hyphen. Subclasses Regex. Examples:: >>> PlainText.to_python('_this9_') '_this9_' >>> PlainText.from_python(' this ') ' this ' >>> PlainText(accept_python=False).from_python(' this ') Traceback (most recent call last): ... Invalid: Enter only letters, numbers, or _ (underscore) >>> PlainText(strip=True).to_python(' this ') 'this' >>> PlainText(strip=True).from_python(' this ') 'this' s^[a-zA-Z_\-0-9]*$s.Enter only letters, numbers, or _ (underscore)RW(RR>R?RcR@RA(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRn)stOneOfcBsOeZdZdZeZeZdZhe dd6e dd6Z dZ RS( se Tests that the value is one of the members of a given list. If ``testValueList=True``, then if the input value is a list or tuple, all the members of the sequence will be checked (i.e., the input must be a subset of the allowed values). Use ``hideList=True`` to keep the list of valid values out of the error message in exceptions. Examples:: >>> oneof = OneOf([1, 2, 3]) >>> oneof.to_python(1) 1 >>> oneof.to_python(4) Traceback (most recent call last): ... Invalid: Value must be one of: 1; 2; 3 (not 4) >>> oneof(testValueList=True).to_python([2, 3, [1, 2, 3]]) [2, 3, [1, 2, 3]] >>> oneof.to_python([2, 3, [1, 2, 3]]) Traceback (most recent call last): ... Invalid: Value must be one of: 1; 2; 3 (not [2, 3, [1, 2, 3]]) R's Invalid valueRWs/Value must be one of: %(items)s (not %(value)r)tnotIncCs|io;t|ttfo%x|D]}|i||q'Wn||ijou|io"t|id|||qdit t |i}t|id|d|d|||ndS(NRWs; RptitemsR6( t testValueListR&R'R(R*thideListR5R2R3R4R(R,R6R7tvRq((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR*ms  N(slist( RR>R?RR'R<RrRsRSR@RAR*(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRoEs t DictConvertercBsleZdZd ZeZd Zhedd6edd6edd6edd 6Z d Z d Z RS(sX Converts values based on a dictionary which has values as keys for the resultant values. If ``allowNull`` is passed, it will not balk if a false value (e.g., '' or None) is given (it will return None in these cases). to_python takes keys and gives values, from_python takes values and gives keys. If you give hideDict=True, then the contents of the dictionary will not show up in error messages. Examples:: >>> dc = DictConverter({1: 'one', 2: 'two'}) >>> dc.to_python(1) 'one' >>> dc.from_python('one') 1 >>> dc.to_python(3) Traceback (most recent call last): Invalid: Enter a value from: 1; 2 >>> dc2 = dc(hideDict=True) >>> dc2.hideDict True >>> dc2.dict {1: 'one', 2: 'two'} >>> dc2.to_python(3) Traceback (most recent call last): Invalid: Choose something >>> dc.from_python('three') Traceback (most recent call last): Invalid: Nothing in my dictionary goes by the value 'three'. Choose one of: 'one'; 'two' tdictsChoose somethingt keyNotFoundsEnter a value from: %(items)st chooseKeysThat value is not knownt valueNotFoundsONothing in my dictionary goes by the value %(value)s. Choose one of: %(items)st chooseValuecCsy|i|SWntj ox|io"t|id|||qditt|ii}t|id|d|||nXdS(NRws; RxRq( RvtKeyErrorthideDictR5R2R3R4treprtkeys(R,R6R7Rq((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRIs !c Csx/|iiD]\}}||jo|SqW|io"t|id|||nRditt|ii}t|id|dt|d|||dS(NRys; RzR6Rq( RvRqR|R5R2R3R4R}tvalues(R,R6R7tkRtRq((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRKs    ! N(sdict( RR>R?RRvR<R|RSR@RARIRK(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRu}s$    tIndexListConvertercBsYeZdZd Zd Zhedd6edd6edd6ZdZd Z RS( s Converts a index (which may be a string like '2') to the value in the given list. Examples:: >>> index = IndexListConverter(['zero', 'one', 'two']) >>> index.to_python(0) 'zero' >>> index.from_python('zero') 0 >>> index.to_python('1') 'one' >>> index.to_python(5) Traceback (most recent call last): Invalid: Index out of range >>> index(not_empty=True).to_python(None) Traceback (most recent call last): Invalid: Please enter a value >>> index.from_python('five') Traceback (most recent call last): Invalid: Item 'five' was not found in the list R'sMust be an integer indextintegersIndex out of ranget outOfRanges(Item %(value)s was not found in the listtnotFoundcCsyt|}Wn7ttfj o%t|id|||nXy|i|SWn1tj o%t|id|||nXdS(NRR(tintRRXR5R2R't IndexError(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRIsc Csgx6tt|iD]}|i||jo|SqWt|id|dt|||dS(NRR6(trangeR1R'R5R2R}(R,R6R7ti((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRKs  N(slist( RR>R?RR'RSR@RARIRK(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRs   t DateValidatorcBsoeZdZd Zd ZeZeZd Z he dd6e dd6e dd6e dd6Z d Z RS( s Validates that a date is within the given range. Be sure to call DateConverter first if you aren't expecting mxDateTime input. ``earliest_date`` and ``latest_date`` may be functions; if so, they will be called each time before validating. ``after_now`` means a time after the current timestamp; note that just a few milliseconds before now is invalid! ``today_or_after`` is more permissive, and ignores hours and minutes. Examples:: >>> from datetime import datetime, timedelta >>> d = DateValidator(earliest_date=datetime(2003, 1, 1)) >>> d.to_python(datetime(2004, 1, 1)) datetime.datetime(2004, 1, 1, 0, 0) >>> d.to_python(datetime(2002, 1, 1)) Traceback (most recent call last): ... Invalid: Date must be after Wednesday, 01 January 2003 >>> d.to_python(datetime(2003, 1, 1)) datetime.datetime(2003, 1, 1, 0, 0) >>> d = DateValidator(after_now=True) >>> now = datetime.now() >>> d.to_python(now+timedelta(seconds=5)) == now+timedelta(seconds=5) True >>> d.to_python(now-timedelta(days=1)) Traceback (most recent call last): ... Invalid: The date must be sometime in the future >>> d.to_python(now+timedelta(days=1)) > now True >>> d = DateValidator(today_or_after=True) >>> d.to_python(now) == now True sDate must be after %(date)staftersDate must be before %(date)stbefores%%A, %%d %%B %%Yt date_formats'The date must be sometime in the futuretfuturec Cs|id|}t|tod}|i|}nd}|iot|io|i}n |i}||joQ|i|}|o|i|}nt |id|d|||qn|i ot|i o|i }n |i }||joQ|i|}|o|i|}nt |id|d|||qkn|i o}t |i }t|} || joQ| i|}|o|i|}nt |id|d|||qn|iot |i }t|} t|| i| i| i} t||i|i|i} | | joQ| i|}|o|i|}nt |id|d|||qndS(NRtutf8RRRR(R2R&tunicodetencodeRt earliest_datetcallabletstrftimetdecodeR5t latest_datet after_nowR RRttoday_or_afterRRRR( R,R6R7RtencodingRtdate_formattedRtdt_modRttodayt value_as_date((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR*=sn            N( RR>R?RRRR<RRRR@RAR*(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRs'   tBoolcBs,eZdZeZdZeZdZRS(s Always Valid, returns True or False based on the value and the existance of the value. If you want to convert strings like ``'true'`` to booleans, then use ``StringBoolean``. Examples:: >>> Bool.to_python(0) False >>> Bool.to_python(1) True >>> Bool.to_python('') False >>> Bool.to_python(None) False cCs t|S(N(tbool(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRIscCstS(N(R<(R,R6((s9/usr/lib/python2.6/site-packages/formencode/validators.pyt empty_values(RR>R?R<t if_missingRIRKR(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR{s  tRangeValidatorcBsCeZdZhedd6edd6ZdZdZdZRS(sThis is an abstract base class for Int and Number. It verifies that a value is within range. It accepts min and max values in the constructor. (Since this is an abstract base class, the tests are in Int and Number.) s0Please enter a number that is %(min)s or greaterttooLows0Please enter a number that is %(max)s or smallerttooHighcCs|idj oE||ijo1|id|d|i}t|||qUn|idj oE||ijo1|id|d|i}t|||qndS(NRtminRtmax(RRR2R5R(R,R6R7R8((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR*sN( RR>R?R@RARRRR*(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRs  tIntcBs0eZdZhedd6ZdZeZRS(sConvert a value to an integer. Example:: >>> Int.to_python('10') 10 >>> Int.to_python('ten') Traceback (most recent call last): ... Invalid: Please enter an integer value >>> Int(min=5).to_python('6') 6 >>> Int(max=10).to_python('11') Traceback (most recent call last): ... Invalid: Please enter a number that is 10 or smaller sPlease enter an integer valueRcCsLyt|SWn7ttfj o%t|id|||nXdS(NR(RRRXR5R2(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRIs (RR>R?R@RARIRK(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRs  tNumbercBs*eZdZhedd6ZdZRS(s{Convert a value to a float or integer. Tries to convert it to an integer if no information is lost. Example:: >>> Number.to_python('10') 10 >>> Number.to_python('10.5') 10.5 >>> Number.to_python('ten') Traceback (most recent call last): ... Invalid: Please enter a number >>> Number(min=5).to_python('6.5') 6.5 >>> Number(max=10.5).to_python('11.5') Traceback (most recent call last): ... Invalid: Please enter a number that is 10.5 or smaller >>> Number().to_python('infinity') inf sPlease enter a numbertnumbercCsyRt|}yt|}Wntj o d}nX||jo|S|SWn1tj o%t|id|||nXdS(NR(tfloatRt OverflowErrorRRR5R2(R,R6R7t int_value((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRIs   (RR>R?R@RARI(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRstStringcBsyeZdZd Zd Zd Zd ZdZhe dd6e dd6Z dZ dZ dZ d Zd ZRS( sg Converts things to string, but treats empty things as the empty string. Also takes a `max` and `min` argument, and the string length must fall in that range. Also you may give an `encoding` argument, which will encode any unicode that is found. Lists and tuples are joined with `list_joiner` (default ``', '``) in ``from_python``. :: >>> String(min=2).to_python('a') Traceback (most recent call last): ... Invalid: Enter a value 2 characters long or more >>> String(max=10).to_python('xxxxxxxxxxx') Traceback (most recent call last): ... Invalid: Enter a value less than 10 characters long >>> String().from_python(None) '' >>> String().from_python([]) '' >>> String().to_python(None) '' >>> String(min=3).to_python(None) Traceback (most recent call last): ... Invalid: Please enter a value >>> String(min=1).to_python('') Traceback (most recent call last): ... Invalid: Please enter a value s, s/Enter a value less than %(max)i characters longRVs-Enter a value %(min)i characters long or moreR[cCs+|idjo|io t|_ndS(N(R_RRR^(R,t new_attrs((s9/usr/lib/python2.6/site-packages/formencode/validators.pyt __initargs__;scCs|p d}nt|tp6yt|}WqWtj ot|}qWXn|idj o&t|to|i|i}n|S(Nt(R&RdRtUnicodeEncodeErrorRRRR(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRI?s  cCs | o|djo d}nt|tpt|ttfo=|iig}|D]}||i||qY~}nyt|}Wqtj ot |}qXn|i dj o&t|t o|i |i }n|i o|i }n|S(NiR(R&RdR'R(t list_joinerR3RKRRRRRRRl(R,R6R7t_[1]Rt((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRKKs  4  cCs|idj oN|dj oAt||ijo+t|id|d|i||n|idj oI| pt||ijo+t|id|d|i||ndS(NRVRR[R(RRR1R5R2R(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRE\s  cCsdS(NR((R,R6((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRhsN(RR>R?RRRR_RRR@RARRIRKRER(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR s%    t UnicodeStringcBsQeZdZdZhedd6ZdddZdZdZ dZ RS( s Converts things to unicode string, this is a specialization of the String class. In addition to the String arguments, an encoding argument is also accepted. By default the encoding will be utf-8. All converted strings are returned as Unicode strings. :: >>> UnicodeString().to_python(None) u'' >>> UnicodeString().to_python([]) u'' >>> UnicodeString(encoding='utf-7').to_python('Ni Ni Ni') u'Ni Ni Ni' sutf-8s"Invalid data or incorrect encodingt badEncodingcKs:ti|||p|i|_|p|i|_dS(N(RR%Rt inputEncodingtoutputEncoding(R,RRR.((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR%scCs|pdSt|to|St|tp1t|dot|}|St|}nyt||iSWnstj o%t|id|||nDtj o7t|id|dt |d|||nXdS(Nut __unicode__RtbadTypeR#R6( R&RthasattrRRtUnicodeDecodeErrorR5R2RXR#(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRIs "cCsjt|tp0t|dot|}q@t|}nt|to|i|i}n|S(NR(R&RRRRR(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRKscCsdS(Nu((R,R6((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRsN( RR>R?RR@RARR%RIRKR(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRks  tSetcBs,eZdZeZdZdZdZRS(s This is for when you think you may return multiple values for a certain field. This way the result will always be a list, even if there's only one result. It's equivalent to ForEach(convertToList=True). If you give ``use_set=True``, then it will return an actual ``set`` object. :: >>> Set.to_python(None) [] >>> Set.to_python('this') ['this'] >>> Set.to_python(('this', 'that')) ['this', 'that'] >>> s = Set(use_set=True) >>> s.to_python(None) set([]) >>> s.to_python('this') set(['this']) >>> s.to_python(('this',)) set(['this']) cCs|ioet|ttifo|St|ttfo t|S|djotSt|gSnut|to|Sto$t|ttifo t|St|to t|S|djogS|gSdS(N(tuse_setR&tsettsetsRR'R(R(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRIs"       cCs|iotSgSdS(N(RR(R,R6((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRs ((RR>R?R<RRRIR(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRs  tEmailcBseZdZeZeideiZeideiei BZ he dd6e dd6e dd6e d d 6e d d 6e d d6Z dZ dZdZRS(s Validate an email address. If you pass ``resolve_domain=True``, then it will try to resolve the domain name to make sure it's valid. This takes longer, of course. You must have the `pyDNS `__ modules installed to look up DNS (MX and A) records. :: >>> e = Email() >>> e.to_python(' test@foo.com ') 'test@foo.com' >>> e.to_python('test') Traceback (most recent call last): ... Invalid: An email address must contain a single @ >>> e.to_python('test@foobar') Traceback (most recent call last): ... Invalid: The domain portion of the email address is invalid (the portion after the @: foobar) >>> e.to_python('test@foobar.com.5') Traceback (most recent call last): ... Invalid: The domain portion of the email address is invalid (the portion after the @: foobar.com.5) >>> e.to_python('test@foo..bar.com') Traceback (most recent call last): ... Invalid: The domain portion of the email address is invalid (the portion after the @: foo..bar.com) >>> e.to_python('test@.foo.bar.com') Traceback (most recent call last): ... Invalid: The domain portion of the email address is invalid (the portion after the @: .foo.bar.com) >>> e.to_python('nobody@xn--m7r7ml7t24h.com') 'nobody@xn--m7r7ml7t24h.com' >>> e.to_python('o*reilly@test.com') 'o*reilly@test.com' >>> e = Email(resolve_domain=True) >>> e.resolve_domain True >>> e.to_python('doesnotexist@colorstudy.com') 'doesnotexist@colorstudy.com' >>> e.to_python('test@forums.nyu.edu') 'test@forums.nyu.edu' >>> # NOTE: If you do not have PyDNS installed this example won't work: >>> e.to_python('test@thisdomaindoesnotexistithinkforsure.com') Traceback (most recent call last): ... Invalid: The domain of the email address does not exist (the portion after the @: thisdomaindoesnotexistithinkforsure.com) >>> e.to_python(u'test@google.com') u'test@google.com' >>> e = Email(not_empty=False) >>> e.to_python('') s^[^ \t\n\r@<>()]+$s ^(?:[a-z0-9][a-z0-9\-]{0,62}\.)+ # (sub)domain - alpha followed by 62max chars (63 total) [a-z]{2,}$ # TLD sPlease enter an email addressR]s(An email address must contain a single @tnoAts]The username portion of the email address is invalid (the portion before the @: %(username)s)t badUsernames@An error occured when trying to connect to the server: %(error)st socketErrorsXThe domain portion of the email address is invalid (the portion after the @: %(domain)s)t badDomainsTThe domain of the email address does not exist (the portion after the @: %(domain)s)tdomainDoesNotExistcOsRti||||io1tp&ddk}|idtdqNndS(NispyDNS is not installed on your system (or the DNS package cannot be found). I cannot resolve domain names in addressessno module named DNS(R$R%tresolve_domainthave_dnstwarningstwarnR(R,R-R.R((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR%/s  c Cs|p"t|id|||n|i}|idd}y|\}}Wn1tj o%t|id|||nX|ii|p(t|id|d|||n|ii|p(t|id|d|||n|ioypt i |d d i i }|p"t i |d d i i }ng}|D]}||d q`~} WnEt it ifj o-} t|id |d| ||nX| p(t|id|d|||qndS(NR]t@iRRtusernameRtdomaintqtypeR tatdataRterrorR(R5R2RltsplitRt usernameRERmtdomainRERtDNSt DnsRequesttreqtanswerstsocketRtDNSError( R,R6R7tsplittedRRRRtxt dnsdomainsR((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR*:sJ  ")cCs |iS(N(Rl(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRIbs(RR>R?R<RRgRhtIRtVERBOSERR@RAR%R*RI(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRs7      (tURLcBseZdZeZeZeZei dei ei BZ ei dZ hedd6edd6edd6ed d 6ed d 6ed d6edd6ZdZdZRS(s Validate a URL, either http://... or https://. If check_exists is true, then we'll actually make a request for the page. If add_http is true, then if no scheme is present we'll add http:// :: >>> u = URL(add_http=True) >>> u.to_python('foo.com') 'http://foo.com' >>> u.to_python('http://hahaha.ha/bar.html') 'http://hahaha.ha/bar.html' >>> u.to_python('http://xn--m7r7ml7t24h.com') 'http://xn--m7r7ml7t24h.com' >>> u.to_python('http://foo.com/test?bar=baz&fleem=morx') 'http://foo.com/test?bar=baz&fleem=morx' >>> u.to_python('http://foo.com/login?came_from=http%3A%2F%2Ffoo.com%2Ftest') 'http://foo.com/login?came_from=http%3A%2F%2Ffoo.com%2Ftest' >>> u.to_python('http://foo.com:8000/test.html') 'http://foo.com:8000/test.html' >>> u.to_python('http://foo.com/something\nelse') Traceback (most recent call last): ... Invalid: That is not a valid URL >>> u.to_python('https://test.com') 'https://test.com' >>> u.to_python('http://test') Traceback (most recent call last): ... Invalid: You must provide a full domain name (like test.com) >>> u.to_python('http://test..com') Traceback (most recent call last): ... Invalid: That is not a valid URL >>> u = URL(add_http=False, check_exists=True) >>> u.to_python('http://google.com') 'http://google.com' >>> u.to_python('google.com') Traceback (most recent call last): ... Invalid: You must start your URL with http://, https://, etc >>> u.to_python('http://ianbicking.org/doesnotexist.html') Traceback (most recent call last): ... Invalid: The server responded that the page could not be found >>> u.to_python('http://this.domain.does.not.exist.example.org/test.html') Traceback (most recent call last): ... Invalid: An error occured when trying to connect to the server: ... If you want to allow addresses without a TLD (e.g., ``localhost``) you can do:: >>> URL(require_tld=False).to_python('http://localhost') 'http://localhost' s ^(http|https):// (?:[%:\w]*@)? # authenticator (?P[a-z0-9][a-z0-9\-]{1,62}\.)* # (sub)domain - alpha followed by 62max chars (63 total) (?P[a-z]{2,}) # TLD (?::[0-9]+)? # port # files/delims/etc (?P/[a-z0-9\-\._~:/\?#\[\]@!%\$&\'\(\)\*\+,;=]*)? $ s ^[a-zA-Z]+:s3You must start your URL with http://, https://, etctnoSchemesThat is not a valid URLtbadURLs:An error occurred when trying to access the URL: %(error)st httpErrors@An error occured when trying to connect to the server: %(error)sRs5The server responded that the page could not be foundRs8The server responded with a bad status code (%(status)s)tstatuss9You must provide a full domain name (like %(domain)s.com)tnoTLDcCsk|i}|io%|ii|pd|}q;n|ii|}|p"t|id|||n|idi|t|id}|i i|}|p"t|id|||n|i oB|id o1t|id|d|id||n|i o4|i dp|i do|i ||n|S( Nshttp://RiRRRttldshttps://(Rltadd_httpt scheme_reRmR5R2tgroupR R1turl_ret require_tldt check_existst startswitht_check_url_exists(R,R6R7tmatch((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRIs.  ,c Cstdjoddkantdjoddkantdjoddkanti|d\}}}}}}|djo ti} n ti} y^| |} |o|d|7}n|o|d|7}n| id|| i} Wnwtij o-} t |i d|d| ||nti j o-} t |i d|d| ||nX| i d jo"t |i d |||n| i d jp| i d jo+t |i d |d | i ||ndS(Nithttpt;t?tHEADRRRiRiiR( thttplibRturlparseRtHTTPConnectiontHTTPSConnectiontrequestt getresponset HTTPExceptionR5R2RR( R,turlR7tschemetnetloctpathtparamstquerytfragmentt ConnClasstconntresR((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRsH       (RR>R?R<RR^RRRgRhRRRRR@RARIR(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRes";        tXRIcBseZdZeideieiBZeideiZeideiei BZ he dd6e dd6e dd 6e d d 6e d d 6e dd6e dd6Z e ddZdZddZdZdZRS(s Validator for XRIs. It supports both i-names and i-numbers, of the first version of the XRI standard. :: >>> inames = XRI(xri_type="i-name") >>> inames.to_python(" =John.Smith ") '=John.Smith' >>> inames.to_python("@Free.Software.Foundation") '@Free.Software.Foundation' >>> inames.to_python("Python.Software.Foundation") Traceback (most recent call last): ... Invalid: The type of i-name is not defined; it may be either individual or organizational >>> inames.to_python("http://example.org") Traceback (most recent call last): ... Invalid: The type of i-name is not defined; it may be either individual or organizational >>> inames.to_python("=!2C43.1A9F.B6F6.E8E6") Traceback (most recent call last): ... Invalid: "!2C43.1A9F.B6F6.E8E6" is an invalid i-name >>> iname_with_schema = XRI(True, xri_type="i-name") >>> iname_with_schema.to_python("=Richard.Stallman") 'xri://=Richard.Stallman' >>> inames.to_python("=John Smith") Traceback (most recent call last): ... Invalid: "John Smith" is an invalid i-name >>> inumbers = XRI(xri_type="i-number") >>> inumbers.to_python("!!1000!de21.4536.2cb2.8074") '!!1000!de21.4536.2cb2.8074' >>> inumbers.to_python("@!1000.9554.fabd.129c!2847.df3c") '@!1000.9554.fabd.129c!2847.df3c' s ^ [\w]+ # A global alphanumeric i-name (\.[\w]+)* # An i-name with dots (\*[\w]+(\.[\w]+)*)* # A community i-name $ s^[\d\.-]s ^ ( [=@]! # It's a personal or organization i-number | !! # It's a network i-number ) [\dA-F]{1,4}(\.[\dA-F]{1,4}){0,3} # A global i-number (![\dA-F]{1,4}(\.[\dA-F]{1,4}){0,3})* # Zero or more sub i-numbers $ sPThe type of i-name is not defined; it may be either individual or organizationaltnoTypes1Dots and dashes may not be repeated consecutivelyt repeatedChars "%(iname)s" is an invalid i-nametbadInames8i-names may not start with numbers nor punctuation markst badInameStarts$"%(inumber)s" is an invalid i-numbert badInumbers4The XRI must be a string (not a %(type)s: %(value)r)Rs)"%(xri_type)s" is not a valid type of XRItbadXrisi-namecKs,||_||_tt|i|dS(sPCreate an XRI validator. @param add_xri: Should the schema be added if not present? Officially it's optional. @type add_xri: C{bool} @param xri_type: What type of XRI should be validated? Possible values: C{i-name} or C{i-number}. @type xri_type: C{str} N(tadd_xritxri_typetsuperRR%(R,R R tkwargs((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR%Ms  cCs9|i}|io|id od|}n|S(sPPrepend the 'xri://' schema if necessary and then remove trailing spacessxri://(RlR R(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRI^s cCst|tp t|tp:t|id|dtt|d|||n|ido|d}n|ddjoD|id jo|dd j o"t|id |||n|id jo|i||n|i ||d S(sPValidate an XRI @raise Invalid: If at least one of the following conditions in met: - C{value} is not a string. - The XRI is not a personal, organizational or network one. - The relevant validator (i-name or i-number) considers the XRI is not valid. RR#R6sxri://iiRt=si-numbert!Rsi-nameN(RR( R&RRR5R2R#RR t_validate_inamet_validate_inumber(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR*fs $!"cCs|d}d|jp d|jo"t|id|||n|ii|o"t|id|||n|ii| p d|jo(t|id|d|||nd S( sValidate an i-nameis..s--RRR@RtinameN(R5R2tiname_invalid_startRtiname_valid_pattern(R,RR7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRs ""!cCsH|iii|p.t|id|d|d|||ndS(sValidate an i-numberRtinumberR6N(t __class__tinumber_patternRR5R2(R,RR7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRsN(RR>R?RgRhRtUNICODERRt IGNORECASERR@RAR<R%RIRR*RR(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRs&'          tOpenIdcBs?eZdZhedd6ZedZdZdZRS(s OpenId validator. :: >>> v = OpenId(add_schema=True) >>> v.to_python(' example.net ') 'http://example.net' >>> v.to_python('@TurboGears') 'xri://@TurboGears' >>> w = OpenId(add_schema=False) >>> w.to_python(' example.net ') Traceback (most recent call last): ... Invalid: "example.net" is not a valid OpenId (it is neither an URL nor an XRI) >>> w.to_python('!!1000') '!!1000' >>> w.to_python('look@me.com') Traceback (most recent call last): ... Invalid: "look@me.com" is not a valid OpenId (it is neither an URL nor an XRI) s@"%(id)s" is not a valid OpenId (it is neither an URL nor an XRI)tbadIdcKs@td||_t|dd|_t|dd|_dS(sCreate an OpenId validator. @param add_schema: Should the schema be added if not present? @type add_schema: C{bool} RR si-namesi-numberN(Rt url_validatorRtiname_validatortinumber_validator(R,t add_schemaR ((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR%sc Cs|i}y|ii||SWnmtj oay|ii||SWqtj o4y|ii||SWqtj oqXqXnXt|id|d|||dS(NRtid(RlRRCR5RRR2(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRIs cCs|i||dS(N(RI(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR*s( RR>R?R@RAR<R%RIR*(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRs  cOs3tidtddddkl}|||S(Ns.please use formencode.national.USStateProvincet stacklevelii(tUSStateProvince(RRtDeprecationWarningtformencode.nationalR"(R.R R"((s9/usr/lib/python2.6/site-packages/formencode/validators.pyt StateProvincescOs3tidtddddkl}|||S(Ns,please use formencode.national.USPhoneNumberR!ii(t USPhoneNumber(RRR#R$R&(R.R R&((s9/usr/lib/python2.6/site-packages/formencode/validators.pyt PhoneNumberscOs3tidtddddkl}|||S(Ns7please use formencode.national.InternationalPhoneNumberR!ii(tInternationalPhoneNumber(RRR#R$R((R.R R(((s9/usr/lib/python2.6/site-packages/formencode/validators.pytIPhoneNumberValidatorstFieldStorageUploadConvertercBs#eZdZddZdZRS(s Handles cgi.FieldStorage instances that are file uploads. This doesn't do any conversion, but it can detect empty upload fields (which appear like normal fields, but have no filename when no upload was given). cCsIt|tio.t|ddo|Std||n|SdS(NtfilenameRW(R&tcgit FieldStorageRfRR5(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRIs cCs;t|tiott|dd Sti||S(NR+(R&R,R-RRfRR$R=(R,R6((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR=sN(RR>R?RRIR=(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR*s tFileUploadKeepercBs5eZdZdZdZdZdZdZRS(s Takes two inputs (a dictionary with keys ``static`` and ``upload``) and converts them into one value on the Python side (a dictionary with ``filename`` and ``content`` keys). The upload takes priority over the static value. The filename may be None if it can't be discovered. Handles uploads of both text and ``cgi.FieldStorage`` upload values. This is basically for use when you have an upload field, and you want to keep the upload around even if the rest of the form submission fails. When converting *back* to the form submission, there may be extra values ``'original_filename'`` and ``'original_content'``, which may want to use in your form to show the user you still have their content around. To use this, make sure you are using variabledecode, then use something like:: Then in your scheme:: class MyScheme(Scheme): myfield = FileUploadKeeper() Note that big file uploads mean big hidden fields, and lots of bytes passed back and forth in the case of an error. tuploadtstaticcCs|i|i}|i|idi}d}}t|tio|i}|i }n(t|t o|od}|}n| oX|oQ|i dd\}}|djo d}n|i d}|i d}nh|d6|d6S(NRit-tbase64R+tcontent( tgett upload_keyt static_keyRlRR&R,R-R+R6RdRR(R,R6R7R/R0R+R3((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRIs       cCs|idd}|idd}|p|o9|i||}hd|i6||i6|d6|d6Shd|i6d|i6SdS(NR+RR3toriginal_filenametoriginal_content(R4t pack_contentR5R6(R,R6R7R+R3RQ((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRK,s    cCs@|i|pd}|pdid}d||f}|S(NR1RR2s%s %s(t base64encodeR(R,R+R3t enc_filenamet enc_contentRQ((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR99s(RR>R?R5R6RIRKR9(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR.s   t DateConvertercBseZdZeZdZdEZei dei Z ei dei Z hdd6dd6dd6dd 6d d 6d d 6d d6d d6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd 6dd!6d"d#6d"d$6d%d&6d%d'6Z h d(d6d)d6d(d 6d*d 6d(d6d*d6d(d6d(d6d*d6d(d6d*d"6d(d%6Zh ed+d,6ed-d.6ed/d06ed1d26ed3d46ed5d66ed7d86ed9d:6ed+d;6Zd<Zd=Zd>Zd?Zd@ZdAZdBZdCZdDZRS(Fs Validates and converts a string date, like mm/yy, dd/mm/yy, dd-mm-yy, etc. Using ``month_style`` you can support ``'mm/dd/yyyy'`` or ``'dd/mm/yyyy'``. Only these two general styles are supported. Accepts English month names, also abbreviated. Returns value as a datetime object (you can get mx.DateTime objects if you use ``datetime_module='mxDateTime'``). Two year dates are assumed to be within 1950-2020, with dates from 21-49 being ambiguous and signaling an error. Use accept_day=False if you just want a month/year (like for a credit card expiration date). :: >>> d = DateConverter() >>> d.to_python('12/3/09') datetime.date(2009, 12, 3) >>> d.to_python('12/3/2009') datetime.date(2009, 12, 3) >>> d.to_python('2/30/04') Traceback (most recent call last): ... Invalid: That month only has 29 days >>> d.to_python('13/2/05') Traceback (most recent call last): ... Invalid: Please enter a month from 1 to 12 >>> d.to_python('1/1/200') Traceback (most recent call last): ... Invalid: Please enter a four-digit year after 1899 If you change ``month_style`` you can get European-style dates:: >>> d = DateConverter(month_style='dd/mm/yyyy') >>> date = d.to_python('12/3/09') >>> date datetime.date(2009, 3, 12) >>> d.from_python(date) '12/03/2009' s mm/dd/yyyys^\s*(\d\d?)[\-\./\\](\d\d?|jan|january|feb|febuary|mar|march|apr|april|may|jun|june|jul|july|aug|august|sep|sept|september|oct|october|nov|november|dec|december)[\-\./\\](\d\d\d?\d?)\s*$s^\s*(\d\d?|jan|january|feb|febuary|mar|march|apr|april|may|jun|june|jul|july|aug|august|sep|sept|september|oct|october|nov|november|dec|december)[\-\./\\](\d\d\d?\d?)\s*$itjantjanuaryitfebtfebuaryitmartmarchitaprtaprilitmayitjuntjuneitjultjulyitaugtaugusti tseptseptt septemberi tocttoctoberi tnovtnovemberi tdectdecemberiiis,Please enter the date in the form %(format)st badFormats!Please enter a month from 1 to 12t monthRangesPlease enter a valid dayt invalidDays!That month only has %(days)i daystdayRanges'That is not a valid day (%(exception)s)t invalidDatesUnknown month name: %(month)stunknownMonthNames"Please enter a number for the yeart invalidYears)Please enter a four-digit year after 1899t fourDigitYeart wrongFormatcOsDtt|i|||idjotd|indS(Ns dd/mm/yyyys mm/dd/yyyysBad month_style: %r(s dd/mm/yyyys mm/dd/yyyy(R R=R%t month_styleRX(R,R-R.((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR%scCs/|io|i||S|i||SdS(N(t accept_dayt convert_dayt convert_month(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRIs c Cs |i|||ii|}|p+t|id|d|i||nt|id}yt|id}Wn.tj o"|i |id|}n#X|idjo||}}n|i |id|}|djp |djo"t|id|||n|djo"t|id |||n|i ||jo/t|id |d |i |||nt |i }yt||||SWn?tj o3}t|id |d t|||nXdS(NRVtformatiis mm/dd/yyyyii RWRXRYtdaysRZt exception(Rkt _day_date_reRmR5R2R_RRRXt make_montht make_yeart _monthDaysR RRRR( R,R6R7RRRRRRt((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRas>     cCs}yt|SWnhtj o\|ii}|ii|o |i|St|id|d|||nXdS(NR[R(RRR Rlt _month_namesRFR5R2(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRgs cCsyt|}Wn1tj o%t|id|||nX|djo|d}n|djo|djo|d}n|djo |djp|djo/|djo"t|id|||n|S( NR\iii2idilicR](RRR5R2(R,RR7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRhs 4cCs|ii|}|p(t|id|dd||n|i|id|}|i|id|}|djp |djo"t|id|||nt|i}t |||dS(NR^Rcsmm/yyyyiii RW( t_month_date_reRmR5R2RgRRhR RR(R,R6R7RRRR((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRbscCsL|itj o | odS|io|i||S|i||SdS(NR(tif_emptyt NoDefaultR`t unconvert_daytunconvert_month(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRKs  cCs/|idjo|idS|idSdS(Ns mm/dd/yyyys%m/%d/%Ys%d/%m/%Y(R_R(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRnscCs |idS(Ns%m/%Y(R(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRosN(RR>R?R^R`R_RRRgRhRRfRkRjRiR@RAR%RIRaRgRhRbRKRnRo(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR=?sR-8           "    t TimeConvertercBseZdZdZeZdZeZdZ h e dd6e dd6e dd6e dd 6e d d 6e d d 6e dd6e dd6e dd6Z dZ dZ dZRS(s5 Converts times in the format HH:MM:SSampm to (h, m, s). Seconds are optional. For ampm, set use_ampm = True. For seconds, use_seconds = True. Use 'optional' for either of these to make them optional. Examples:: >>> tim = TimeConverter() >>> tim.to_python('8:30') (8, 30) >>> tim.to_python('20:30') (20, 30) >>> tim.to_python('30:00') Traceback (most recent call last): ... Invalid: You must enter an hour in the range 0-23 >>> tim.to_python('13:00pm') Traceback (most recent call last): ... Invalid: You must enter an hour in the range 1-12 >>> tim.to_python('12:-1') Traceback (most recent call last): ... Invalid: You must enter a minute in the range 0-59 >>> tim.to_python('12:02pm') (12, 2) >>> tim.to_python('12:02am') (0, 2) >>> tim.to_python('1:00PM') (13, 0) >>> tim.from_python((13, 0)) '13:00:00' >>> tim2 = tim(use_ampm=True, use_seconds=False) >>> tim2.from_python((13, 0)) '1:00pm' >>> tim2.from_python((0, 0)) '12:00am' >>> tim2.from_python((12, 0)) '12:00pm' Examples with ``datetime.time``:: >>> v = TimeConverter(use_datetime=True) >>> a = v.to_python('18:00') >>> a datetime.time(18, 0) >>> b = v.to_python('30:00') Traceback (most recent call last): ... Invalid: You must enter an hour in the range 0-23 >>> v2 = TimeConverter(prefer_ampm=True, use_datetime=True) >>> v2.from_python(a) '6:00:00pm' >>> v3 = TimeConverter(prefer_ampm=True, ... use_seconds=False, use_datetime=True) >>> a = v3.to_python('18:00') >>> a datetime.time(18, 0) >>> v3.from_python(a) '6:00pm' >>> a = v3.to_python('18:00:00') Traceback (most recent call last): ... Invalid: You may not enter seconds toptionalsYou must indicate AM or PMtnoAMPMsThere are too many :'st tooManyColonsYou may not enter secondst noSecondssYou must enter secondstsecondsRequireds"You must enter minutes (after a :)tminutesRequireds7The %(part)s value you gave is not a number: %(number)rt badNumbers-You must enter an hour in the range %(range)stbadHours)You must enter a minute in the range 0-59t badMinutes)You must enter a second in the range 0-59t badSecondcCsJ|i||}|io&t|i}t|}||S|SdS(N(t_to_python_tuplet use_datetimeR RR(R,R6R7RQRt time_class((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRI\s    c Csg|i}t}|io|di}|djo<|idjo"t|id|||qd}qt}|djo d}nd}|d }nd}|id}t|d jo"t|id |||nt|d jo-|i o"t|id |||nt|d jo<|i o2|i djo"t|id |||nt|djo"t|id|||nyt |d}WnAt j o5t|id|d|ddd||nX|o|djp |djo.t|id|d|dd||n|djo|djoq|djo|djo d}q||7}nI|djp |djo.t|id|d|dd||nyt |d} WnAt j o5t|id|d|ddd||nX| djp | djo(t|id|d| ||nt|d joyt |d } Wn;t j o/t|id|d|d ddnX| djp | djo(t|id|d| ||q>nd} | djo || fS|| | fSdS(NitamtpmRqRrii t:iRsRtiRuiRvRwRtpartthourRxRs1-12is0-23tminutei;RytsecondRz(R~R( RlR<tuse_ampmR R5R2R^RR1t use_secondsRRR( R,R6R7Rt explicit_ampmtlast_twotoffsettpartsRRR((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR{es           cCsat|ttfo|St|do |i|i}}|i}nPt|djo|\}}}n*t|djo|\}}d}nd}|idjo |i p|ioi|idjoYd}|djo|d8}d }q-|djo d }q-|djo d}q-n|i od ||||fSd |||fSdS( NRiiiRRqR~i Rs%i:%02i:%02i%ss %i:%02i%s( R&RRRRRRR1Rt prefer_ampmR(R,R6R7RRRtampm((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRKs0          N(RR>R?RR<RRR|RRR@RARIR{RK(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRps&D         ^cOs3tidtddddkl}|||S(Ns+please use formencode.national.USPostalCodeR!ii(t USPostalCode(RRR#R$R(R.R R((s9/usr/lib/python2.6/site-packages/formencode/validators.pyt PostalCodest StripFieldcBs9eZdZdZhedd6ZdZdZRS(s Take a field from a dictionary, removing the key from the dictionary. ``name`` is the key. The field value and a new copy of the dictionary with that field removed are returned. >>> StripField('test').to_python({'a': 1, 'test': 2}) (2, {'a': 1}) >>> StripField('test').to_python({}) Traceback (most recent call last): ... Invalid: The name 'test' is missing tnamesThe name %(name)s is missingtmissingcCst|i}y||i}||i=Wn@tj o4t|id|dt|i||nX||fS(NRR(tcopyRR{R5R2R}(R,t valueDictR7Rttfield((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRIs  cCstS(N(R<(R,R6((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR= s(sname(RR>R?RSR@RARIR=(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRs  t StringBoolcBsceZdZddddddgZddd d d d gZhed d6ZdZdZRS(sf Converts a string to a boolean. Values like 'true' and 'false' are considered True and False, respectively; anything in ``true_values`` is true, anything in ``false_values`` is false, case-insensitive). The first item of those lists is considered the preferred form. :: >>> s = StringBoolean() >>> s.to_python('yes'), s.to_python('no') (True, False) >>> s.to_python(1), s.to_python('N') (True, False) >>> s.to_python('ye') Traceback (most recent call last): ... Invalid: Value should be 'true' or 'false' ttrueR;tyestytont1tfalsetftnoRNtofft0s%Value should be %(true)r or %(false)rtstringc Cst|ttfo|ii}||ijotS| p||ijotSt |i d|d|idd|id||nt |S(NRRiR( R&RRRlR t true_valuesR^t false_valuesR<R5R2R(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRI& s  cCs"|o |idS|idSdS(Ni(RR(R,R6R7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRK3 s ( RR>R?RRR@RARIRK(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR s  t SignedStringcBs^eZdZhedd6edd6Zd ZdZdZdZ dZ d Z RS( s Encodes a string into a signed string, and base64 encodes both the signature string and a random nonce. It is up to you to provide a secret, and to keep the secret handy and consistent. s"Value does not contain a signaturet malformedsSignature is not correcttbadsigic Cs.tp>yddklaWqEtj oddklaqEXn|idd}| pt|djo"t|id|||n|\}}|i d}|i d}||i }||i }tt |i ||i }||jo"t|id|||n|S(Ni(tsha1(tshaiRR2R(RthashlibRRRRR1R5R2Rt nonce_lengthRtsecrettdigest(R,R6R7Rtsigtresttnoncetexpected((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRIN s&   # cCstp>yddklaWqEtj oddklaqEXn|i}t|}t|i||i}|i|d|i||S(Ni(R(Rt ( RRRRt make_nonceRRRR(R,R6R7RR((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRKf s  cCs|idiiddS(NR2s R(RRltreplace(R,R6((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRr scCsWtpddkandig}t|iD]}|ttidq1~S(NiRi(trandomR3RRtchrt randrange(R,RR((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRu s N( RR>R?R@RARRRRIRKRR(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR< s   t IPAddresscBs+eZdZhdd6dd6ZdZRS(s Formencode validator to check whether a string is a correct IP address Examples:: >>> ip = IPAddress() >>> ip.to_python('127.0.0.1') '127.0.0.1' >>> ip.to_python('299.0.0.1') Traceback (most recent call last): ... Invalid: The octets must be within the range of 0-255 (not '299') >>> ip.to_python('192.168.0.1/1') Traceback (most recent call last): ... Invalid: Please enter a valid IP address (a.b.c.d) >>> ip.to_python('asdf') Traceback (most recent call last): ... Invalid: Please enter a valid IP address (a.b.c.d) u)Please enter a valid IP address (a.b.c.d)t bad_formatu<The octets must be within the range of 0-255 (not %(octet)r)tillegal_octetsc Csy|id}t|djo(t|id|d|||nx\|D]T}t|djpt|djo(t|id|d|||qTqTWWn1tj o%t|id|||nXdS( Nt.iRR6iiRtoctet(RR1R5R2RR(R,R6R7toctetsR((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR* s(&0(RR>R?RAR*(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR} s  tCIDRcBs2eZdZeeiddddZdZRS(s Formencode validator to check whether a string is in correct CIDR notation (IP address, or IP address plus /mask) Examples:: >>> cidr = CIDR() >>> cidr.to_python('127.0.0.1') '127.0.0.1' >>> cidr.to_python('299.0.0.1') Traceback (most recent call last): ... Invalid: The octets must be within the range of 0-255 (not '299') >>> cidr.to_python('192.168.0.1/1') Traceback (most recent call last): ... Invalid: The network size (bits) must be within the range of 8-32 (not '1') >>> cidr.to_python('asdf') Traceback (most recent call last): ... Invalid: Please enter a valid IP address (a.b.c.d) or IP network (a.b.c.d/e) RuCPlease enter a valid IP address (a.b.c.d) or IP network (a.b.c.d/e)t illegal_bitsuGThe network size (bits) must be within the range of 8-32 (not %(bits)r)c Csyd|jo|id\}}n|d}}ti|||t|djpt|djo(t|id|d|||nWn1tj o%t|id|||nXdS(Nt/i iRtbitsR(RRR*RR5R2R(R,R6R7taddrR((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR* s  &,(RR>R?RvRt _messagesRAR*(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR s   t MACAddresscBsOeZdZeZdZeZhedd6edd6Z dZ e Z RS(s Formencode validator to check whether a string is a correct hardware (MAC) address. Examples:: >>> mac = MACAddress() >>> mac.to_python('aa:bb:cc:dd:ee:ff') 'aabbccddeeff' >>> mac.to_python('aa:bb:cc:dd:ee:ff:e') Traceback (most recent call last): ... Invalid: A MAC address must contain 12 digits and A-F; the value you gave has 13 characters >>> mac.to_python('aa:bb:cc:dd:ee:fx') Traceback (most recent call last): ... Invalid: MAC addresses may only contain 0-9 and A-F (and optionally :), not 'x' >>> MACAddress(add_colons=True).to_python('aabbccddeeff') 'aa:bb:cc:dd:ee:ff' t0123456789abcdefABCDEFuZA MAC address must contain 12 digits and A-F; the value you gave has %(length)s characterst bad_lengthuKMAC addresses may only contain 0-9 and A-F (and optionally :), not %(char)rt bad_charactercCs|idd}|i}t|djo.t|id|dt|||nxF|D]>}||ijo(t|id|d|||qfqfW|ioJd|d d !|d d !|d d !|d d !|d d!|dd!f}n|S(NRRi RtlengthRtchars%s:%s:%s:%s:%s:%siiiiii (RR R1R5R2tvalid_characterst add_colons(R,R6R7taddressR((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRI s ., )( RR>R?R^RlRR<RR@RARIRK(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR s  t FormValidatorcBs)eZdZeZdZdZdZRS(sV A FormValidator is something that can be chained with a Schema. Unlike normal chaining the FormValidator can validate forms that aren't entirely valid. The important method is .validate(), of course. It gets passed a dictionary of the (processed) values from the form. If you have .validate_partial_form set to True, then it will get the incomplete values as well -- use .has_key() to test if the field was able to process any particular field. Anyway, .validate() should return a string or a dictionary. If a string, it's an error message that applies to the whole form. If not, then it should be a dictionary of fieldName: errorMessage. The special key "form" is the error message for the form as a whole (i.e., a string is equivalent to {"form": string}). Return None on no errors. cCstS(N(R<(R,R6((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR=! sN( RR>R?R<tvalidate_partial_formRtvalidate_partial_pythontvalidate_partial_otherR=(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR s tRequireIfMissingcBs/eZdZdZdZdZdZdZRS(sL This requires one field based on another field being present or missing. This is applied to a form, not an individual field (usually using a Schema's ``pre_validators`` or ``chained_validators``). If you provide a ``missing`` value (a string key name) then if that field is missing the field must be entered. This gives you an either/or situation. If you provide a ``present`` value (another string key name) then if that field is present, the required field must also be present. :: >>> from formencode import validators >>> v = validators.RequireIfPresent('phone_type', ... present='phone') >>> v.to_python({'phone_type':'', 'phone':'510 420 4577'}) Traceback (most recent call last): ... Invalid: You must give a value for phone_type >>> v.to_python({'phone': ''}) {'phone': ''} Note that if you have a validator on the optionally-required field, you should probably use ``if_missing=None``. This way you won't get an error from the Schema about a missing value. For example:: class PhoneInput(Schema): phone = PhoneNumber() phone_type = String(if_missing=None) chained_validators = [RequireifPresent('phone_type', present='phone')] trequiredc Cst}|io|i|i o t}n|io|i|io t}n|oY|i|i oEtd|it|dht|id|t||i6n|S(NsYou must give a value for %st error_dictR]( R<RR4R^tpresentRR5R6R2(R,t value_dictR7t is_required((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRIQ s     #N(srequired( RR>R?RRRRRSRI(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR$ s #t FieldsMatchcBsneZdZeZd ZeZd Z he dd6e dd6e dd6Z d Z d Z d ZRS(s Tests that the given fields match, i.e., are identical. Useful for password+confirmation fields. Pass the list of field names in as `field_names`. :: >>> f = FieldsMatch('pass', 'conf') >>> f.to_python({'pass': 'xx', 'conf': 'xx'}) {'conf': 'xx', 'pass': 'xx'} >>> f.to_python({'pass': 'xx', 'conf': 'yy'}) Traceback (most recent call last): ... Invalid: conf: Fields do not match Rt field_namess)Fields do not match (should be %(match)s)RWsFields do not matchtinvalidNoMatchsFields should be a dictionarytnotDictcOsCtt|i||t|idjotdndS(Nis/FieldsMatch() requires at least two field names(R RR%R1RRX(R,R-R.((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR%} scCs=x&|iD]}|i|pdSq W|i||dS(N(RRFR*(R,t field_dictR7R((s9/usr/lib/python2.6/site-packages/formencode/validators.pytvalidate_partial s   c CsSy||id}WnItj o%t|id|||ntj o d}nXh}xr|idD]c}|i|d|joD|io |id|d||| s%s: %sR( RRXR5R2R{R4t show_matchRqtsortR3( R,RR7trefterrorsRt error_listRR6t error_message((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR* s,"    4 N(Rs field_names(RR>R?R<RRRR^RRSR@RAR%RR*(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR` s    tCreditCardValidatorc BseZdZeZdZdZd/Zhedd6edd6ed d 6ed d 6Z d Z dZ dZ dZ hd0d1gd6d2d3d4d5d6gd6d7gd6d8d9gd 6d:d;d<d=d>d?d@dAgd*6dBdCdDgd.6ZRS(Esw Checks that credit card numbers are valid (if not real). You pass in the name of the field that has the credit card type and the field with the credit card number. The credit card type should be one of "visa", "mastercard", "amex", "dinersclub", "discover", "jcb". You must check the expiration date yourself (there is no relation between CC number/types and expiration dates). :: >>> cc = CreditCardValidator() >>> cc.to_python({'ccType': 'visa', 'ccNumber': '4111111111111111'}) {'ccNumber': '4111111111111111', 'ccType': 'visa'} >>> cc.to_python({'ccType': 'visa', 'ccNumber': '411111111111111'}) Traceback (most recent call last): ... Invalid: ccNumber: You did not enter a valid number of digits >>> cc.to_python({'ccType': 'visa', 'ccNumber': '411111111111112'}) Traceback (most recent call last): ... Invalid: ccNumber: You did not enter a valid number of digits >>> cc().to_python({}) Traceback (most recent call last): ... Invalid: The field ccType is missing tccTypetccNumbert cc_type_fieldtcc_number_fields1Please enter only the number, no other characterst notANumbers*You did not enter a valid number of digitst badLengthsThat number is not validt invalidNumbersThe field %(key)s is missingt missing_keycCsG|i|id p|i|id odS|i||dS(N(R4RRRR*(R,RR7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR scCs|i||}|of|i}|itdig}|D]\}}|d||fqC~||d|ndS(Ns
s%s: %sR(t_validateReturnRqRR5R3(R,RR7RRRRR6((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR* s   *c CsxO|i|ifD];}||jo(t|id|d|t|qqW||iii}||ii}|idd}|idd}yt|Wn*t j oh|id||i6SXt }t }xf|i |D]W\}} t || jo t }nt || jo|i|o t }PqqW|ph|id||i6S|ph|id||i6S|i|ph|id||i6SdS( NRtkeyRRR1RRR(RRR5R2R6R RlRtlongRR<t _cardInfoR1R^Rt_validateMod10R( R,RR7RRRt foundValidt validLengthtprefixR((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR s< )   cCsd}d}xktt|dddD]M}x6t|dt||D]}|t|}qNW|dd}q)W|ddjS(s? This code by Sean Reifschneider, of tummy.com iiiii (RR1RR(R,RtdoubletsumRtc((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR st4ii tvisat51t52t53t54t55t mastercardt6011tdiscovert34it37tamext300it301t302t303t304t305t36t38t dinersclubt3t2131t1800tjcb(s cc_type_fieldscc_number_field(Ri(Ri (Ri(Ri(Ri(Ri(Ri(Ri(Ri(Ri(Ri(Ri(Ri(Ri(Ri(Ri(Ri(R i(R i(R i(R i(RR>R?R^RRRRSR@RARR*RRR(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR sH     "      tCreditCardExpirescBsgeZdZeZdZdZd Zd Z he dd6e dd6Z d Z d Z d ZRS(s Checks that credit card expiration date is valid relative to the current date. You pass in the name of the field that has the credit card expiration month and the field with the credit card expiration year. :: >>> ed = CreditCardExpires() >>> ed.to_python({'ccExpiresMonth': '11', 'ccExpiresYear': '2250'}) {'ccExpiresYear': '2250', 'ccExpiresMonth': '11'} >>> ed.to_python({'ccExpiresMonth': '10', 'ccExpiresYear': '2005'}) Traceback (most recent call last): ... Invalid: ccExpiresMonth: Invalid Expiration Date
ccExpiresYear: Invalid Expiration Date tccExpiresMontht ccExpiresYeartcc_expires_month_fieldtcc_expires_year_fields,Please enter numbers only for month and yearRsInvalid Expiration DateRcCsG|i|id p|i|id odS|i||dS(N(R4RRRR*(R,RR7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRE scCs|i||}|of|i}|itdig}|D]\}}|d||fqC~||d|ndS(Ns
s%s: %sR(RRqRR5R3(R,RR7RRRRR6((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR*K s   *c CsQt||ii}t||ii}yt|}t|}t|i}t|}t||i |i |i }|dd}|djo|d} n|} t|| |d} Wnt j o4h|i d||i6|i d||i6Stj o4h|i d||i6|i d||i6SXdS(Ni iRR(RRRlRRR RRRRRRRR2tAssertionError( R,RR7RRRRRt next_monthtnext_month_yeart expires_date((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRU s(    (scc_expires_month_fieldscc_expires_year_fieldN(RR>R?R^RRRRSRRR@RARR*R(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR# s   tCreditCardSecurityCodecBseZdZeZdZdZdZhedd6edd6Z d Z d Z d Z hd d 6d d6d d6dd6Z RS(sN Checks that credit card security code has the correct number of digits for the given credit card type. You pass in the name of the field that has the credit card type and the field with the credit card security code. :: >>> code = CreditCardSecurityCode() >>> code.to_python({'ccType': 'visa', 'ccCode': '111'}) {'ccType': 'visa', 'ccCode': '111'} >>> code.to_python({'ccType': 'visa', 'ccCode': '1111'}) Traceback (most recent call last): ... Invalid: ccCode: Invalid credit card security code length RtccCodeRt cc_code_fields7Please enter numbers only for credit card security codeRs(Invalid credit card security code lengthRcCsG|i|id p|i|id odS|i||dS(N(R4RRRR*(R,RR7((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR scCs|i||}|of|i}|itdig}|D]\}}|d||fqC~||d|ndS(Ns
s%s: %sR(RRqRR5R3(R,RR7RRRRR6((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR* s   *cCst||ii}t||ii}yt|Wn*tj oh|id||i6SX|i|}t}t ||jo t }n|ph|id||i6SdS(NRR( RRRlRRRR2RR<R1R^(R,RR7RRRR((s9/usr/lib/python2.6/site-packages/formencode/validators.pyR s  iRRRiR(s cc_type_fields cc_code_field(RR>R?R^RRRRSR@RARR*RR(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyRm s    R5([R?RRgRRRRRt interfacestapiRRtfilterst simplefilterR#RRt NameErrorRR,t fieldstorageRtDiscoverNameServersR^RRR<R@RR R RRRRR$RRBRRRTRYR\R`RbRnRoRuRRRRRRRRRRRRR%R'R)R*R.R=RpRRRt StringBooleanRRRRRRtRequireIfPresentRRRRt__all__tglobalsRqRR6R&R#t issubclasst Validatortappend(((s9/usr/lib/python2.6/site-packages/formencode/validators.pyts                    \A#45 I8M8y#.b==:   K '0A,//:AJH