diff roundup/backends/back_anydbm.py @ 6999:e5a28b8ded72

backout checkin 60b37f632601 It broke things.
author John Rouillard <rouilj@ieee.org>
date Wed, 05 Oct 2022 23:37:40 -0400
parents e14b013ac83b
children 30cc3d6f1a3d
line wrap: on
line diff
--- a/roundup/backends/back_anydbm.py	Wed Oct 05 23:09:44 2022 -0400
+++ b/roundup/backends/back_anydbm.py	Wed Oct 05 23:37:40 2022 -0400
@@ -50,7 +50,6 @@
 
 from hashlib import md5
 
-
 def db_exists(config):
     # check for the user db
     for db in 'nodes.user nodes.user.db'.split():
@@ -58,11 +57,9 @@
             return 1
     return 0
 
-
 def db_nuke(config):
     shutil.rmtree(config.DATABASE)
 
-
 #
 # Now the database
 #
@@ -110,10 +107,10 @@
         self.classes = {}
         self.cache = {}         # cache of nodes loaded or created
         self.stats = {'cache_hits': 0, 'cache_misses': 0, 'get_items': 0,
-                      'filtering': 0}
-        self.dirtynodes = {}      # keep track of the dirty nodes by class
-        self.newnodes = {}        # keep track of the new nodes by class
-        self.destroyednodes = {}  # keep track of the destroyed nodes by class
+            'filtering': 0}
+        self.dirtynodes = {}    # keep track of the dirty nodes by class
+        self.newnodes = {}      # keep track of the new nodes by class
+        self.destroyednodes = {}# keep track of the destroyed nodes by class
         self.transactions = []
         self.indexer = get_indexer(config, self)
         self.security = security.Security(self)
@@ -130,7 +127,7 @@
         self.lockfile.flush()
 
         self.Session = None
-        self.Otk = None
+        self.Otk     = None
 
     def post_init(self):
         """Called once the schema initialisation has finished.
@@ -176,8 +173,8 @@
             classes = self.classes.values()
         for klass in classes:
             if show_progress:
-                for nodeid in support.Progress('Reindex %s' % klass.classname,
-                                               klass.list()):
+                for nodeid in support.Progress('Reindex %s'%klass.classname,
+                        klass.list()):
                     klass.index(nodeid)
             else:
                 for nodeid in klass.list():
@@ -185,7 +182,7 @@
         self.indexer.save_index()
 
     def __repr__(self):
-        return '<back_anydbm instance at %x>' % id(self)
+        return '<back_anydbm instance at %x>'%id(self)
 
     #
     # Classes
@@ -199,21 +196,17 @@
     def addclass(self, cl):
         cn = cl.classname
         if cn in self.classes:
-            raise ValueError(_('Class "%s" already defined.' % cn))
+            raise ValueError(_('Class "%s" already defined.'%cn))
         self.classes[cn] = cl
 
         # add default Edit and View permissions
-        self.security.addPermission(
-            name="Create", klass=cn,
+        self.security.addPermission(name="Create", klass=cn,
             description="User is allowed to create "+cn)
-        self.security.addPermission(
-            name="Edit", klass=cn,
+        self.security.addPermission(name="Edit", klass=cn,
             description="User is allowed to edit "+cn)
-        self.security.addPermission(
-            name="View", klass=cn,
+        self.security.addPermission(name="View", klass=cn,
             description="User is allowed to access "+cn)
-        self.security.addPermission(
-            name="Retire", klass=cn,
+        self.security.addPermission(name="Retire", klass=cn,
             description="User is allowed to retire "+cn)
 
     def getclasses(self):
@@ -228,7 +221,7 @@
         try:
             return self.classes[classname]
         except KeyError:
-            raise KeyError('There is no class called "%s"' % classname)
+            raise KeyError('There is no class called "%s"'%classname)
 
     #
     # Class DBs
@@ -239,7 +232,7 @@
         logging.getLogger('roundup.hyperdb.backend').info('clear')
         for cn in self.classes:
             for dummy in 'nodes', 'journals':
-                path = os.path.join(self.dir, 'journals.%s' % cn)
+                path = os.path.join(self.dir, 'journals.%s'%cn)
                 if os.path.exists(path):
                     os.remove(path)
                 elif os.path.exists(path+'.db'):    # dbm appends .db
@@ -255,7 +248,7 @@
         """ grab a connection to the class db that will be used for
             multiple actions
         """
-        return self.opendb('nodes.%s' % classname, mode)
+        return self.opendb('nodes.%s'%classname, mode)
 
     def determine_db_type(self, path):
         """ determine which DB wrote the class file
