diff --git a/djblets/cache/serials.py b/djblets/cache/serials.py
index fca034067cfcfa71c4690d7216dc7e949692c66e..ad2702a71577e639a28c15644e9dbda367f48a29 100644
--- a/djblets/cache/serials.py
+++ b/djblets/cache/serials.py
@@ -64,7 +64,7 @@ def generate_ajax_serial():
     if not AJAX_SERIAL:
         template_dirs = itertools.chain.from_iterable(
             template_settings.get('DIRS', [])
-            for template_settings in getattr(settings, 'TEMPLATES', None)
+            for template_settings in getattr(settings, 'TEMPLATES', [])
         )
 
         for template_path in template_dirs:
diff --git a/djblets/db/tests/test_relation_counter_field.py b/djblets/db/tests/test_relation_counter_field.py
index 12591e251f59fe18b77410a5153daa41dd7dc86a..7080975ccbd15f2217d99ecb99e140e8ad306015 100644
--- a/djblets/db/tests/test_relation_counter_field.py
+++ b/djblets/db/tests/test_relation_counter_field.py
@@ -197,7 +197,6 @@ class RelationCounterFieldTests(SpyAgency, TestModelsLoaderMixin, TestCase):
                                                    created=False))
         self.assertTrue(save_func.last_returned(False))
 
-
     #
     # Forward-relation ManyToManyField tests
     #
diff --git a/djblets/extensions/manager.py b/djblets/extensions/manager.py
index 77e31b240fd5fa9de9b11aba42c2b0950522dc77..26d5f81fca21a41d25bdb8be918c3407eafaccd4 100644
--- a/djblets/extensions/manager.py
+++ b/djblets/extensions/manager.py
@@ -1338,10 +1338,10 @@ class ExtensionManager(object):
         extension.registration.installed = False
         extension.registration.save()
 
-        for path in (extension.info.installed_htdocs_path,
-                     extension.info.installed_static_path):
-            if os.path.exists(path):
-                shutil.rmtree(path, ignore_errors=True)
+        for media_path in (extension.info.installed_htdocs_path,
+                           extension.info.installed_static_path):
+            if os.path.exists(media_path):
+                shutil.rmtree(media_path, ignore_errors=True)
 
     def _install_admin_urls(self, extension):
         """Install administration URLs.
@@ -1510,7 +1510,7 @@ class ExtensionManager(object):
                 The extension whose apps are being removed.
         """
         # Remove the extension's apps from INSTALLED_APPS.
