Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More rules for ruff #1794

Merged
merged 4 commits into from
Jun 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions debug_toolbar/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ def clean_signed(self):
signing.Signer(salt=self.salt).unsign(self.cleaned_data["signed"])
)
return verified
except signing.BadSignature:
raise ValidationError("Bad signature")
except signing.BadSignature as exc:
raise ValidationError("Bad signature") from exc

def verified_data(self):
return self.is_valid() and self.cleaned_data["signed"]
Expand Down
1 change: 0 additions & 1 deletion debug_toolbar/panels/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ def ready(cls):
be done unconditionally for the panel regardless of whether it is
enabled for a particular request. It should be idempotent.
"""
pass

# URLs for panel-specific views

Expand Down
5 changes: 1 addition & 4 deletions debug_toolbar/panels/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,7 @@ def _store_call_info(
else:
self.hits += 1
elif name == "get_many":
if "keys" in kwargs:
keys = kwargs["keys"]
else:
keys = args[0]
keys = kwargs["keys"] if "keys" in kwargs else args[0]
self.hits += len(return_value)
self.misses += len(keys) - len(return_value)
time_taken *= 1000
Expand Down
2 changes: 1 addition & 1 deletion debug_toolbar/panels/headers.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class HeadersPanel(Panel):
template = "debug_toolbar/panels/headers.html"

def process_request(self, request):
wsgi_env = list(sorted(request.META.items()))
wsgi_env = sorted(request.META.items())
self.request_headers = {
unmangle(k): v for (k, v) in wsgi_env if is_http_header(k)
}
Expand Down
8 changes: 4 additions & 4 deletions debug_toolbar/panels/history/panel.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import contextlib
import json

from django.http.request import RawPostDataException
Expand All @@ -22,7 +23,7 @@ class HistoryPanel(Panel):
def get_headers(self, request):
headers = super().get_headers(request)
observe_request = self.toolbar.get_observe_request()
store_id = getattr(self.toolbar, "store_id")
store_id = self.toolbar.store_id
if store_id and observe_request(request):
headers["djdt-store-id"] = store_id
return headers
Expand Down Expand Up @@ -62,10 +63,9 @@ def generate_stats(self, request, response):
and request.body
and request.headers.get("content-type") == "application/json"
):
try:
with contextlib.suppress(ValueError):
data = json.loads(request.body)
except ValueError:
pass

except RawPostDataException:
# It is not guaranteed that we may read the request data (again).
data = None
Expand Down
9 changes: 3 additions & 6 deletions debug_toolbar/panels/profiling.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

class FunctionCall:
def __init__(
self, statobj, func, depth=0, stats=None, id=0, parent_ids=[], hsv=(0, 0.5, 1)
self, statobj, func, depth=0, stats=None, id=0, parent_ids=None, hsv=(0, 0.5, 1)
):
self.statobj = statobj
self.func = func
Expand All @@ -23,7 +23,7 @@ def __init__(
self.stats = statobj.stats[func][:4]
self.depth = depth
self.id = id
self.parent_ids = parent_ids
self.parent_ids = parent_ids or []
self.hsv = hsv

def parent_classes(self):
Expand Down Expand Up @@ -88,10 +88,7 @@ def subfuncs(self):
for func, stats in self.statobj.all_callees[self.func].items():
i += 1
h1 = h + (i / count) / (self.depth + 1)
if stats[3] == 0:
s1 = 0
else:
s1 = s * (stats[3] / self.stats[3])
s1 = 0 if stats[3] == 0 else s * (stats[3] / self.stats[3])
yield FunctionCall(
self.statobj,
func,
Expand Down
4 changes: 1 addition & 3 deletions debug_toolbar/panels/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,5 @@ def generate_stats(self, request, response):
(k, request.session.get(k)) for k in sorted(request.session.keys())
]
except TypeError:
session_list = [
(k, request.session.get(k)) for k in request.session.keys()
]
session_list = [(k, request.session.get(k)) for k in request.session]
self.record_stats({"session": {"list": session_list}})
4 changes: 2 additions & 2 deletions debug_toolbar/panels/sql/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ def clean_params(self):

try:
return json.loads(value)
except ValueError:
raise ValidationError("Is not valid JSON")
except ValueError as exc:
raise ValidationError("Is not valid JSON") from exc

def clean_alias(self):
value = self.cleaned_data["alias"]
Expand Down
2 changes: 1 addition & 1 deletion debug_toolbar/panels/sql/panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def _duplicate_query_key(query):

def _process_query_groups(query_groups, databases, colors, name):
counts = defaultdict(int)
for (alias, key), query_group in query_groups.items():
for (alias, _key), query_group in query_groups.items():
count = len(query_group)
# Queries are similar / duplicates only if there are at least 2 of them.
if count > 1:
Expand Down
11 changes: 4 additions & 7 deletions debug_toolbar/panels/sql/tracking.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import contextlib
import contextvars
import datetime
import json
Expand Down Expand Up @@ -59,10 +60,7 @@ def cursor(*args, **kwargs):
cursor = connection._djdt_cursor(*args, **kwargs)
if logger is None:
return cursor
if allow_sql.get():
wrapper = NormalCursorWrapper
else:
wrapper = ExceptionCursorWrapper
wrapper = NormalCursorWrapper if allow_sql.get() else ExceptionCursorWrapper
return wrapper(cursor.cursor, connection, logger)

def chunked_cursor(*args, **kwargs):
Expand Down Expand Up @@ -174,10 +172,9 @@ def _record(self, method, sql, params):
stop_time = perf_counter()
duration = (stop_time - start_time) * 1000
_params = ""
try:
with contextlib.suppress(TypeError):
# object JSON serializable?
_params = json.dumps(self._decode(params))
except TypeError:
pass # object not JSON serializable
template_info = get_template_info()

# Sql might be an object (such as psycopg Composed).
Expand Down
2 changes: 1 addition & 1 deletion debug_toolbar/panels/sql/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def process(stmt):
return "".join(escaped_value(token) for token in stmt.flatten())


def reformat_sql(sql, with_toggle=False):
def reformat_sql(sql, *, with_toggle=False):
formatted = parse_sql(sql)
if not with_toggle:
return formatted
Expand Down
6 changes: 2 additions & 4 deletions debug_toolbar/panels/templates/panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def _store_template_info(self, sender, **kwargs):
value.model._meta.label,
)
else:
token = allow_sql.set(False)
token = allow_sql.set(False) # noqa: FBT003
try:
saferepr(value) # this MAY trigger a db query
except SQLQueryTriggered:
Expand Down Expand Up @@ -192,9 +192,7 @@ def generate_stats(self, request, response):
template = self.templates[0]["template"]
# django templates have the 'engine' attribute, while jinja
# templates use 'backend'
engine_backend = getattr(template, "engine", None) or getattr(
template, "backend"
)
engine_backend = getattr(template, "engine", None) or template.backend
template_dirs = engine_backend.dirs
else:
context_processors = None
Expand Down
1 change: 1 addition & 0 deletions debug_toolbar/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ def get_panels():
warnings.warn(
f"Please remove {logging_panel} from your DEBUG_TOOLBAR_PANELS setting.",
DeprecationWarning,
stacklevel=1,
)
return PANELS

Expand Down
2 changes: 1 addition & 1 deletion debug_toolbar/toolbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def render_toolbar(self):
"The debug toolbar requires the staticfiles contrib app. "
"Add 'django.contrib.staticfiles' to INSTALLED_APPS and "
"define STATIC_URL in your settings."
)
) from None
else:
raise

Expand Down
5 changes: 1 addition & 4 deletions debug_toolbar/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,7 @@ def get_template_source_from_exception_info(


def get_name_from_obj(obj: Any) -> str:
if hasattr(obj, "__name__"):
name = obj.__name__
else:
name = obj.__class__.__name__
name = obj.__name__ if hasattr(obj, "__name__") else obj.__class__.__name__

if hasattr(obj, "__module__"):
module = obj.__module__
Expand Down
75 changes: 58 additions & 17 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,24 +66,65 @@ source = ["src", ".tox/*/site-packages"]
fail_under = 94
show_missing = true

[tool.ruff.isort]
combine-as-imports = true

[tool.ruff]
select = [
# flake8/Pyflakes
"F",
# flake8/pycodestyle
"E",
"W",
# isort
"I",
# pyupgrade
"UP",
# pygrep-hooks
"PGH",
extend-select = [
# pyflakes, pycodestyle
"F", "E", "W",
# mmcabe
# "C90",
# isort
"I",
# pep8-naming
# "N",
# pyupgrade
"UP",
# flake8-2020
# "YTT",
# flake8-boolean-trap
"FBT",
# flake8-bugbear
"B",
# flake8-builtins
# "A",
# flake8-comprehensions
"C4",
# flake8-django
"DJ",
# flake8-logging-format
"G",
# flake8-pie
"PIE",
# flake8-simplify
"SIM",
# flake8-gettext
"INT",
# pygrep-hooks
"PGH",
# pylint
# "PL",
# unused noqa
"RUF100",
]
ignore = [
"E501",
extend-ignore = [
# Allow zip() without strict=
"B905",
# No line length errors
"E501",
]
fix = true
show-fixes = true
target-version = "py38"

[tool.ruff.isort]
combine-as-imports = true

[tool.ruff.mccabe]
max-complexity = 15

[tool.ruff.per-file-ignores]
"*/migrat*/*" = [
# Allow using PascalCase model names in migrations
"N806",
# Ignore the fact that migration files are invalid module names
"N999",
]
2 changes: 1 addition & 1 deletion tests/context_processors.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
def broken(request):
request.non_existing_attribute
_read = request.non_existing_attribute
9 changes: 9 additions & 0 deletions tests/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,22 @@ def __repr__(self):
class Binary(models.Model):
field = models.BinaryField()

def __str__(self):
return ""


class PostgresJSON(models.Model):
field = JSONField()

def __str__(self):
return ""


if settings.USE_GIS:
from django.contrib.gis.db import models as gismodels

class Location(gismodels.Model):
point = gismodels.PointField()

def __str__(self):
return ""
5 changes: 2 additions & 3 deletions tests/panels/test_profiling.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ def test_view_executed_once(self):
self.assertContains(response, "Profiling")
self.assertEqual(User.objects.count(), 1)

with self.assertRaises(IntegrityError):
with transaction.atomic():
response = self.client.get("/new_user/")
with self.assertRaises(IntegrityError), transaction.atomic():
response = self.client.get("/new_user/")
self.assertEqual(User.objects.count(), 1)
4 changes: 2 additions & 2 deletions tests/panels/test_sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from ..models import Binary, PostgresJSON


def sql_call(use_iterator=False):
def sql_call(*, use_iterator=False):
qs = User.objects.all()
if use_iterator:
qs = qs.iterator()
Expand Down Expand Up @@ -105,7 +105,7 @@ async def test_cursor_wrapper_asyncio_ctx(self, mock_wrapper):
await sync_to_async(sql_call)()

async def task():
sql_tracking.allow_sql.set(False)
sql_tracking.allow_sql.set(False) # noqa: FBT003
# By disabling sql_tracking.allow_sql, we are indicating that any
# future SQL queries should be stopped. If SQL query occurs,
# it raises an exception.
Expand Down