@@ -285,7 +278,7 @@
         if not db_type or hasattr(anydbm, 'whichdb'):
             if __debug__:
                 logging.getLogger('roundup.hyperdb.backend').debug(
-                    "opendb anydbm.open(%r, 'c')" % path)
+                    "opendb anydbm.open(%r, 'c')"%path)
             return anydbm.open(path, 'c')
 
         # in Python <3 it anydbm was a little dumb so manually open the
@@ -299,14 +292,13 @@
                 except ImportError:
                     raise hyperdb.DatabaseError(_(
                         "Couldn't open database - the required module '%s' "
-                        "(as dbm.gnu) is not available") % db_type)
+                        "(as dbm.gnu) is not available")%db_type)
             else:
-                raise hyperdb.DatabaseError(_(
-                    "Couldn't open database - the "
-                    "required module '%s' is not available") % db_type)
+                raise hyperdb.DatabaseError(_("Couldn't open database - the "
+                             "required module '%s' is not available")%db_type)
         if __debug__:
             logging.getLogger('roundup.hyperdb.backend').debug(
-                "opendb %r.open(%r, %r)" % (db_type, path, mode))
+                "opendb %r.open(%r, %r)"%(db_type, path, mode))
         return dbm.open(path, mode)
 
     #
@@ -367,7 +359,7 @@
         """
         if __debug__:
             logging.getLogger('roundup.hyperdb.backend').debug(
-                'save %s%s %r' % (classname, nodeid, node))
+                'save %s%s %r'%(classname, nodeid, node))
         self.transactions.append((self.doSaveNode, (classname, nodeid, node)))
 
     def getnode(self, classname, nodeid, db=None, cache=1):
@@ -381,7 +373,7 @@
         if nodeid in cache_dict:
             if __debug__:
                 logging.getLogger('roundup.hyperdb.backend').debug(
-                    'get %s%s cached' % (classname, nodeid))
+                    'get %s%s cached'%(classname, nodeid))
                 self.stats['cache_hits'] += 1
             return cache_dict[nodeid]
 
@@ -389,18 +381,18 @@
             self.stats['cache_misses'] += 1
             start_t = time.time()
             logging.getLogger('roundup.hyperdb.backend').debug(
-                'get %s%s' % (classname, nodeid))
+                'get %s%s'%(classname, nodeid))
 
         # get from the database and save in the cache
         if db is None:
             db = self.getclassdb(classname)
         if nodeid not in db:
-            raise IndexError("no such %s %s" % (classname, nodeid))
+            raise IndexError("no such %s %s"%(classname, nodeid))
 
         # check the uncommitted, destroyed nodes
         if (classname in self.destroyednodes and
                 nodeid in self.destroyednodes[classname]):
-            raise IndexError("no such %s %s" % (classname, nodeid))
+            raise IndexError("no such %s %s"%(classname, nodeid))
 
         # decode
         res = marshal.loads(db[nodeid])
@@ -422,7 +414,7 @@
            destroy() method on Class.
         """
         logging.getLogger('roundup.hyperdb.backend').info(
-            'destroy %s%s' % (classname, nodeid))
+            'destroy %s%s'%(classname, nodeid))
 
         # remove from cache and newnodes if it's there
         if (classname in self.cache and nodeid in self.cache[classname]):
@@ -522,6 +514,7 @@
             db = self.getclassdb(classname)
         return count + len(db)
 
+
     #
     # Files - special node properties
     # inherited from FileStorage
@@ -529,9 +522,8 @@
     #
     # Journal
     #
-
     def addjournal(self, classname, nodeid, action, params, creator=None,
-                   creation=None):
+            creation=None):
         """ Journal the Action
         'action' may be:
 
@@ -546,27 +538,27 @@
         """
         if __debug__:
             logging.getLogger('roundup.hyperdb.backend').debug(
-                'addjournal %s%s %s %r %s %r' % (
-                    classname, nodeid, action, params, creator, creation))
+                'addjournal %s%s %s %r %s %r'%(classname,
+                nodeid, action, params, creator, creation))
         if creator is None:
             creator = self.getuid()
