Use attrs and modernize form classes
authorKarl O. Pinc <kop@karlpinc.com>
Sat, 23 Jan 2021 02:49:41 +0000 (20:49 -0600)
committerKarl O. Pinc <kop@karlpinc.com>
Sat, 23 Jan 2021 02:49:54 +0000 (20:49 -0600)
src/pgwui_core/core.py

index bf8f9fcb3c63113c933708fb18f086a160f8c0d6..9d85129f7b5bd9e484a9b15869167984be621e70 100644 (file)
@@ -161,6 +161,7 @@ class UploadTableWTForm(UploadNullFileWTForm):
     ivals = UploadTableInitialPost
 
 
+@attr.s
 class LoadedForm(collections.abc.MutableMapping):
     '''
     Abstract class representing an upload form.
@@ -177,8 +178,15 @@ class LoadedForm(collections.abc.MutableMapping):
       _form   Instantaiated html form object (WTForms)
       _fc     Class handling html form
     '''
-    def __init__(self, uh, fc=None, data={}, **kwargs):
-        super(LoadedForm, self).__init__()
+    uh = attr.ib(default=None)
+    _store = attr.ib(factory=dict)
+    _fc = attr.ib(default=None)
+    _form = attr.ib(default=None)
+    ivals = attr.ib(default=None)
+
+    def build(self, uh, fc=None, data={}, **kwargs):
+        '''Form initialization
+        '''
         self.uh = uh
         if data == {}:
             store = dict(kwargs)
@@ -188,6 +196,7 @@ class LoadedForm(collections.abc.MutableMapping):
         self._store = store
         self._fc = fc
         self.ivals = fc.ivals().build(self.uh.request.registry.settings)
+        return self
 
     def __iter__(self):
         for item in self._store:
@@ -230,6 +239,7 @@ class LoadedForm(collections.abc.MutableMapping):
         return response
 
 
+@attr.s
 class CredsLoadedForm(LoadedForm):
     '''
     Acts like a dict, but with extra methods.
@@ -243,9 +253,12 @@ class CredsLoadedForm(LoadedForm):
     Methods:
       read()  Load form from pyramid request object.
     '''
-    def __init__(self, uh, fc=UserWTForm, data={}, **kwargs):
-        data.update(kwargs)
-        super(CredsLoadedForm, self).__init__(uh, fc, data)
+    user = attr.ib(default=None)
+    password = attr.ib(default=None)
+    action = attr.ib(default=None)
+
+    def build(self, uh, fc=UserWTForm, data={}, **kwargs):
+        return super().build(uh, fc, data, **kwargs)
 
     def session_put(self, key, value):
         '''
@@ -271,7 +284,7 @@ class CredsLoadedForm(LoadedForm):
         '''
 
         # Read parent's data
-        super(CredsLoadedForm, self).read()
+        super().read()
 
         # Read our form data
 
@@ -307,7 +320,7 @@ class CredsLoadedForm(LoadedForm):
         '''
         Produces the dict pyramid will use to render the form.
         '''
-        response = super(CredsLoadedForm, self).write(result, errors)
+        response = super().write(result, errors)
         if ('havecreds' not in response
                 or ('havecreds' in response and not response['havecreds'])):
             # We don't know if the credentials are good or
@@ -321,6 +334,7 @@ class CredsLoadedForm(LoadedForm):
         return response
 
 
+@attr.s
 class AuthLoadedForm(CredsLoadedForm):
     '''
     Acts like a dict, but with extra methods.
@@ -334,9 +348,7 @@ class AuthLoadedForm(CredsLoadedForm):
       _form   Instantaiated html form object (WXForms)
 
     '''
-    def __init__(self, uh, fc=AuthWTForm, data={}, **kwargs):
-        data.update(kwargs)
-        super(AuthLoadedForm, self).__init__(uh, fc, data)
+    db = attr.ib(default=None)
 
     def read(self):
         '''
@@ -344,7 +356,7 @@ class AuthLoadedForm(CredsLoadedForm):
         '''
 
         # Read parent's data
-        super(AuthLoadedForm, self).read()
+        super().read()
 
         # Keep form variables handy
         self['db'] = self._form.db.data
@@ -353,11 +365,12 @@ class AuthLoadedForm(CredsLoadedForm):
         '''
         Produces the dict pyramid will use to render the form.
         '''
-        response = super(AuthLoadedForm, self).write(result, errors)
+        response = super().write(result, errors)
         response['db'] = self['db']
         return response
 
 
+@attr.s
 class UploadFileForm(AuthLoadedForm):
     '''
     Acts like a dict, but with extra methods.
@@ -368,9 +381,14 @@ class UploadFileForm(AuthLoadedForm):
     Methods:
       read()  Load form from pyramid request object.
     '''
