We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
IS_EMPTY_OR validator returns incorrect "empty" value
When setting default validators, the https://github.com/web2py/web2py/commit/bdbc053285b67fd3ee02f2ea862b30ca495f33e2 commit mistakenly sets the `null` attribute of the `IS_EMPTY_OR` validator to `''` for _all_ field types rather than just the string based field types.

[This line](https://github.com/web2py/web2py/blob/1877f497309e71918aa78e1a1288cbe3cb5392ec/gluon/dal.py#L81):

```
 requires[0] = validators.IS_EMPTY_OR(requires[0], null='' if field in ('string', 'text', 'password') else None)
```

should instead be:

```
 requires[0] = validators.IS_EMPTY_OR(requires[0], null='' if field.type in ('string', 'text', 'password') else None)
```

Notice, `field.type` rather than `field`.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `gluon/dal.py`
Content:
```
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 
4 """
5 | This file is part of the web2py Web Framework
6 | Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
7 | License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
8 
9 Takes care of adapting pyDAL to web2py's needs
10 -----------------------------------------------
11 """
12 
13 from pydal import DAL as DAL
14 from pydal import Field
15 from pydal.objects import Row, Rows, Table, Query, Set, Expression
16 from pydal import SQLCustomType, geoPoint, geoLine, geoPolygon
17 
18 def _default_validators(db, field):
19     """
20     Field type validation, using web2py's validators mechanism.
21 
22     makes sure the content of a field is in line with the declared
23     fieldtype
24     """
25     from gluon import validators
26     field_type, field_length = field.type, field.length
27     requires = []
28 
29     if field_type in (('string', 'text', 'password')):
30         requires.append(validators.IS_LENGTH(field_length))
31     elif field_type == 'json':
32         requires.append(validators.IS_EMPTY_OR(validators.IS_JSON()))
33     elif field_type == 'double' or field_type == 'float':
34         requires.append(validators.IS_FLOAT_IN_RANGE(-1e100, 1e100))
35     elif field_type == 'integer':
36         requires.append(validators.IS_INT_IN_RANGE(-2**31, 2**31))
37     elif field_type == 'bigint':
38         requires.append(validators.IS_INT_IN_RANGE(-2**63, 2**63))
39     elif field_type.startswith('decimal'):
40         requires.append(validators.IS_DECIMAL_IN_RANGE(-10**10, 10**10))
41     elif field_type == 'date':
42         requires.append(validators.IS_DATE())
43     elif field_type == 'time':
44         requires.append(validators.IS_TIME())
45     elif field_type == 'datetime':
46         requires.append(validators.IS_DATETIME())
47     elif db and field_type.startswith('reference') and \
48             field_type.find('.') < 0 and \
49             field_type[10:] in db.tables:
50         referenced = db[field_type[10:]]
51         if hasattr(referenced, '_format') and referenced._format:
52             requires = validators.IS_IN_DB(db, referenced._id,
53                                            referenced._format)
54             if field.unique:
55                 requires._and = validators.IS_NOT_IN_DB(db, field)
56             if field.tablename == field_type[10:]:
57                 return validators.IS_EMPTY_OR(requires)
58             return requires
59     elif db and field_type.startswith('list:reference') and \
60             field_type.find('.') < 0 and \
61             field_type[15:] in db.tables:
62         referenced = db[field_type[15:]]
63         if hasattr(referenced, '_format') and referenced._format:
64             requires = validators.IS_IN_DB(db, referenced._id,
65                                            referenced._format, multiple=True)
66         else:
67             requires = validators.IS_IN_DB(db, referenced._id,
68                                            multiple=True)
69         if field.unique:
70             requires._and = validators.IS_NOT_IN_DB(db, field)
71         if not field.notnull:
72             requires = validators.IS_EMPTY_OR(requires)
73         return requires
74     # does not get here for reference and list:reference
75     if field.unique:
76         requires.insert(0, validators.IS_NOT_IN_DB(db, field))
77     excluded_fields = ['string', 'upload', 'text', 'password', 'boolean']
78     if (field.notnull or field.unique) and not field_type in excluded_fields:
79         requires.insert(0, validators.IS_NOT_EMPTY())
80     elif not field.notnull and not field.unique and requires:
81         requires[0] = validators.IS_EMPTY_OR(requires[0], null='' if field in ('string', 'text', 'password') else None)
82     return requires
83 
84 from gluon.serializers import custom_json, xml
85 from gluon.utils import web2py_uuid
86 from gluon import sqlhtml
87 
88 
89 DAL.serializers = {'json': custom_json, 'xml': xml}
90 DAL.validators_method = _default_validators
91 DAL.uuid = lambda x: web2py_uuid()
92 DAL.representers = {
93     'rows_render': sqlhtml.represent,
94     'rows_xml': sqlhtml.SQLTABLE
95 }
96 DAL.Field = Field
97 DAL.Table = Table
98 
99 #: add web2py contrib drivers to pyDAL
100 from pydal.drivers import DRIVERS
101 if not DRIVERS.get('pymysql'):
102     try:
103         from .contrib import pymysql
104         DRIVERS['pymysql'] = pymysql
105     except:
106         pass
107 if not DRIVERS.get('pyodbc'):
108     try:
109         from .contrib import pypyodbc as pyodbc
110         DRIVERS['pyodbc'] = pyodbc
111     except:
112         pass
113 if not DRIVERS.get('pg8000'):
114     try:
115         from .contrib import pg8000
116         DRIVERS['pg8000'] = pg8000
117     except:
118         pass
119
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/gluon/dal.py b/gluon/dal.py
--- a/gluon/dal.py
+++ b/gluon/dal.py
@@ -75,10 +75,10 @@
     if field.unique:
         requires.insert(0, validators.IS_NOT_IN_DB(db, field))
     excluded_fields = ['string', 'upload', 'text', 'password', 'boolean']
-    if (field.notnull or field.unique) and not field_type in excluded_fields:
+    if (field.notnull or field.unique) and field_type not in excluded_fields:
         requires.insert(0, validators.IS_NOT_EMPTY())
     elif not field.notnull and not field.unique and requires:
-        requires[0] = validators.IS_EMPTY_OR(requires[0], null='' if field in ('string', 'text', 'password') else None)
+        requires[0] = validators.IS_EMPTY_OR(requires[0], null='' if field.type in ('string', 'text', 'password') else None)
     return requires
 
 from gluon.serializers import custom_json, xml

{"golden_diff": "diff --git a/gluon/dal.py b/gluon/dal.py\n--- a/gluon/dal.py\n+++ b/gluon/dal.py\n@@ -75,10 +75,10 @@\n     if field.unique:\n         requires.insert(0, validators.IS_NOT_IN_DB(db, field))\n     excluded_fields = ['string', 'upload', 'text', 'password', 'boolean']\n-    if (field.notnull or field.unique) and not field_type in excluded_fields:\n+    if (field.notnull or field.unique) and field_type not in excluded_fields:\n         requires.insert(0, validators.IS_NOT_EMPTY())\n     elif not field.notnull and not field.unique and requires:\n-        requires[0] = validators.IS_EMPTY_OR(requires[0], null='' if field in ('string', 'text', 'password') else None)\n+        requires[0] = validators.IS_EMPTY_OR(requires[0], null='' if field.type in ('string', 'text', 'password') else None)\n     return requires\n \n from gluon.serializers import custom_json, xml\n", "issue": "IS_EMPTY_OR validator returns incorrect \"empty\" value\nWhen setting default validators, the https://github.com/web2py/web2py/commit/bdbc053285b67fd3ee02f2ea862b30ca495f33e2 commit mistakenly sets the `null` attribute of the `IS_EMPTY_OR` validator to `''` for _all_ field types rather than just the string based field types.\n\n[This line](https://github.com/web2py/web2py/blob/1877f497309e71918aa78e1a1288cbe3cb5392ec/gluon/dal.py#L81):\n\n```\n requires[0] = validators.IS_EMPTY_OR(requires[0], null='' if field in ('string', 'text', 'password') else None)\n```\n\nshould instead be:\n\n```\n requires[0] = validators.IS_EMPTY_OR(requires[0], null='' if field.type in ('string', 'text', 'password') else None)\n```\n\nNotice, `field.type` rather than `field`.\n\n", "before_files": [{"content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n\"\"\"\n| This file is part of the web2py Web Framework\n| Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>\n| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)\n\nTakes care of adapting pyDAL to web2py's needs\n-----------------------------------------------\n\"\"\"\n\nfrom pydal import DAL as DAL\nfrom pydal import Field\nfrom pydal.objects import Row, Rows, Table, Query, Set, Expression\nfrom pydal import SQLCustomType, geoPoint, geoLine, geoPolygon\n\ndef _default_validators(db, field):\n    \"\"\"\n    Field type validation, using web2py's validators mechanism.\n\n    makes sure the content of a field is in line with the declared\n    fieldtype\n    \"\"\"\n    from gluon import validators\n    field_type, field_length = field.type, field.length\n    requires = []\n\n    if field_type in (('string', 'text', 'password')):\n        requires.append(validators.IS_LENGTH(field_length))\n    elif field_type == 'json':\n        requires.append(validators.IS_EMPTY_OR(validators.IS_JSON()))\n    elif field_type == 'double' or field_type == 'float':\n        requires.append(validators.IS_FLOAT_IN_RANGE(-1e100, 1e100))\n    elif field_type == 'integer':\n        requires.append(validators.IS_INT_IN_RANGE(-2**31, 2**31))\n    elif field_type == 'bigint':\n        requires.append(validators.IS_INT_IN_RANGE(-2**63, 2**63))\n    elif field_type.startswith('decimal'):\n        requires.append(validators.IS_DECIMAL_IN_RANGE(-10**10, 10**10))\n    elif field_type == 'date':\n        requires.append(validators.IS_DATE())\n    elif field_type == 'time':\n        requires.append(validators.IS_TIME())\n    elif field_type == 'datetime':\n        requires.append(validators.IS_DATETIME())\n    elif db and field_type.startswith('reference') and \\\n            field_type.find('.') < 0 and \\\n            field_type[10:] in db.tables:\n        referenced = db[field_type[10:]]\n        if hasattr(referenced, '_format') and referenced._format:\n            requires = validators.IS_IN_DB(db, referenced._id,\n                                           referenced._format)\n            if field.unique:\n                requires._and = validators.IS_NOT_IN_DB(db, field)\n            if field.tablename == field_type[10:]:\n                return validators.IS_EMPTY_OR(requires)\n            return requires\n    elif db and field_type.startswith('list:reference') and \\\n            field_type.find('.') < 0 and \\\n            field_type[15:] in db.tables:\n        referenced = db[field_type[15:]]\n        if hasattr(referenced, '_format') and referenced._format:\n            requires = validators.IS_IN_DB(db, referenced._id,\n                                           referenced._format, multiple=True)\n        else:\n            requires = validators.IS_IN_DB(db, referenced._id,\n                                           multiple=True)\n        if field.unique:\n            requires._and = validators.IS_NOT_IN_DB(db, field)\n        if not field.notnull:\n            requires = validators.IS_EMPTY_OR(requires)\n        return requires\n    # does not get here for reference and list:reference\n    if field.unique:\n        requires.insert(0, validators.IS_NOT_IN_DB(db, field))\n    excluded_fields = ['string', 'upload', 'text', 'password', 'boolean']\n    if (field.notnull or field.unique) and not field_type in excluded_fields:\n        requires.insert(0, validators.IS_NOT_EMPTY())\n    elif not field.notnull and not field.unique and requires:\n        requires[0] = validators.IS_EMPTY_OR(requires[0], null='' if field in ('string', 'text', 'password') else None)\n    return requires\n\nfrom gluon.serializers import custom_json, xml\nfrom gluon.utils import web2py_uuid\nfrom gluon import sqlhtml\n\n\nDAL.serializers = {'json': custom_json, 'xml': xml}\nDAL.validators_method = _default_validators\nDAL.uuid = lambda x: web2py_uuid()\nDAL.representers = {\n    'rows_render': sqlhtml.represent,\n    'rows_xml': sqlhtml.SQLTABLE\n}\nDAL.Field = Field\nDAL.Table = Table\n\n#: add web2py contrib drivers to pyDAL\nfrom pydal.drivers import DRIVERS\nif not DRIVERS.get('pymysql'):\n    try:\n        from .contrib import pymysql\n        DRIVERS['pymysql'] = pymysql\n    except:\n        pass\nif not DRIVERS.get('pyodbc'):\n    try:\n        from .contrib import pypyodbc as pyodbc\n        DRIVERS['pyodbc'] = pyodbc\n    except:\n        pass\nif not DRIVERS.get('pg8000'):\n    try:\n        from .contrib import pg8000\n        DRIVERS['pg8000'] = pg8000\n    except:\n        pass\n", "path": "gluon/dal.py"}], "after_files": [{"content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n\"\"\"\n| This file is part of the web2py Web Framework\n| Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>\n| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)\n\nTakes care of adapting pyDAL to web2py's needs\n-----------------------------------------------\n\"\"\"\n\nfrom pydal import DAL as DAL\nfrom pydal import Field\nfrom pydal.objects import Row, Rows, Table, Query, Set, Expression\nfrom pydal import SQLCustomType, geoPoint, geoLine, geoPolygon\n\ndef _default_validators(db, field):\n    \"\"\"\n    Field type validation, using web2py's validators mechanism.\n\n    makes sure the content of a field is in line with the declared\n    fieldtype\n    \"\"\"\n    from gluon import validators\n    field_type, field_length = field.type, field.length\n    requires = []\n\n    if field_type in (('string', 'text', 'password')):\n        requires.append(validators.IS_LENGTH(field_length))\n    elif field_type == 'json':\n        requires.append(validators.IS_EMPTY_OR(validators.IS_JSON()))\n    elif field_type == 'double' or field_type == 'float':\n        requires.append(validators.IS_FLOAT_IN_RANGE(-1e100, 1e100))\n    elif field_type == 'integer':\n        requires.append(validators.IS_INT_IN_RANGE(-2**31, 2**31))\n    elif field_type == 'bigint':\n        requires.append(validators.IS_INT_IN_RANGE(-2**63, 2**63))\n    elif field_type.startswith('decimal'):\n        requires.append(validators.IS_DECIMAL_IN_RANGE(-10**10, 10**10))\n    elif field_type == 'date':\n        requires.append(validators.IS_DATE())\n    elif field_type == 'time':\n        requires.append(validators.IS_TIME())\n    elif field_type == 'datetime':\n        requires.append(validators.IS_DATETIME())\n    elif db and field_type.startswith('reference') and \\\n            field_type.find('.') < 0 and \\\n            field_type[10:] in db.tables:\n        referenced = db[field_type[10:]]\n        if hasattr(referenced, '_format') and referenced._format:\n            requires = validators.IS_IN_DB(db, referenced._id,\n                                           referenced._format)\n            if field.unique:\n                requires._and = validators.IS_NOT_IN_DB(db, field)\n            if field.tablename == field_type[10:]:\n                return validators.IS_EMPTY_OR(requires)\n            return requires\n    elif db and field_type.startswith('list:reference') and \\\n            field_type.find('.') < 0 and \\\n            field_type[15:] in db.tables:\n        referenced = db[field_type[15:]]\n        if hasattr(referenced, '_format') and referenced._format:\n            requires = validators.IS_IN_DB(db, referenced._id,\n                                           referenced._format, multiple=True)\n        else:\n            requires = validators.IS_IN_DB(db, referenced._id,\n                                           multiple=True)\n        if field.unique:\n            requires._and = validators.IS_NOT_IN_DB(db, field)\n        if not field.notnull:\n            requires = validators.IS_EMPTY_OR(requires)\n        return requires\n    # does not get here for reference and list:reference\n    if field.unique:\n        requires.insert(0, validators.IS_NOT_IN_DB(db, field))\n    excluded_fields = ['string', 'upload', 'text', 'password', 'boolean']\n    if (field.notnull or field.unique) and field_type not in excluded_fields:\n        requires.insert(0, validators.IS_NOT_EMPTY())\n    elif not field.notnull and not field.unique and requires:\n        requires[0] = validators.IS_EMPTY_OR(requires[0], null='' if field.type in ('string', 'text', 'password') else None)\n    return requires\n\nfrom gluon.serializers import custom_json, xml\nfrom gluon.utils import web2py_uuid\nfrom gluon import sqlhtml\n\n\nDAL.serializers = {'json': custom_json, 'xml': xml}\nDAL.validators_method = _default_validators\nDAL.uuid = lambda x: web2py_uuid()\nDAL.representers = {\n    'rows_render': sqlhtml.represent,\n    'rows_xml': sqlhtml.SQLTABLE\n}\nDAL.Field = Field\nDAL.Table = Table\n\n#: add web2py contrib drivers to pyDAL\nfrom pydal.drivers import DRIVERS\nif not DRIVERS.get('pymysql'):\n    try:\n        from .contrib import pymysql\n        DRIVERS['pymysql'] = pymysql\n    except:\n        pass\nif not DRIVERS.get('pyodbc'):\n    try:\n        from .contrib import pypyodbc as pyodbc\n        DRIVERS['pyodbc'] = pyodbc\n    except:\n        pass\nif not DRIVERS.get('pg8000'):\n    try:\n        from .contrib import pg8000\n        DRIVERS['pg8000'] = pg8000\n    except:\n        pass\n", "path": "gluon/dal.py"}]}