Repository: web2py/web2py

Issue:
NameError: global name 'signature_list' is not defined
```python
Traceback (most recent call last):
  File "/Users/abhishesh/Dropbox/WORK/web2py/gluon/restricted.py", line 216, in restricted
    exec(ccode, environment)
  File "/Users/abhishesh/Dropbox/WORK/web2py/applications/artemis/models/db.py", line 231, in <module>
    auth.define_tables(username=False, signature=False, enable_tokens=True)
  File "/Users/abhishesh/Dropbox/WORK/web2py/gluon/tools.py", line 2238, in define_tables
    settings.table_token_name, []) + signature_list
NameError: global name 'signature_list' is not defined
```


Discussion:
I don't think this error exists in trunk, can you try it?
This happens when we do `enable_tokens=True` in `auth.define_tables()`. I'll check if there is a unit test around it !
by the way ! trunk == master is it !
Change to following in `gluon/tests/test_tools.py`

```python
self.auth.define_tables(username=True, signature=False, enable_tokens=True)
```
and run on master branch 
```
./web2py --run_system_tests
```
we get the error
@abhishesh you are right! Good catch of a bug due to the auth refactoring, I'll look into it.

Resolving patch:
diff --git a/gluon/authapi.py b/gluon/authapi.py
--- a/gluon/authapi.py
+++ b/gluon/authapi.py
@@ -244,11 +244,13 @@ def define_tables(self, username=None, signature=None, migrate=None,
             migrate = db._migrate
         if fake_migrate is None:
             fake_migrate = db._fake_migrate
+        
         settings = self.settings
         if username is None:
             username = settings.use_username
         else:
             settings.use_username = username
+        
         if not self.signature:
             self.define_signature()
         if signature is True:
@@ -259,6 +261,8 @@ def define_tables(self, username=None, signature=None, migrate=None,
             signature_list = [signature]
         else:
             signature_list = signature
+        self._table_signature_list = signature_list
+
         is_not_empty = IS_NOT_EMPTY(error_message=self.messages.is_empty)
         is_crypted = CRYPT(key=settings.hmac_key,
                            min_length=settings.password_min_length)
diff --git a/gluon/tools.py b/gluon/tools.py
--- a/gluon/tools.py
+++ b/gluon/tools.py
@@ -2214,7 +2214,7 @@ def define_tables(self, username=None, signature=None, enable_tokens=False,
             fake_migrate = db._fake_migrate
         settings = self.settings
         settings.enable_tokens = enable_tokens
-        super(Auth, self).define_tables(username, signature, migrate, fake_migrate)
+        signature_list = super(Auth, self).define_tables(username, signature, migrate, fake_migrate)._table_signature_list
 
         now = current.request.now
         reference_table_user = 'reference %s' % settings.table_user_name
@@ -3759,11 +3759,10 @@ def profile(self,
             extra_fields = self.settings.extra_fields.get(self.settings.table_user_name, [])
             if any(f.compute for f in extra_fields):
                 user = table_user[self.user.id]
-                self._update_session_user(user) 
+                self._update_session_user(user)
             else:
                 self.user.update(table_user._filter_fields(form.vars))
 
-            
             session.flash = self.messages.profile_updated
             self.log_event(log, self.user)
             callback(onaccept, form)
@@ -4220,15 +4219,15 @@ def wikimenu(self):
 class Crud(object):  # pragma: no cover
 
     default_messages = dict(
-        submit_button = 'Submit',
-        delete_label = 'Check to delete',
-        record_created = 'Record Created',
-        record_updated = 'Record Updated',
-        record_deleted = 'Record Deleted',
-        update_log = 'Record %(id)s updated',
-        create_log = 'Record %(id)s created',
-        read_log = 'Record %(id)s read',
-        delete_log = 'Record %(id)s deleted',
+        submit_button='Submit',
+        delete_label='Check to delete',
+        record_created='Record Created',
+        record_updated='Record Updated',
+        record_deleted='Record Deleted',
+        update_log='Record %(id)s updated',
+        create_log='Record %(id)s created',
+        read_log='Record %(id)s read',
+        delete_log='Record %(id)s deleted',
     )
 
     def url(self, f=None, args=None, vars=None):
@@ -4809,7 +4808,7 @@ class Service(object):
 
     def __init__(self, environment=None, check_args=False):
         self.check_args = check_args
-        
+
         self.run_procedures = {}
         self.csv_procedures = {}
         self.xml_procedures = {}
@@ -5067,7 +5066,7 @@ def serve_run(self, args=None):
             args = request.args
         if args and args[0] in self.run_procedures:
             return str(self.call_service_function(self.run_procedures[args[0]],
-                                        *args[1:], **dict(request.vars)))
+                                                  *args[1:], **dict(request.vars)))
         self.error()
 
     def serve_csv(self, args=None):
@@ -5088,7 +5087,7 @@ def none_exception(value):
         if args and args[0] in self.csv_procedures:
             import types
             r = self.call_service_function(self.csv_procedures[args[0]],
-                                 *args[1:], **dict(request.vars))
+                                           *args[1:], **dict(request.vars))
             s = StringIO()
             if hasattr(r, 'export_to_csv_file'):
                 r.export_to_csv_file(s)
@@ -5115,7 +5114,7 @@ def serve_xml(self, args=None):
             args = request.args
         if args and args[0] in self.xml_procedures:
             s = self.call_service_function(self.xml_procedures[args[0]],
-                                 *args[1:], **dict(request.vars))
+                                           *args[1:], **dict(request.vars))
             if hasattr(s, 'as_list'):
                 s = s.as_list()
             return serializers.xml(s, quote=False)
@@ -5128,7 +5127,7 @@ def serve_rss(self, args=None):
             args = request.args
         if args and args[0] in self.rss_procedures:
             feed = self.call_service_function(self.rss_procedures[args[0]],
-                                    *args[1:], **dict(request.vars))
+                                              *args[1:], **dict(request.vars))
         else:
             self.error()
         response.headers['Content-Type'] = 'application/rss+xml'
@@ -5476,7 +5475,7 @@ def call():
 
     def error(self):
         raise HTTP(404, "Object does not exist")
-    
+
     # we make this a method so that subclasses can override it if they want to do more specific argument-checking
     # but the default implmentation is the simplest: just pass the arguments we got, with no checking
     def call_service_function(self, f, *a, **b):
@@ -5484,7 +5483,8 @@ def call_service_function(self, f, *a, **b):
             return universal_caller(f, *a, **b)
         else:
             return f(*a, **b)
-  
+
+
 def completion(callback):
     """
     Executes a task on completion of the called action.


Test patch: