Custom validator broken in 2.18.4, working in 2.17.2

82 views
Skip to first unread message

David Manns

unread,
Apr 4, 2019, 4:52:37 PM4/4/19
to web2py-users
The table in question has a field:

    Field('Paiddate', 'date', requires = [IS_EMPTY_OR(IS_DATE()), IS_EMPTY_OR(IS_MEMBERSHIP_YEAR_END())]),

The custom validator is:

class IS_MEMBERSHIP_YEAR_END(object):
    def __init__(self, error_message='Not a membership year end'):
        self.error_message = error_message
    def __call__(self, value):
        yearend = datetime.date(2018,9,30)
        if value.month==yearend.month and value.day==yearend.day:
            return (value, None)
        return (value, self.error_message)

This works in 2.17.2

I updated my test environment to 2.18.4 and it fails.

On the console I see:

web2py Web Framework
Created by Massimo Di Pierro, Copyright 2007-2019
Version 2.18.4-stable+timestamp.2019.03.13.05.27.54
Database drivers available: sqlite3, imaplib, pyodbc, pymysql
please visit:
('\t', 'http://127.0.0.1:8000/')
starting browser...
Traceback (most recent call last):
  File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.1\gluon\html.py", line 1890, in _validate
    (value, errors) = validator(value)
  File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.1\gluon\packages\dal\pydal\validators.py", line 144, in __call__
    return self.validate(value), None
  File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.1\gluon\packages\dal\pydal\validators.py", line 2754, in validate
    return self.other.validate(value)
AttributeError: 'IS_MEMBERSHIP_YEAR_END' object has no attribute 'validate'

The ticket shows:

Error ticket for "init"

Ticket ID

127.0.0.1.2019-04-04.16-41-08.0dce185d-d8d2-4d36-9e47-8c82bc1d54f5

<type 'exceptions.Exception'> Validation error, field:Paiddate <pydal.validators.IS_EMPTY_OR object at 0x0000000004878048>

Version

web2py™ Version 2.18.4-stable+timestamp.2019.03.13.05.27.54
Python Python 2.7.14: C:\Python27\python.exe (prefix: C:\Python27)

Traceback

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
Traceback (most recent call last):
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.1\gluon\restricted.py", line 219, in restricted
exec(ccode, environment)
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.1\applications\init\controllers/default.py", line 1747, in <module>
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.1\gluon\globals.py", line 421, in <lambda>
self._caller = lambda f: f()
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.1\applications\init\models\db.py", line 109, in wrapped_f
return f(*args)
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.1\applications\init\controllers/default.py", line 214, in memberform
deletable = dltbl, onvalidation=setmodified, onaccept=modmember, ondelete=delmember)
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.1\gluon\tools.py", line 4322, in update
detect_record_change=self.settings.detect_record_change):
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.1\gluon\sqlhtml.py", line 1758, in accepts
**kwargs
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.1\gluon\html.py", line 2149, in accepts
status = self._traverse(status, hideerror)
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.1\gluon\html.py", line 910, in _traverse
newstatus = c._traverse(status, hideerror) and newstatus
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.1\gluon\html.py", line 910, in _traverse
newstatus = c._traverse(status, hideerror) and newstatus
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.1\gluon\html.py", line 910, in _traverse
newstatus = c._traverse(status, hideerror) and newstatus
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.1\gluon\html.py", line 910, in _traverse
newstatus = c._traverse(status, hideerror) and newstatus
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.1\gluon\html.py", line 917, in _traverse
newstatus = self._validate()
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.1\gluon\html.py", line 1895, in _validate
raise Exception(msg)
Exception: Validation error, field:Paiddate <pydal.validators.IS_EMPTY_OR object at 0x0000000004878048>

Kevin Keller

unread,
Apr 5, 2019, 11:35:55 AM4/5/19
to web2py-users
Could you create a ticket for this please? 

Thanks! 

--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to the Google Groups "web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to web2py+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

David Manns

unread,
Apr 5, 2019, 12:59:15 PM4/5/19
to web2py-users

Leonel Câmara

unread,
Apr 5, 2019, 2:07:22 PM4/5/19
to web2py-users
The way validators are in 2.18.4 you need to do it like this:


class IS_MEMBERSHIP_YEAR_END(Validator)
:
    def __init__(self, error_message='Not a membership year end'):
        self.error_message = error_message

    def validate(self, value):

        yearend = datetime.date(2018,9,30)
        if value.month==yearend.month and value.day==yearend.day:
            return value
        else:
            raise ValidationError(self.translator(self.error_message))

Anthony