-    def __init__(self, uh, fc=UploadFileWTForm, data={}, **kwargs):
-        data.update(kwargs)
-        super(UploadFileForm, self).__init__(uh, fc, data)
+    upload_fmt = attr.ib(default=None)
+    trim_upload = attr.ib(default=None)
+    literal_col_headings = attr.ib(default=None)
+    filename = attr.ib(default=None)
+    localfh = attr.ib(default=None)
+
+    def build(self, uh, fc=UploadFileWTForm, data={}, **kwargs):
+        return super().build(uh, fc, data, **kwargs)
 
     def read(self):
         '''
@@ -378,7 +396,7 @@ class UploadFileForm(AuthLoadedForm):
         '''
 
         # Read parent's data
-        super(UploadFileForm, self).read()
+        super().read()
 
         # Read our own data
         self['upload_fmt'] = self._form.upload_fmt.data
@@ -388,7 +406,7 @@ class UploadFileForm(AuthLoadedForm):
         # Other POST variables involving a file
         self['filename'] = ''
         self['localfh'] = ''
-        if 'action' in self:
+        if self['action']:
             if self._form.datafile.data != '':
                 post = self.uh.request.POST
                 if hasattr(post['datafile'], 'filename'):
@@ -417,7 +435,7 @@ class UploadFileForm(AuthLoadedForm):
         else:
             literal_col_headings_checked = UNCHECKED
 
-        response = super(UploadFileForm, self).write(result, errors)
+        response = super().write(result, errors)
         response['filename'] = self['filename']
         response['trim_upload'] = trim_upload_checked
         response['csv_value'] = CSV_VALUE
@@ -436,6 +454,7 @@ class UploadFormBaseMixin():
         return response
 
 
+@attr.s
 class UploadDoubleFileFormMixin(UploadFormBaseMixin):
     '''
     Adds a last_key attribute to self, from POST
@@ -448,6 +467,7 @@ class UploadDoubleFileFormMixin(UploadFormBaseMixin):
     Methods:
       read()  Load form from pyramid request object.
     '''
+    last_key = attr.ib(default=None)
 
     def read(self):
         '''
@@ -469,6 +489,7 @@ class UploadDoubleFileFormMixin(UploadFormBaseMixin):
         return super().write_response(response)
 
 
+@attr.s
 class UploadDoubleFileForm(UploadDoubleFileFormMixin, UploadFileForm):
     '''
     Acts like a dict, but with extra methods.
@@ -479,15 +500,11 @@ class UploadDoubleFileForm(UploadDoubleFileFormMixin, UploadFileForm):
     Methods:
       read()  Load form from pyramid request object.
     '''
-    def __init__(self, uh, fc=UploadFileWTForm, data={}, **kwargs):
-        data.update(kwargs)
-        super().__init__(uh, fc, data)
-
     def read(self):
         '''
         Read form data from the client
         '''
-        # Read parents' data
+        # Read all parents' data
         super().read()
 
     def write(self, result, errors):
@@ -498,6 +515,7 @@ class UploadDoubleFileForm(UploadDoubleFileFormMixin, UploadFileForm):
         return super().write_response(response)
 
 
+@attr.s
 class UploadNullMixin(UploadFormBaseMixin):
     '''
     Acts like a dict, but with extra methods.
@@ -530,6 +548,7 @@ class UploadNullMixin(UploadFormBaseMixin):
         return super().write_response(response)
 
 
+@attr.s
 class UploadTableForm(UploadNullMixin, UploadFileForm):
     '''
     Acts like a dict, but with extra methods.
@@ -540,16 +559,15 @@ class UploadTableForm(UploadNullMixin, UploadFileForm):
     Methods:
       read()  Load form from pyramid request object.
     '''
-    def __init__(self, uh, fc=UploadTableWTForm, data={}, **kwargs):
-        data.update(kwargs)
-        super().__init__(uh, fc, data)
+    def build(self, uh, fc=UploadTableWTForm, data={}, **kwargs):
+        return super().build(uh, fc, data, **kwargs)
 
     def read(self):
         '''
         Read form data from the client
         '''
 
-        # Read parents' data
+        # Read all parents' data
         super().read()
         # Read our own data
         self['table'] = self._form.table.data
@@ -563,6 +581,7 @@ class UploadTableForm(UploadNullMixin, UploadFileForm):
         return super().write_response(response)
 
 
+@attr.s
 class UploadDoubleTableForm(UploadDoubleFileFormMixin, UploadTableForm):
     '''
     Acts like a dict, but with extra methods.
@@ -573,15 +592,11 @@ class UploadDoubleTableForm(UploadDoubleFileFormMixin, UploadTableForm):
     Methods:
       read()  Load form from pyramid request object.
     '''
-    def __init__(self, uh, fc=UploadTableWTForm, data={}, **kwargs):
-        data.update(kwargs)
-        super().__init__(uh, fc, data)
-
     def read(self):
         '''
         Read form data from the client
         '''
-        # Read parents' data
+        # Read all parents' data
         super().read()
 
     def write(self, result, errors):