-        removed_apps = self._installed_apps_setting.remove_list(
+        self._installed_apps_setting.remove_list(
             extension.apps or [extension.info.app_name])
 
         # Now clear the apps and their modules from any caches.
diff --git a/djblets/forms/fields.py b/djblets/forms/fields.py
index c2c368dda2d075a42198a5159377c225635fbc9e..6bfc02e94d3ae3edcda3726c5346396518e2f92c 100644
--- a/djblets/forms/fields.py
+++ b/djblets/forms/fields.py
@@ -212,7 +212,7 @@ class ConditionsField(forms.Field):
                 self.widget.condition_errors[e.condition_index] = \
                     self.error_messages['value_required']
             else:
-                self.widget.condition_errors[e.condition_index] =  str(e)
+                self.widget.condition_errors[e.condition_index] = str(e)
 
             raise forms.ValidationError(
                 self.error_messages['condition_errors'],
diff --git a/djblets/log/__init__.py b/djblets/log/__init__.py
index 13a4f4d6fa4d7361ffad69bacd2376b0a3d9560d..0bba04961a7e7a7f3028448e884f0f1ad50d5643 100644
--- a/djblets/log/__init__.py
+++ b/djblets/log/__init__.py
@@ -401,6 +401,7 @@ def _Logger_log(self, *args, **kwargs):
 
     _old_log(self, *args, **kwargs)
 
+
 _old_log = logging.Logger._log
 
 if _old_log is not _Logger_log:
@@ -420,6 +421,7 @@ def _has_keywords(func):
     else:
         return inspect.getargspec(func).keywords is not None
 
+
 if not _has_keywords(logging.exception):
     def _logging_exception(msg, *args, **kwargs):
         kwargs['exc_info'] = 1
diff --git a/djblets/log/middleware.py b/djblets/log/middleware.py
index 21069602fca1bff4020772671b5610f0b0daf5b6..453a589662eee8d0ff4c00c2fd8d3faa1ecb131f 100644
--- a/djblets/log/middleware.py
+++ b/djblets/log/middleware.py
@@ -206,7 +206,7 @@ class LoggingMiddleware(MiddlewareMixin):
                     'SQL Query profile (%d times, %.3fs average)\n%s\n\n%s\n\n' % \
                     (len(entries), time / len(entries), sql, tracebacks)
 
-            sorted_times = sorted(times.keys(), reverse=1)
+            sorted_times = sorted(times.keys(), reverse=True)
             for time in sorted_times:
                 profile_log.log(logging.INFO, times[time])
 
diff --git a/djblets/recaptcha/mixins.py b/djblets/recaptcha/mixins.py
index b358ff6a92204a4011b815618d2b6f76c0b32073..95a8657fd3dd9367df009a4f45ae27c135b8545c 100644
--- a/djblets/recaptcha/mixins.py
+++ b/djblets/recaptcha/mixins.py
@@ -5,7 +5,7 @@ See :ref:`using-recaptcha` for a guide on using reCAPTCHA validation.
 
 import json
 import logging
-from urllib.error import URLError
+from urllib.error import HTTPError
 from urllib.parse import urlencode
 from urllib.request import urlopen
 
@@ -74,10 +74,10 @@ class RecaptchaFormMixin(forms.Form):
             try:
                 resp = urlopen(
                     'https://www.google.com/recaptcha/api/siteverify',
-                    data)
+                    data.encode('utf-8'))
 
                 payload = resp.read()
-            except URLError as e:
+            except HTTPError as e:
                 logging.exception('Could not make reCAPTCHA request: HTTP %s: '
                                   '%s',
                                   e.code, e.read())
diff --git a/djblets/registries/errors.py b/djblets/registries/errors.py
index 3bac55a3c2634b8eb2872dca2472841b7e068f74..33a06029fd41102985075747214cc70514c9f3b4 100644
--- a/djblets/registries/errors.py
+++ b/djblets/registries/errors.py
@@ -1,5 +1,6 @@
 """Exception classes for dealing with Djblets registries."""
 
+
 class ItemLookupError(Exception):
     """An error that occurs during item lookup."""
 
diff --git a/djblets/siteconfig/models.py b/djblets/siteconfig/models.py
index 0bc326e7a2993cdce3c6cb3950f6181941dd17ad..0c6c815e4dbf87994397392ecc8186101d56cfba 100644
--- a/djblets/siteconfig/models.py
+++ b/djblets/siteconfig/models.py
@@ -103,7 +103,7 @@ class SiteConfiguration(models.Model):
         cls.add_global_defaults({key: default_value})
 
     @classmethod
-    def remove_global_default(self, key):
+    def remove_global_default(cls, key):
         """Remove a global default value for a settings key.
 
         Args:
@@ -113,7 +113,7 @@ class SiteConfiguration(models.Model):
         _GLOBAL_DEFAULTS.pop(key)
 
     @classmethod
-    def clear_global_defaults(self):
+    def clear_global_defaults(cls):
         """Clear all default values for this site configuration.
 
         This will clear only global defaults. This will not affect defaults
diff --git a/djblets/template/tests/test_caches.py b/djblets/template/tests/test_caches.py
index b182b62c9fdbf1e0b65421ccbe952a87a63fd28e..5986d040f655007502d4011222bec12099475270 100644
--- a/djblets/template/tests/test_caches.py
+++ b/djblets/template/tests/test_caches.py
@@ -26,7 +26,6 @@ class CachesTests(TestCase):
                                             'library'):
                     Template(template_str).render(Context({}))
 