unread,
Apr 5, 2019, 3:14:21 PM4/5/19
to web2py-users
Though that breaks backward compatibility, as the interface for custom validators is provided in the official documentation.

David Manns

unread,
Apr 6, 2019, 9:25:26 AM4/6/19
to web2py-users
The web2py book needs to be updated, as Anthony points out.

As suggested I changed the validator to:

class IS_MEMBERSHIP_YEAR_END(Validator):

    def __init__(self, error_message='Not a membership year end'):
        self.error_message = error_message
    def validate(self, value):

        yearend = datetime.date(2018,9,30)
        if value.month==yearend.month and value.day==yearend.day:
            return value
        else:
            raise ValidationError(self.translator(self.error_message))

Also added to the model:

from gluon.validators import Validator

If the entered value was a valid date that passed the test (9/30/nnnn) all was well. However the failure path produced a ticket, it looks as if the raised error is not being caught????


Ticket ID

127.0.0.1.2019-04-06.09-16-04.3787fce5-0056-4df3-9918-be34e83041be

<type 'exceptions.Exception'> Validation error, field:Paiddate <pydal.validators.IS_EMPTY_OR object at 0x000000000B261EB8>

):
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.2\gluon\restricted.py", line 219, in restricted
exec(ccode, environment)
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.2\applications\init\controllers/default.py", line 1747, in <module>
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.2\gluon\globals.py", line 421, in <lambda>
self._caller = lambda f: f
()
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.2\applications\init\models\db.py", line 110, in wrapped_f
return f(*args)
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.2\applications\init\controllers/default.py", line 214, in memberform

deletable = dltbl, onvalidation=setmodified, onaccept=modmember, ondelete=delmember
)
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.2\gluon\tools.py", line 4322, in update
detect_record_change=self.settings.detect_record_change):
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.2\gluon\sqlhtml.py", line 1758, in accepts
**kwargs
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.2\gluon\html.py", line 2149, in accepts
status = self._traverse(status, hideerror)
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.2\gluon\html.py", line 910, in _traverse

newstatus = c._traverse(status, hideerror) and newstatus
  File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.2\gluon\html.py", line 910, in _traverse

newstatus = c._traverse(status, hideerror) and newstatus
  File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.2\gluon\html.py", line 910, in _traverse

newstatus = c._traverse(status, hideerror) and newstatus
  File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.2\gluon\html.py", line 910, in _traverse

newstatus = c._traverse(status, hideerror) and newstatus
  File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.2\gluon\html.py", line 917, in _traverse
newstatus = self._validate()
File "C:\Users\David\Google Drive\Oxcamne Archive\Web Site\OxCamNE.2.2\gluon\html.py", line 1895, in _validate
raise Exception(msg)
Exception: Validation error, field:Paiddate <pydal.validators.IS_EMPTY_OR object at 0x000000000B261EB8>

On Thursday, April 4, 2019 at 4:52:37 PM UTC-4, David Manns wrote:

Leonel Câmara

unread,
Apr 6, 2019, 2:42:58 PM4/6/19
to web2py-users
Did you import ValidationError as well?

David Manns

unread,
Apr 6, 2019, 3:06:20 PM4/6/19
to web2py-users
Changed my import to:

from pydal.validators import Validator, ValidationError

class IS_MEMBERSHIP_YEAR_END(Validator):

    def __init__(self, error_message='Not a membership year end'):
        self.error_message = error_message
    def validate(self, value):

        yearend =  datetime.date(2018,9,30)
        if value.month==yearend.month and value.day==yearend.day:
            return value
        else:
            raise ValidationError(self.translator(self.error_message))

Now works with 2.18.4, thank you!

The 'book' needs to be updated!

On Thursday, April 4, 2019 at 4:52:37 PM UTC-4, David Manns wrote:

David Manns

unread,
Apr 6, 2019, 3:12:47 PM4/6/19
to web2py-users
PS this is not backward compatible to 2.17.2


On Thursday, April 4, 2019 at 4:52:37 PM UTC-4, David Manns wrote:

Anthony

unread,
Apr 6, 2019, 3:40:47 PM4/6/19
to web2py-users
The book should be update, but we should also decide if we're OK breaking backward compatibility in this way.

Anthony

Massimo Di Pierro

unread,
Apr 7, 2019, 12:36:13 AM4/7/19
to web2py-users
we will fix the backward incompatibility asap. Not intentional.

David Manns

unread,
Apr 9, 2019, 9:19:40 AM4/9/19
to web2py-users
The original version works with 2.18.5 Thank you!


On Thursday, April 4, 2019 at 4:52:37 PM UTC-4, David Manns wrote:
Reply all
Reply to author
Forward
Message has been deleted
0 new messages