-        self.transactions.append((self.doSaveJournal, (
-            classname, nodeid, action, params, creator, creation)))
+        self.transactions.append((self.doSaveJournal, (classname, nodeid,
+            action, params, creator, creation)))
 
     def setjournal(self, classname, nodeid, journal):
         """Set the journal to the "journal" list."""
         if __debug__:
             logging.getLogger('roundup.hyperdb.backend').debug(
-                'setjournal %s%s %r' % (classname, nodeid, journal))
+                'setjournal %s%s %r'%(classname, nodeid, journal))
         self.transactions.append((self.doSetJournal, (classname, nodeid,
-                                                      journal)))
+            journal)))
 
     def fix_journal(self, classname, journal):
         """ fix password entries to correct type """
         pwprops = {}
         for pn, prop in self.getclass(classname).properties.items():
             if isinstance(prop, hyperdb.Password):
-                pwprops[pn] = 1
+                pwprops [pn] = 1
         if not pwprops:
             return journal
         for j in journal:
@@ -598,36 +590,36 @@
                 if not cache_creation:
                     cache_creation = date.Date()
                 res.append((cache_nodeid, cache_creation, cache_creator,
-                            cache_action, cache_params))
+                    cache_action, cache_params))
 
         # attempt to open the journal - in some rare cases, the journal may
         # not exist
         try:
-            db = self.opendb('journals.%s' % classname, 'r')
+            db = self.opendb('journals.%s'%classname, 'r')
         except anydbm.error as error:
             if str(error) == "need 'c' or 'n' flag to open new db":
-                raise IndexError('no such %s %s' % (classname, nodeid))
+                raise IndexError('no such %s %s'%(classname, nodeid))
             elif error.args[0] != 2:
                 # this isn't a "not found" error, be alarmed!
                 raise
             if res:
                 # we have unsaved journal entries, return them
-                return self.fix_journal(classname, res)
-            raise IndexError('no such %s %s' % (classname, nodeid))
+                return self.fix_journal (classname, res)
+            raise IndexError('no such %s %s'%(classname, nodeid))
         try:
             journal = marshal.loads(db[nodeid])
         except KeyError:
             db.close()
             if res:
                 # we have some unsaved journal entries, be happy!
-                return self.fix_journal(classname, res)
-            raise IndexError('no such %s %s' % (classname, nodeid))
+                return self.fix_journal (classname, res)
+            raise IndexError('no such %s %s'%(classname, nodeid))
         db.close()
 
         # add all the saved journal entries for this node
         for nodeid, date_stamp, user, action, params in journal:
             res.append((nodeid, date.Date(date_stamp), user, action, params))
