diff --git a/CHANGES b/CHANGES
index afbc0ee..540b2fc 100644
--- a/CHANGES
+++ b/CHANGES
@@ -15,6 +15,7 @@ Next
Unreleased
==========
+- Update Python syntax for modern versions with pyupgrade
- Drop support for EOL Python <3.8 and Django <2.2 versions
- Switch to ruff instead of pep8 and flake8
- Move from CircleCI to Github Actions for CI
diff --git a/csp/decorators.py b/csp/decorators.py
index e6489a2..69d0f85 100644
--- a/csp/decorators.py
+++ b/csp/decorators.py
@@ -12,7 +12,7 @@ def _wrapped(*a, **kw):
def csp_update(**kwargs):
- update = dict((k.lower().replace("_", "-"), v) for k, v in kwargs.items())
+ update = {k.lower().replace("_", "-"): v for k, v in kwargs.items()}
def decorator(f):
@wraps(f)
@@ -27,7 +27,7 @@ def _wrapped(*a, **kw):
def csp_replace(**kwargs):
- replace = dict((k.lower().replace("_", "-"), v) for k, v in kwargs.items())
+ replace = {k.lower().replace("_", "-"): v for k, v in kwargs.items()}
def decorator(f):
@wraps(f)
@@ -42,7 +42,7 @@ def _wrapped(*a, **kw):
def csp(**kwargs):
- config = dict((k.lower().replace("_", "-"), [v] if isinstance(v, str) else v) for k, v in kwargs.items())
+ config = {k.lower().replace("_", "-"): [v] if isinstance(v, str) else v for k, v in kwargs.items()}
def decorator(f):
@wraps(f)
diff --git a/csp/extensions/__init__.py b/csp/extensions/__init__.py
index 227289b..2e152b8 100644
--- a/csp/extensions/__init__.py
+++ b/csp/extensions/__init__.py
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
from jinja2 import nodes
from jinja2.ext import Extension
@@ -8,7 +6,7 @@
class NoncedScript(Extension):
# a set of names that trigger the extension.
- tags = set(["script"])
+ tags = {"script"}
def parse(self, parser):
# the first token is the token that started the tag. In our case
diff --git a/csp/middleware.py b/csp/middleware.py
index c354b64..35465d9 100644
--- a/csp/middleware.py
+++ b/csp/middleware.py
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import base64
import http.client as http_client
import os
diff --git a/csp/templatetags/csp.py b/csp/templatetags/csp.py
index 572bfe7..d31a921 100644
--- a/csp/templatetags/csp.py
+++ b/csp/templatetags/csp.py
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
from django import template
from django.template.base import token_kwargs
diff --git a/csp/tests/test_utils.py b/csp/tests/test_utils.py
index b5f6a60..e4e30b6 100644
--- a/csp/tests/test_utils.py
+++ b/csp/tests/test_utils.py
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
from django.conf import settings
from django.test.utils import override_settings
from django.utils.functional import lazy
diff --git a/csp/tests/utils.py b/csp/tests/utils.py
index ba60bc7..2d96b1c 100644
--- a/csp/tests/utils.py
+++ b/csp/tests/utils.py
@@ -21,11 +21,11 @@ def get_response(req):
rf = RequestFactory()
-class ScriptTestBase(object):
+class ScriptTestBase:
def assert_template_eq(self, tpl1, tpl2):
aaa = tpl1.replace("\n", "").replace(" ", "")
bbb = tpl2.replace("\n", "").replace(" ", "")
- assert aaa == bbb, "{} != {}".format(aaa, bbb)
+ assert aaa == bbb, f"{aaa} != {bbb}"
def process_templates(self, tpl, expected):
request = rf.get("/")
diff --git a/csp/utils.py b/csp/utils.py
index a213fcf..821912d 100644
--- a/csp/utils.py
+++ b/csp/utils.py
@@ -99,14 +99,14 @@ def build_policy(config=None, update=None, replace=None, nonce=None):
include_nonce_in = getattr(settings, "CSP_INCLUDE_NONCE_IN", ["default-src"])
for section in include_nonce_in:
policy = policy_parts.get(section, "")
- policy_parts[section] = ("%s %s" % (policy, "'nonce-%s'" % nonce)).strip()
+ policy_parts[section] = ("{} {}".format(policy, "'nonce-%s'" % nonce)).strip()
- return "; ".join(["{} {}".format(k, val).strip() for k, val in policy_parts.items()])
+ return "; ".join([f"{k} {val}".strip() for k, val in policy_parts.items()])
def _default_attr_mapper(attr_name, val):
if val:
- return ' {}="{}"'.format(attr_name, val)
+ return f' {attr_name}="{val}"'
else:
return ""
@@ -115,7 +115,7 @@ def _bool_attr_mapper(attr_name, val):
# Only return the bare word if the value is truthy
# ie - defer=False should actually return an empty string
if val:
- return " {}".format(attr_name)
+ return f" {attr_name}"
else:
return ""
@@ -125,9 +125,9 @@ def _async_attr_mapper(attr_name, val):
attributes. It can be set explicitly to `false` with no surrounding quotes
according to the spec."""
if val in [False, "False"]:
- return " {}=false".format(attr_name)
+ return f" {attr_name}=false"
elif val:
- return " {}".format(attr_name)
+ return f" {attr_name}"
else:
return ""
@@ -144,7 +144,7 @@ def _async_attr_mapper(attr_name, val):
SCRIPT_ATTRS["nomodule"] = _bool_attr_mapper
# Generates an interpolatable string of valid attrs eg - '{nonce}{id}...'
-ATTR_FORMAT_STR = "".join(["{{{}}}".format(a) for a in SCRIPT_ATTRS])
+ATTR_FORMAT_STR = "".join([f"{{{a}}}" for a in SCRIPT_ATTRS])
_script_tag_contents_re = re.compile(
@@ -176,4 +176,4 @@ def build_script_tag(content=None, **kwargs):
# Don't render block contents if the script has a 'src' attribute
c = _unwrap_script(content) if content and not kwargs.get("src") else ""
attrs = ATTR_FORMAT_STR.format(**data).rstrip()
- return "".format(attrs, c).strip()
+ return f"".strip()
diff --git a/docs/conf.py b/docs/conf.py
index a4711c9..0bb8fd7 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Django-CSP documentation build configuration file, created by
# sphinx-quickstart on Wed Oct 31 13:02:27 2012.
diff --git a/setup.py b/setup.py
index 1c10c07..b6710ef 100644
--- a/setup.py
+++ b/setup.py
@@ -11,7 +11,7 @@
os.system("python setup.py sdist upload")
os.system("python setup.py bdist_wheel upload")
print("You probably want to also tag the version now:")
- print(' git tag -a %s -m "version %s"' % (version, version))
+ print(f' git tag -a {version} -m "version {version}"')
print(" git push --tags")
sys.exit()
diff --git a/test_settings.py b/test_settings.py
deleted file mode 100644
index e69de29..0000000