-        templatetags_module_name = 'djblets.template.tests.templatetags'
         template_str = (
             '{% load template_tests %}'
             '{% my_test_template_tag %}'
diff --git a/djblets/util/humanize.py b/djblets/util/humanize.py
index 0ea48ded49dc6f358f8b2fc8ca047a945c1352b3..f181ea096c96219d554b1803a516163dc3f8807d 100644
--- a/djblets/util/humanize.py
+++ b/djblets/util/humanize.py
@@ -1,5 +1,6 @@
 """Functions to humanize values."""
 
+
 def humanize_list(value):
     """
     Humanizes a list of values, inserting commas and "and" where appropriate.
diff --git a/djblets/util/templatetags/djblets_images.py b/djblets/util/templatetags/djblets_images.py
index 55241374da7566f388e43c7cfd519790a7ac3262..97db071448af69b08c629c98864cb83e484b7fd9 100644
--- a/djblets/util/templatetags/djblets_images.py
+++ b/djblets/util/templatetags/djblets_images.py
@@ -113,7 +113,7 @@ def thumbnail(f, size='400x100'):
                 # Calculate height based on width
                 y = int(x * (image.size[1] / image.size[0]))
 
-            image.thumbnail([x, y], Image.ANTIALIAS)
+            image.thumbnail((x, y), Image.ANTIALIAS)
 
             save_image_to_storage(image, storage, miniature)
         except (IOError, KeyError) as e:
diff --git a/djblets/util/templatetags/djblets_utils.py b/djblets/util/templatetags/djblets_utils.py
index 34c0cae9693ead895f040f5bed77b8b8388fda36..546c58cd9b3be9a9cec868f5fbdbe5f9f8c5e691 100644
--- a/djblets/util/templatetags/djblets_utils.py
+++ b/djblets/util/templatetags/djblets_utils.py
@@ -722,6 +722,8 @@ def paragraphs(text):
             s += "<p>%s</p>\n" % line
 
     return mark_safe(s)
+
+
 paragraphs.is_safe = True
 
 
diff --git a/djblets/webapi/errors.py b/djblets/webapi/errors.py
index 3f8e80b5ca33c7847414eb5aadcd8b514e70295b..6bb17d237faff18be034edf06c5981f89033fdcd 100644
--- a/djblets/webapi/errors.py
+++ b/djblets/webapi/errors.py
@@ -1,5 +1,6 @@
 """Error classes and codes for WebAPI."""
 
+
 class WebAPIError(object):
     """
     An API error, containing an error code and human readable message.
diff --git a/djblets/webapi/models.py b/djblets/webapi/models.py
index fe9cdcf1785aeec097003ca48f9ac88c2278d04a..89e0811f673f1c24db1dbd209c220fe43fbe15ff 100644
--- a/djblets/webapi/models.py
+++ b/djblets/webapi/models.py
@@ -69,7 +69,7 @@ class BaseWebAPIToken(models.Model):
             webapi_token_updated.send(instance=self, sender=type(self))
 
     @classmethod
-    def get_root_resource(self):
+    def get_root_resource(cls):
         raise NotImplementedError
 
     @classmethod
diff --git a/djblets/webapi/oauth2_scopes.py b/djblets/webapi/oauth2_scopes.py
index 4c48296d551fff6290752ab9f6d6012fc1bb9040..599e57f3bef173c989a76bdc95b04d117ffba1fe 100644
--- a/djblets/webapi/oauth2_scopes.py
+++ b/djblets/webapi/oauth2_scopes.py
@@ -119,18 +119,6 @@ class WebAPIScopeDictionary(object):
 
         return self._scope_dict
 
-    def iterkeys(self):
-        """Iterate through all keys in the dictionary.
-
-        This is used by oauth2_provider when on Python 2.x to get the list
-        of scope keys.
-
-        Yields:
-            unicode:
-            The key for each scope.
-        """
-        return self.scope_dict.iterkeys()
-
     def keys(self):
         """Iterate through all keys in the dictionary.
 
diff --git a/djblets/webapi/responses.py b/djblets/webapi/responses.py
index 060fb6e041092d9d06c1d5211e022d952feeb522..37fb4ed052ce2242d0347fefda7e2a190e71cfff 100644
--- a/djblets/webapi/responses.py
+++ b/djblets/webapi/responses.py
@@ -11,6 +11,7 @@ from djblets.webapi.errors import INVALID_FORM_DATA
 
 class WebAPIResponse(HttpResponse):
     """An API response, formatted for the desired file format."""
+
     supported_mimetypes = [
         'application/json',
         'application/xml',