-        return self.fix_journal(classname, res)
+        return self.fix_journal (classname, res)
 
     def pack(self, pack_before):
         """ Delete all journal entries except "create" before 'pack_before'.
@@ -636,7 +628,7 @@
         for classname in self.getclasses():
             packed = 0
             # get the journal db
-            db_name = 'journals.%s' % classname
+            db_name = 'journals.%s'%classname
             path = os.path.join(os.getcwd(), self.dir, classname)
             db_type = self.determine_db_type(path)
             db = self.opendb(db_name, 'w')
@@ -659,25 +651,24 @@
                 db[key] = marshal.dumps(l)
 
                 logging.getLogger('roundup.hyperdb.backend').info(
-                    'packed %d %s items' % (packed, classname))
+                    'packed %d %s items'%(packed, classname))
 
             if db_type == 'gdbm':
                 db.reorganize()
             db.close()
 
+
     #
     # Basic transaction support
     #
-
     def commit(self):
         """ Commit the current transactions.
 
         Save all data changed since the database was opened or since the
         last commit() or rollback().
         """
-        logging.getLogger('roundup.hyperdb.backend').info(
-            'commit %s transactions' % (
-                len(self.transactions)))
+        logging.getLogger('roundup.hyperdb.backend').info('commit %s transactions'%(
+            len(self.transactions)))
 
         # keep a handle to all the database files opened
         self.databases = {}
@@ -721,7 +712,7 @@
         """ get the class db, looking in our cache of databases for commit
         """
         # get the database handle
-        db_name = 'nodes.%s' % classname
+        db_name = 'nodes.%s'%classname
         if db_name not in self.databases:
             self.databases[db_name] = self.getclassdb(classname, 'c')
         return self.databases[db_name]
@@ -739,13 +730,13 @@
         """ get the journal db, looking in our cache of databases for commit
         """
         # get the database handle
-        db_name = 'journals.%s' % classname
+        db_name = 'journals.%s'%classname
         if db_name not in self.databases:
             self.databases[db_name] = self.opendb(db_name, 'c')
         return self.databases[db_name]
 
     def doSaveJournal(self, classname, nodeid, action, params, creator,
-                      creation):
+            creation):
         # serialise the parameters now if necessary
         if isinstance(params, type({})):
             if action in ('set', 'create'):
@@ -801,8 +792,8 @@
     def rollback(self):
         """ Reverse all actions from the current transaction.
         """
-        logging.getLogger('roundup.hyperdb.backend').info(
-            'rollback %s transactions' % (len(self.transactions)))
+        logging.getLogger('roundup.hyperdb.backend').info('rollback %s transactions'%(
+            len(self.transactions)))
 
         for method, args in self.transactions:
             # delete temporary files
@@ -822,10 +813,7 @@
             self.lockfile.close()
             self.lockfile = None
 
-
 _marker = []
-
-
 class Class(hyperdb.Class):
     """The handle to a particular class of nodes in a hyperdatabase."""
 
@@ -877,15 +865,16 @@
         if self.db.journaltag is None:
             raise hyperdb.DatabaseError(_('Database open read-only'))
 
-        if ('creator' in propvalues or 'actor' in propvalues or
-                'creation' in propvalues or 'activity' in propvalues):
+
+        if ('creator' in propvalues or 'actor' in propvalues or 
+             'creation' in propvalues or 'activity' in propvalues):
             raise KeyError('"creator", "actor", "creation" and '
-                           '"activity" are reserved')
+                '"activity" are reserved')
 
         for p in propvalues:
             prop = self.properties[p]
             if prop.computed:
-                raise KeyError('"%s" is a computed property' % p)
+                raise KeyError('"%s" is a computed property'%p)
 
         # new node's id
         newid = self.db.newid(self.classname)
@@ -899,14 +888,14 @@
                 except KeyError:
                     pass
                 else:
-                    raise ValueError('node with key "%s" exists' % value)
+                    raise ValueError('node with key "%s" exists'%value)
 
             # try to handle this property
             try:
                 prop = self.properties[key]
             except KeyError:
-                raise KeyError('"%s" has no property "%s"' % (self.classname,
-                                                              key))
+                raise KeyError('"%s" has no property "%s"'%(self.classname,
+                    key))
 
             if value is not None and isinstance(prop, hyperdb.Link):
                 if type(value) != type(''):
@@ -917,11 +906,11 @@
                     try:
                         value = self.db.classes[link_class].lookup(value)
                     except (TypeError, KeyError):
-                        raise IndexError('new property "%s": %s not a %s' % (
+                        raise IndexError('new property "%s": %s not a %s'%(
                             key, value, link_class))
                 elif not self.db.getclass(link_class).hasnode(value):
-                    raise IndexError('%s has no node %s' % (link_class,
-                                                            value))
+                    raise IndexError('%s has no node %s'%(link_class,
+                        value))
 
                 # save off the value
                 propvalues[key] = value
@@ -929,88 +918,85 @@
                 # register the link with the newly linked node
                 if self.do_journal and self.properties[key].do_journal:
                     self.db.addjournal(link_class, value, 'link',
-                                       (self.classname, newid, key))
+                        (self.classname, newid, key))
 
             elif isinstance(prop, hyperdb.Multilink):
                 if value is None:
                     value = []
                 if not hasattr(value, '__iter__') or type(value) == type(''):
-                    raise TypeError(
-                        'new property "%s" not an iterable of ids' % key)
+                    raise TypeError('new property "%s" not an iterable of ids'%key)
 
                 # clean up and validate the list of links
                 link_class = self.properties[key].classname
                 l = []
                 for entry in value:
                     if type(entry) != type(''):
-                        raise ValueError('"%s" multilink value (%r) '
-                                         'must contain Strings' % (key, value))
+                        raise ValueError('"%s" multilink value (%r) '\
+                            'must contain Strings'%(key, value))
                     # if it isn't a number, it's a key
                     if not num_re.match(entry):
                         try:
                             entry = self.db.classes[link_class].lookup(entry)
                         except (TypeError, KeyError):
-                            raise IndexError(
-                                'new property "%s": %s not a %s' % (
-                                    key, entry,
-                                    self.properties[key].classname))
-                        l.append(entry)
+                            raise IndexError('new property "%s": %s not a %s'%(
+                                key, entry, self.properties[key].classname))
+                    l.append(entry)
                 value = l
                 propvalues[key] = value
 
                 # handle additions
                 for nodeid in value:
                     if not self.db.getclass(link_class).hasnode(nodeid):
-                        raise IndexError('%s has no node %s' % (link_class,
-                                                                nodeid))
+                        raise IndexError('%s has no node %s'%(link_class,
+                            nodeid))
                     # register the link with the newly linked node
                     if self.do_journal and self.properties[key].do_journal:
                         self.db.addjournal(link_class, nodeid, 'link',
-                                           (self.classname, newid, key))
+                            (self.classname, newid, key))
 
             elif isinstance(prop, hyperdb.String):
                 if type(value) != type('') and type(value) != type(u''):
-                    raise TypeError('new property "%s" not a string' % key)
+                    raise TypeError('new property "%s" not a string'%key)
                 if prop.indexme:
                     self.db.indexer.add_text((self.classname, newid, key),
-                                             value)
+                        value)
 
             elif isinstance(prop, hyperdb.Password):
                 if not isinstance(value, password.Password):
-                    raise TypeError('new property "%s" not a Password' % key)
+                    raise TypeError('new property "%s" not a Password'%key)
 
             elif isinstance(prop, hyperdb.Date):
                 if value is not None and not isinstance(value, date.Date):
-                    raise TypeError('new property "%s" not a Date' % key)
+                    raise TypeError('new property "%s" not a Date'%key)
 
             elif isinstance(prop, hyperdb.Interval):
                 if value is not None and not isinstance(value, date.Interval):
-                    raise TypeError('new property "%s" not an Interval' % key)
+                    raise TypeError('new property "%s" not an Interval'%key)
 
             elif value is not None and isinstance(prop, hyperdb.Number):
                 try:
                     float(value)
                 except ValueError:
-                    raise TypeError('new property "%s" not numeric' % key)
+                    raise TypeError('new property "%s" not numeric'%key)
 
             elif value is not None and isinstance(prop, hyperdb.Integer):
                 try:
                     int(value)
                 except ValueError:
-                    raise TypeError('new property "%s" not an integer' % key)
+                    raise TypeError('new property "%s" not an integer'%key)
 
             elif value is not None and isinstance(prop, hyperdb.Boolean):
                 try:
                     int(value)
                 except ValueError:
-                    raise TypeError('new property "%s" not boolean' % key)
+                    raise TypeError('new property "%s" not boolean'%key)
 
         # make sure there's data where there needs to be
         for key, prop in self.properties.items():
             if key in propvalues:
                 continue
             if key == self.key:
-                raise ValueError('key property "%s" is required' % key)
+                raise ValueError('key property "%s" is required'%key)
             if isinstance(prop, hyperdb.Multilink):
                 propvalues[key] = []
 
@@ -1171,10 +1157,10 @@
         if not propvalues:
             return propvalues
 
-        if ('creator' in propvalues or 'actor' in propvalues or
-                'creation' in propvalues or 'activity' in propvalues):
+        if ('creator' in propvalues or 'actor' in propvalues or 
+             'creation' in propvalues or 'activity' in propvalues):
             raise KeyError('"creator", "actor", "creation" and '
-                           '"activity" are reserved')
+                '"activity" are reserved')
 
         if 'id' in propvalues:
             raise KeyError('"id" is reserved')
@@ -1182,7 +1168,7 @@
         for p in propvalues:
             prop = self.properties[p]
             if prop.computed:
-                raise KeyError('"%s" is a computed property' % p)
+                raise KeyError('"%s" is a computed property'%p)
 
         if self.db.journaltag is None:
             raise hyperdb.DatabaseError(_('Database open read-only'))
@@ -1207,7 +1193,7 @@
                 except KeyError:
                     pass
                 else:
-                    raise ValueError('node with key "%s" exists' % value)
+                    raise ValueError('node with key "%s" exists'%value)
 
             # this will raise the KeyError if the property isn't valid
             # ... we don't use getprops() here because we only care about
@@ -1215,7 +1201,7 @@
             try:
                 prop = self.properties[propname]
             except KeyError:
-                raise KeyError('"%s" has no property named "%s"' % (
+                raise KeyError('"%s" has no property named "%s"'%(
                     self.classname, propname))
 
             # if the value's the same as the existing value, no sense in
@@ -1231,54 +1217,52 @@
                 link_class = prop.classname
                 # if it isn't a number, it's a key
                 if value is not None and not isinstance(value, type('')):
-                    raise ValueError('property "%s" link value be a string' % (
+                    raise ValueError('property "%s" link value be a string'%(
                         propname))
                 if isinstance(value, type('')) and not num_re.match(value):
                     try:
                         value = self.db.classes[link_class].lookup(value)
                     except (TypeError, KeyError):
-                        raise IndexError('new property "%s": %s not a %s' % (
+                        raise IndexError('new property "%s": %s not a %s'%(
                             propname, value, prop.classname))
 
                 if (value is not None and
                         not self.db.getclass(link_class).hasnode(value)):
-                    raise IndexError('%s has no node %s' % (link_class,
-                                                            value))
+                    raise IndexError('%s has no node %s'%(link_class,
+                        value))
 
                 if self.do_journal and prop.do_journal:
                     # register the unlink with the old linked node
                     if propname in node and node[propname] is not None:
-                        self.db.addjournal(link_class, node[propname],
-                                           'unlink',
-                                           (self.classname, nodeid, propname))
+                        self.db.addjournal(link_class, node[propname], 'unlink',
+                            (self.classname, nodeid, propname))
 
                     # register the link with the newly linked node
                     if value is not None:
                         self.db.addjournal(link_class, value, 'link',
-                                           (self.classname, nodeid, propname))
+                            (self.classname, nodeid, propname))
 
             elif isinstance(prop, hyperdb.Multilink):
                 if value is None:
                     value = []
                 if not hasattr(value, '__iter__') or type(value) == type(''):
                     raise TypeError('new property "%s" not an iterable of'
-                                    ' ids' % propname)
+                        ' ids'%propname)
                 link_class = self.properties[propname].classname
                 l = []
                 for entry in value:
                     # if it isn't a number, it's a key
                     if type(entry) != type(''):
                         raise ValueError('new property "%s" link value '
-                                         'must be a string' % propname)
+                            'must be a string'%propname)
                     if not num_re.match(entry):
                         try:
                             entry = self.db.classes[link_class].lookup(entry)
                         except (TypeError, KeyError):
-                            raise IndexError(
-                                'new property "%s": %s not a %s' % (
-                                    propname, entry,
-                                    self.properties[propname].classname))
-                        l.append(entry)
+                            raise IndexError('new property "%s": %s not a %s'%(
+                                propname, entry,
+                                self.properties[propname].classname))
+                    l.append(entry)
                 value = l
                 propvalues[propname] = value
 
@@ -1297,21 +1281,21 @@
                     # register the unlink with the old linked node
                     if self.do_journal and self.properties[propname].do_journal:
                         self.db.addjournal(link_class, id, 'unlink',
-                                           (self.classname, nodeid, propname))
+                            (self.classname, nodeid, propname))
                     l.remove(id)
                     remove.append(id)
 
                 # handle additions
                 for id in value:
                     if not self.db.getclass(link_class).hasnode(id):
-                        raise IndexError('%s has no node %s' % (link_class,
-                                                                id))
+                        raise IndexError('%s has no node %s'%(link_class,
+                            id))
                     if id in l:
                         continue
                     # register the link with the newly linked node
                     if self.do_journal and self.properties[propname].do_journal:
                         self.db.addjournal(link_class, id, 'link',
-                                           (self.classname, nodeid, propname))
+                            (self.classname, nodeid, propname))
                     l.append(id)
                     add.append(id)
 
@@ -1327,16 +1311,15 @@
             elif isinstance(prop, hyperdb.String):
                 if value is not None and type(value) != type('') and type(value) != type(u''):
                     raise TypeError('new property "%s" not a '
-                                    'string' % propname)
+                        'string'%propname)
                 if prop.indexme:
-                    self.db.indexer.add_text(
-                        (self.classname, nodeid, propname),
+                    self.db.indexer.add_text((self.classname, nodeid, propname),
                         value)
 
             elif isinstance(prop, hyperdb.Password):
                 if not isinstance(value, password.Password):
                     raise TypeError('new property "%s" not a '
-                                    'Password' % propname)
+                        'Password'%propname)
                 propvalues[propname] = value
                 journalvalues[propname] = \
                     current and password.JournalPassword(current)
@@ -1344,13 +1327,13 @@
             elif value is not None and isinstance(prop, hyperdb.Date):
                 if not isinstance(value, date.Date):
                     raise TypeError('new property "%s" not a '
-                                    'Date' % propname)
+                        'Date'%propname)
                 propvalues[propname] = value
 
             elif value is not None and isinstance(prop, hyperdb.Interval):
                 if not isinstance(value, date.Interval):
                     raise TypeError('new property "%s" not an '
-                                    'Interval' % propname)
+                        'Interval'%propname)
                 propvalues[propname] = value
 
             elif value is not None and isinstance(prop, hyperdb.Number):
@@ -1358,21 +1341,21 @@
                     float(value)
                 except ValueError:
                     raise TypeError('new property "%s" not '
-                                    'numeric' % propname)
+                        'numeric'%propname)
 
             elif value is not None and isinstance(prop, hyperdb.Integer):
                 try:
                     int(value)
                 except ValueError:
                     raise TypeError('new property "%s" not '
-                                    'numeric' % propname)
+                        'numeric'%propname)
 
             elif value is not None and isinstance(prop, hyperdb.Boolean):
                 try:
                     int(value)
                 except ValueError:
                     raise TypeError('new property "%s" not '
-                                    'boolean' % propname)
+                        'boolean'%propname)
 
             node[propname] = value
 
@@ -1444,7 +1427,7 @@
             pass
         else:
             raise KeyError("Key property (%s) of retired node clashes "
-                           "with existing one (%s)" % (key, node[key]))
+                "with existing one (%s)" % (key, node[key]))
         # Now we can safely restore node
         self.fireAuditors('restore', nodeid, None)
         del node[self.db.RETIRED_FLAG]
@@ -1516,7 +1499,7 @@
         """
         if not self.key:
             raise TypeError('No key property set for '
-                            'class %s' % self.classname)
+                'class %s'%self.classname)
         cldb = self.db.getclassdb(self.classname)
         try:
             for nodeid in self.getnodeids(cldb):
@@ -1529,8 +1512,8 @@
                     return nodeid
         finally:
             cldb.close()
-        raise KeyError('No key (%s) value "%s" for "%s"' % (
-            self.key, keyvalue, self.classname))
+        raise KeyError('No key (%s) value "%s" for "%s"'%(self.key,
+            keyvalue, self.classname))
 
     # change from spec - allows multiple props to match
     def find(self, **propspec):
@@ -1561,7 +1544,7 @@
             prop = props[propname]
             if not isinstance(prop, hyperdb.Link) and not isinstance(prop, hyperdb.Multilink):
                 raise TypeError("'%s' not a Link/Multilink "
-                                "property" % propname)
+                    "property"%propname)
 
         # ok, now do the find
         cldb = self.db.getclassdb(self.classname)
@@ -1575,7 +1558,7 @@
                 for propname, itemids in propspec.items():
                     if type(itemids) is not type({}):
                         if itemids is None or isinstance(itemids, type("")):
-                            itemids = {itemids: 1}
+                            itemids = {itemids:1}
                         else:
                             itemids = dict.fromkeys(itemids)
 
@@ -1594,7 +1577,7 @@
                         break
                     elif isinstance(prop, hyperdb.Multilink):
                         if prop.rev_property:
-                            rev_multilinks.append((prop, itemids))
+                            rev_multilinks.append ((prop, itemids))
                             continue
                         hit = 0
                         for v in value:
@@ -1607,7 +1590,7 @@
             for prop, itemids in rev_multilinks:
                 rprop = prop.rev_property
                 fun = l.append
-                if isinstance(rprop, hyperdb.Multilink):
+                if isinstance (rprop, hyperdb.Multilink):
                     fun = l.extend
                 for id in itemids:
                     fun(rprop.cls.get(id, rprop.name))
@@ -1628,7 +1611,7 @@
         for propname in requirements:
             prop = self.properties[propname]
             if not isinstance(prop, hyperdb.String):
-                raise TypeError("'%s' not a String property" % propname)
+                raise TypeError("'%s' not a String property"%propname)
             requirements[propname] = requirements[propname].lower()
         l = []
         cldb = self.db.getclassdb(self.classname)
@@ -1705,8 +1688,8 @@
         return res
 
     def _filter(self, search_matches, filterspec, proptree,
-                num_re=re.compile(r'^\d+$'), retired=False,
-                exact_match_spec={}):
+            num_re = re.compile(r'^\d+$'), retired=False,
+            exact_match_spec={}):
         """Return a list of the ids of the nodes in this class that
         match the 'filter' spec, sorted by the group spec and then the
         sort spec.
@@ -1805,7 +1788,7 @@
                     bv = []
                     for val in v:
                         if type(val) is type(''):
-                            bv.append(propclass.from_raw(val))
+                            bv.append(propclass.from_raw (val))
                         else:
                             bv.append(val)
                     l.append((OTHER, k, bv))
@@ -1817,17 +1800,17 @@
 
                 elif isinstance(propclass, hyperdb.Number):
                     if type(v) != type([]):
-                        try:
+                        try :
                             v = v.split(',')
-                        except AttributeError:
+                        except AttributeError :
                             v = [v]
                     l.append((OTHER, k, [float(val) for val in v]))
 
                 elif isinstance(propclass, hyperdb.Integer):
                     if type(v) != type([]):
-                        try:
+                        try :
                             v = v.split(',')
-                        except AttributeError:
+                        except AttributeError :
                             v = [v]
                     l.append((OTHER, k, [int(val) for val in v]))
 
@@ -1927,7 +1910,7 @@
                 matches = k
 
             # add sorting information to the proptree
-            JPROPS = {'actor': 1, 'activity': 1, 'creator': 1, 'creation': 1}
+            JPROPS = {'actor':1, 'activity':1, 'creator':1, 'creation':1}
             children = []
             if proptree:
                 children = proptree.sortable_children()
@@ -1937,8 +1920,8 @@
                 assert (dir and prop)
                 propclass = props[prop]
                 pt.sort_ids = []
-                is_pointer = isinstance(propclass, (hyperdb.Link,
-                                                    hyperdb.Multilink))
+                is_pointer = isinstance(propclass,(hyperdb.Link,
+                    hyperdb.Multilink))
                 if not is_pointer:
                     pt.sort_result = []
                 try:
@@ -1965,7 +1948,7 @@
                                 if isinstance(propclass, hyperdb.Multilink):
                                     v = []
                                 if prop == 'id':
-                                    v = int(itemid)
+                                    v = int (itemid)
                                 pt.sort_ids.append(v)
                                 if not is_pointer:
                                     pt.sort_result.append(v)
@@ -1983,7 +1966,7 @@
                             link = self.db.classes[lcn]
                             key = link.orderprop()
                             child = pt.propdict[key]
-                            if key != 'id':
+                            if key!='id':
                                 if v not in lcache:
                                     # open the link class db if it's not already
                                     if lcldb is None:
@@ -2190,7 +2173,6 @@
                           repr_export(params)])
         return r
 
-
 class FileClass(hyperdb.FileClass, Class):
     """This class defines a large chunk of data. To support this, it has a
        mandatory String property "content" which is typically saved off
@@ -2246,7 +2228,7 @@
                 return b2s(self.db.getfile(self.classname, nodeid, None))
             except IOError as strerror:
                 # XXX by catching this we don't see an error in the log.
-                return 'ERROR reading file: %s%s\n%s\n%s' % (
+                return 'ERROR reading file: %s%s\n%s\n%s'%(
                         self.classname, nodeid, poss_msg, strerror)
             except UnicodeDecodeError as e:
                 # if content is not text (e.g. jpeg file) we get
@@ -2255,10 +2237,8 @@
                 # of content as this string is included in the etag
                 # calculation of the object.
                 return ('%s%s is not text, retrieve using '
-                        'binary_content property. mdsum: %s') % (
-                            self.classname, nodeid,
-                            md5(self.db.getfile(
-                                self.classname, nodeid, None)).hexdigest())  # nosec - bandit md5 use ok
+                        'binary_content property. mdsum: %s')%(self.classname,
+                   nodeid, md5(self.db.getfile(self.classname, nodeid, None)).hexdigest())  # nosec - bandit md5 use ok
         elif propname == 'binary_content':
             return self.db.getfile(self.classname, nodeid, None)
 
@@ -2301,7 +2281,7 @@
                     index_content = content.decode('utf-8', errors='ignore')
                 mime_type = self.get(itemid, 'type', self.default_mime_type)
                 self.db.indexer.add_text((self.classname, itemid, 'content'),
-                                         index_content, mime_type)
+                    index_content, mime_type)
             propvalues['content'] = content
 
         # fire reactors
@@ -2322,7 +2302,7 @@
                     index_content = index_content.decode('utf-8',
                                                          errors='ignore')
                 self.db.indexer.add_text((self.classname, nodeid, 'content'),
-                                         index_content, mime_type)
+                    index_content, mime_type)
             elif isinstance(propclass, hyperdb.String) and propclass.indexme:
                 # index them under (classname, nodeid, property)
                 try:
@@ -2332,7 +2312,6 @@
                     continue
                 self.db.indexer.add_text((self.classname, nodeid, prop), value)
 
-
 # deviation from spec - was called ItemClass
 class IssueClass(Class, roundupdb.IssueClass):
     # Overridden methods:

Roundup Issue Tracker: http://roundup-tracker.org/