Apply suggested rewrites from pyupgrade for Python 3.9 and up

```
git ls-files --others --cached --exclude-standard -- '*.py' | xargs pyupgrade --py39-plus
```
pull/12156/head
Matt Westcott 2024-07-22 16:27:06 +01:00 zatwierdzone przez Matt Westcott
rodzic 4ad2527824
commit 80b1ebe40b
27 zmienionych plików z 91 dodań i 102 usunięć

Wyświetl plik

@ -1,7 +1,7 @@
from __future__ import annotations
import logging
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING
from django.conf import settings
from django.core.exceptions import PermissionDenied
@ -47,7 +47,7 @@ class PublishRevisionAction:
user=None,
changed: bool = True,
log_action: bool = True,
previous_revision: Optional[Revision] = None,
previous_revision: Revision | None = None,
):
self.revision = revision
self.object = self.revision.as_object()
@ -107,7 +107,7 @@ class PublishRevisionAction:
user,
changed,
log_action: bool,
previous_revision: Optional[Revision] = None,
previous_revision: Revision | None = None,
):
from wagtail.models import Revision

Wyświetl plik

@ -34,7 +34,7 @@ def extract_panel_definitions_from_model_class(model, exclude=None):
return panels
@functools.lru_cache(maxsize=None)
@functools.cache
def get_edit_handler(model):
"""
Get the panel to use in the Wagtail admin when editing this model.

Wyświetl plik

@ -1,6 +1,7 @@
from collections.abc import Mapping
from datetime import date, datetime, timezone
from functools import wraps
from typing import Any, List, Mapping, Optional
from typing import Any, Optional
from unittest import mock
from django import forms
@ -846,7 +847,7 @@ class TestFieldPanel(TestCase):
def _get_form(
self,
data: Optional[Mapping[str, Any]] = None,
fields: Optional[List[str]] = None,
fields: Optional[list[str]] = None,
) -> WagtailAdminPageForm:
cls = get_form_for_model(
EventPage,

Wyświetl plik

@ -1,4 +1,5 @@
from typing import Any, List, Mapping
from collections.abc import Mapping
from typing import Any
from warnings import warn
from django import forms
@ -152,7 +153,7 @@ class SubMenuItem(MenuItem):
self,
name: str,
label: str,
menu_items: List[MenuItem],
menu_items: list[MenuItem],
icon_name: str = "",
classname: str = "",
classnames: str = "",
@ -262,7 +263,7 @@ class SearchModule:
@adapter("wagtail.sidebar.MainMenuModule", base=BaseSidebarAdapter)
class MainMenuModule:
def __init__(
self, menu_items: List[MenuItem], account_menu_items: List[MenuItem], user
self, menu_items: list[MenuItem], account_menu_items: list[MenuItem], user
):
self.menu_items = menu_items
self.account_menu_items = account_menu_items

Wyświetl plik

@ -317,7 +317,7 @@ class BaseListingView(WagtailAdminTemplateMixin, BaseListView):
ActiveFilter(
bound_field.auto_id,
filter_def.label,
"%s - %s" % (start_date_display, end_date_display),
f"{start_date_display} - {end_date_display}",
self.get_url_without_filter_param(
[
widget.suffixed(field_name, suffix)

Wyświetl plik

@ -1,4 +1,5 @@
from typing import Any, Mapping, Union
from collections.abc import Mapping
from typing import Any, Union
from django.conf import settings
from django.contrib.auth import get_user_model

Wyświetl plik

@ -1,4 +1,4 @@
from typing import Any, Dict
from typing import Any
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
@ -165,7 +165,7 @@ class BaseSearchView(PermissionCheckedMixin, BaseListingView):
kwargs["actions_next_url"] = self.get_index_url()
return kwargs
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
context = super().get_context_data(**kwargs)
context.update(
{
@ -182,7 +182,7 @@ class BaseSearchView(PermissionCheckedMixin, BaseListingView):
class SearchView(BaseSearchView):
template_name = "wagtailadmin/pages/search.html"
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
context = super().get_context_data(**kwargs)
context["search_form"] = SearchForm(self.request.GET)
return context

Wyświetl plik

@ -1,4 +1,4 @@
from typing import Any, Dict
from typing import Any
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import PermissionDenied
@ -68,7 +68,7 @@ class ContentTypeUseView(BaseListingView):
],
)
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
context = super().get_context_data(**kwargs)
context["page_class"] = self.page_class
return context

Wyświetl plik

@ -1,5 +1,5 @@
import logging
from typing import Iterable, Set, Tuple
from collections.abc import Iterable
from django.conf import settings
from django.db.models import Q
@ -89,8 +89,8 @@ def autocreate_redirects_on_page_move(
def _page_urls_for_sites(
page: Page, sites: Tuple[Site], cache_target: Page
) -> Set[Tuple[Site, str, str]]:
page: Page, sites: tuple[Site], cache_target: Page
) -> set[tuple[Site, str, str]]:
urls = set()
for site in sites:
# use a `HttpRequest` to influence the return value

Wyświetl plik

@ -1,5 +1,4 @@
import os
from typing import List
from django.core.exceptions import PermissionDenied, SuspiciousOperation
from django.db import transaction
@ -123,7 +122,7 @@ class IndexView(generic.IndexView):
return super().get_base_queryset().select_related("redirect_page", "site")
@cached_property
def header_more_buttons(self) -> List[Button]:
def header_more_buttons(self) -> list[Button]:
buttons = super().header_more_buttons.copy()
buttons.append(
Button(

Wyświetl plik

@ -1,5 +1,3 @@
from typing import List
from django.conf import settings
from django.contrib.admin.utils import quote
from django.contrib.auth.models import Permission
@ -118,7 +116,7 @@ def register_snippet_listing_buttons(snippet, user, next_url=None):
@hooks.register("construct_translated_pages_to_cascade_actions")
def construct_translated_pages_to_cascade_actions(pages: List[Page], action: str):
def construct_translated_pages_to_cascade_actions(pages: list[Page], action: str):
if not getattr(settings, "WAGTAILSIMPLETRANSLATION_SYNC_PAGE_TREE", False):
return

Wyświetl plik

@ -3,8 +3,9 @@ import inspect
import logging
import re
import unicodedata
from collections.abc import Iterable
from hashlib import md5
from typing import TYPE_CHECKING, Any, Dict, Iterable, Union
from typing import TYPE_CHECKING, Any, Union
from warnings import warn
from anyascii import anyascii
@ -256,7 +257,7 @@ def find_available_slug(parent, requested_slug, ignore_page_id=None):
return slug
@functools.lru_cache(maxsize=None)
@functools.cache
def get_content_languages():
"""
Cache of settings.WAGTAIL_CONTENT_LANGUAGES in a dictionary for easy lookups by key.
@ -545,7 +546,7 @@ class BatchCreator(BatchProcessor):
if self.max_size and len(self.items) == self.max_size:
self.process()
def extend(self, iterable: Iterable[Union[Model, Dict[str, Any]]]) -> None:
def extend(self, iterable: Iterable[Union[Model, dict[str, Any]]]) -> None:
for value in iterable:
if isinstance(value, self.model):
self.add(instance=value)

Wyświetl plik

@ -1,5 +1,3 @@
from typing import List
from django.utils.html import escape
from wagtail.documents import get_document_model
@ -20,7 +18,7 @@ class DocumentLinkHandler(LinkHandler):
return cls.expand_db_attributes_many([attrs])[0]
@classmethod
def expand_db_attributes_many(cls, attrs_list: List[dict]) -> List[str]:
def expand_db_attributes_many(cls, attrs_list: list[dict]) -> list[str]:
return [
'<a href="%s">' % escape(doc.url) if doc else "<a>"
for doc in cls.get_many(attrs_list)

Wyświetl plik

@ -8,10 +8,11 @@ import os.path
import re
import time
from collections import OrderedDict, defaultdict
from collections.abc import Iterable
from contextlib import contextmanager
from io import BytesIO
from tempfile import SpooledTemporaryFile
from typing import Any, Dict, Iterable, List, Optional, Union
from typing import Any
import willow
from django.apps import apps
@ -442,12 +443,12 @@ class AbstractImage(ImageFileMixin, CollectionMember, index.Indexed, models.Mode
"""Get the Rendition model for this Image model"""
return cls.renditions.rel.related_model
def _get_prefetched_renditions(self) -> Union[Iterable["AbstractRendition"], None]:
def _get_prefetched_renditions(self) -> Iterable[AbstractRendition] | None:
if "renditions" in getattr(self, "_prefetched_objects_cache", {}):
return self.renditions.all()
return getattr(self, "prefetched_renditions", None)
def _add_to_prefetched_renditions(self, rendition: "AbstractRendition") -> None:
def _add_to_prefetched_renditions(self, rendition: AbstractRendition) -> None:
# Reuse this rendition if requested again from this object
try:
self._prefetched_objects_cache["renditions"]._result_cache.append(rendition)
@ -458,7 +459,7 @@ class AbstractImage(ImageFileMixin, CollectionMember, index.Indexed, models.Mode
except AttributeError:
pass
def get_rendition(self, filter: Union["Filter", str]) -> "AbstractRendition":
def get_rendition(self, filter: Filter | str) -> AbstractRendition:
"""
Returns a ``Rendition`` instance with a ``file`` field value (an
image) reflecting the supplied ``filter`` value and focal point values
@ -486,7 +487,7 @@ class AbstractImage(ImageFileMixin, CollectionMember, index.Indexed, models.Mode
return rendition
def find_existing_rendition(self, filter: "Filter") -> "AbstractRendition":
def find_existing_rendition(self, filter: Filter) -> AbstractRendition:
"""
Returns an existing ``Rendition`` instance with a ``file`` field value
(an image) reflecting the supplied ``filter`` value and focal point
@ -505,7 +506,7 @@ class AbstractImage(ImageFileMixin, CollectionMember, index.Indexed, models.Mode
except KeyError:
raise Rendition.DoesNotExist
def create_rendition(self, filter: "Filter") -> "AbstractRendition":
def create_rendition(self, filter: Filter) -> AbstractRendition:
"""
Creates and returns a ``Rendition`` instance with a ``file`` field
value (an image) reflecting the supplied ``filter`` value and focal
@ -526,9 +527,7 @@ class AbstractImage(ImageFileMixin, CollectionMember, index.Indexed, models.Mode
)
return rendition
def get_renditions(
self, *filters: Union["Filter", str]
) -> Dict[str, "AbstractRendition"]:
def get_renditions(self, *filters: Filter | str) -> dict[str, AbstractRendition]:
"""
Returns a ``dict`` of ``Rendition`` instances with image files reflecting
the supplied ``filters``, keyed by filter spec patterns.
@ -566,8 +565,8 @@ class AbstractImage(ImageFileMixin, CollectionMember, index.Indexed, models.Mode
return {filter.spec: renditions[filter] for filter in filters}
def find_existing_renditions(
self, *filters: "Filter"
) -> Dict["Filter", "AbstractRendition"]:
self, *filters: Filter
) -> dict[Filter, AbstractRendition]:
"""
Returns a dictionary of existing ``Rendition`` instances with ``file``
values (images) reflecting the supplied ``filters`` and the focal point
@ -578,8 +577,8 @@ class AbstractImage(ImageFileMixin, CollectionMember, index.Indexed, models.Mode
created before, the return value will be an empty dict.
"""
Rendition = self.get_rendition_model()
filters_by_spec: Dict[str, Filter] = {f.spec: f for f in filters}
found: Dict[Filter, AbstractRendition] = {}
filters_by_spec: dict[str, Filter] = {f.spec: f for f in filters}
found: dict[Filter, AbstractRendition] = {}
# Interrogate prefetched values first (where available)
prefetched_renditions = self._get_prefetched_renditions()
@ -589,7 +588,7 @@ class AbstractImage(ImageFileMixin, CollectionMember, index.Indexed, models.Mode
# prefetched value, and further cache/database lookups are avoided.
# group renditions by the filters of interest
potential_matches: Dict[Filter, List[AbstractRendition]] = defaultdict(list)
potential_matches: dict[Filter, list[AbstractRendition]] = defaultdict(list)
for rendition in prefetched_renditions:
try:
filter = filters_by_spec[rendition.filter_spec]
@ -637,9 +636,7 @@ class AbstractImage(ImageFileMixin, CollectionMember, index.Indexed, models.Mode
found[filter] = rendition
return found
def create_renditions(
self, *filters: "Filter"
) -> Dict["Filter", "AbstractRendition"]:
def create_renditions(self, *filters: Filter) -> dict[Filter, AbstractRendition]:
"""
Creates multiple ``Rendition`` instances with image files reflecting the supplied
``filters``, and returns them as a ``dict`` keyed by the relevant ``Filter`` instance.
@ -664,8 +661,8 @@ class AbstractImage(ImageFileMixin, CollectionMember, index.Indexed, models.Mode
filter = filters[0]
return {filter: self.create_rendition(filter)}
return_value: Dict[Filter, AbstractRendition] = {}
filter_map: Dict[str, Filter] = {f.spec: f for f in filters}
return_value: dict[Filter, AbstractRendition] = {}
filter_map: dict[str, Filter] = {f.spec: f for f in filters}
# Read file contents into memory
with self.open_file() as file:
@ -688,7 +685,7 @@ class AbstractImage(ImageFileMixin, CollectionMember, index.Indexed, models.Mode
# identical renditions in the meantime, we should find them to avoid clashes.
# NB: Clashes can still occur, because there is no get_or_create() equivalent
# for multiple objects. However, this will reduce that risk considerably.
files_for_deletion: List[File] = []
files_for_deletion: list[File] = []
# Assemble Q() to identify potential clashes
lookup_q = Q()
@ -724,8 +721,8 @@ class AbstractImage(ImageFileMixin, CollectionMember, index.Indexed, models.Mode
return return_value
def generate_rendition_instance(
self, filter: "Filter", source: BytesIO
) -> "AbstractRendition":
self, filter: Filter, source: BytesIO
) -> AbstractRendition:
"""
Use the supplied ``source`` image to create and return an
**unsaved** ``Rendition`` instance, with a ``file`` value reflecting
@ -740,7 +737,7 @@ class AbstractImage(ImageFileMixin, CollectionMember, index.Indexed, models.Mode
),
)
def generate_rendition_file(self, filter: "Filter", *, source: File = None) -> File:
def generate_rendition_file(self, filter: Filter, *, source: File = None) -> File:
"""
Generates an in-memory image matching the supplied ``filter`` value
and focal point value from this object, wraps it in a ``File`` object
@ -877,7 +874,7 @@ class Filter:
self.spec = spec
@classmethod
def expand_spec(self, spec: Union["str", Iterable["str"]]) -> List["str"]:
def expand_spec(self, spec: str | Iterable[str]) -> list[str]:
"""
Converts a spec pattern with brace-expansions, into a list of spec patterns.
For example, "width-{100,200}" becomes ["width-100", "width-200"].
@ -1092,14 +1089,14 @@ class ResponsiveImage:
def __init__(
self,
renditions: Dict[str, "AbstractRendition"],
attrs: Optional[Dict[str, Any]] = None,
renditions: dict[str, AbstractRendition],
attrs: dict[str, Any] | None = None,
):
self.renditions = list(renditions.values())
self.attrs = attrs
@classmethod
def get_width_srcset(cls, renditions_list: List["AbstractRendition"]):
def get_width_srcset(cls, renditions_list: list[AbstractRendition]):
if len(renditions_list) == 1:
# No point in using width descriptors if there is a single image.
return renditions_list[0].url
@ -1122,7 +1119,7 @@ class ResponsiveImage:
def __bool__(self):
return bool(self.renditions)
def __eq__(self, other: "ResponsiveImage"):
def __eq__(self, other: ResponsiveImage):
if isinstance(other, ResponsiveImage):
return self.renditions == other.renditions and self.attrs == other.attrs
return False
@ -1138,16 +1135,16 @@ class Picture(ResponsiveImage):
def __init__(
self,
renditions: Dict[str, "AbstractRendition"],
attrs: Optional[Dict[str, Any]] = None,
renditions: dict[str, AbstractRendition],
attrs: dict[str, Any] | None = None,
):
super().__init__(renditions, attrs)
# Store renditions grouped by format separately for access from templates.
self.formats = self.get_formats(renditions)
def get_formats(
self, renditions: Dict[str, "AbstractRendition"]
) -> Dict[str, List["AbstractRendition"]]:
self, renditions: dict[str, AbstractRendition]
) -> dict[str, list[AbstractRendition]]:
"""
Group renditions by the format they are for, if any.
If there is only one format, no grouping is required.

Wyświetl plik

@ -1,5 +1,3 @@
from typing import List
from wagtail.images import get_image_model
from wagtail.images.formats import get_image_format
from wagtail.rich_text import EmbedHandler
@ -19,7 +17,7 @@ class ImageEmbedHandler(EmbedHandler):
return cls.expand_db_attributes_many([attrs])[0]
@classmethod
def expand_db_attributes_many(cls, attrs_list: List[dict]) -> List[str]:
def expand_db_attributes_many(cls, attrs_list: list[dict]) -> list[str]:
"""
Given a dict of attributes from the <embed> tag, return the real HTML
representation for use on the front-end.

Wyświetl plik

@ -193,7 +193,7 @@ def get_default_page_content_type():
return ContentType.objects.get_for_model(Page)
@functools.lru_cache(maxsize=None)
@functools.cache
def get_streamfield_names(model_class):
return tuple(
field.name
@ -1295,7 +1295,7 @@ class Page(AbstractPage, index.Indexed, ClusterableModel, metaclass=PageBase):
private_page_options = ["password", "groups", "login"]
@staticmethod
def route_for_request(request: "HttpRequest", path: str) -> RouteResult | None:
def route_for_request(request: HttpRequest, path: str) -> RouteResult | None:
"""
Find the page route for the given HTTP request object, and URL path. The route
result (`page`, `args`, and `kwargs`) will be cached via
@ -1322,7 +1322,7 @@ class Page(AbstractPage, index.Indexed, ClusterableModel, metaclass=PageBase):
return request._wagtail_route_for_request
@staticmethod
def find_for_request(request: "HttpRequest", path: str) -> "Page" | None:
def find_for_request(request: HttpRequest, path: str) -> Page | None:
"""
Find the page for the given HTTP request object, and URL path. The full
page route will be cached via `request._wagtail_route_for_request`

Wyświetl plik

@ -158,9 +158,7 @@ class BaseLogEntryManager(models.Manager):
content_type = ContentType.objects.get_for_id(
permission.content_type_id
)
if user.has_perm(
"%s.%s" % (content_type.app_label, permission.codename)
):
if user.has_perm(f"{content_type.app_label}.{permission.codename}"):
allowed_content_type_ids.add(permission.content_type_id)
user._allowed_content_type_ids = allowed_content_type_ids

Wyświetl plik

@ -1,5 +1,4 @@
import uuid
from typing import Dict
from django.apps import apps
from django.conf import settings
@ -98,7 +97,7 @@ class Locale(models.Model):
def __str__(self):
return force_str(self.get_display_name())
def _get_language_info(self) -> Dict[str, str]:
def _get_language_info(self) -> dict[str, str]:
return translation.get_language_info(self.language_code)
@property

Wyświetl plik

@ -1,7 +1,8 @@
import posixpath
import warnings
from collections import defaultdict
from typing import Any, Dict, Iterable, Tuple
from collections.abc import Iterable
from typing import Any
from django.apps import apps
from django.contrib.contenttypes.models import ContentType
@ -588,7 +589,7 @@ class SpecificIterable(BaseIterable):
setattr(item, annotation, value)
yield item
def _get_chunks(self, queryset) -> Iterable[Tuple[Dict[str, Any]]]:
def _get_chunks(self, queryset) -> Iterable[tuple[dict[str, Any]]]:
if not self.chunked_fetch:
# The entire result will be stored in memory, so there is no
# benefit to splitting the result

Wyświetl plik

@ -1,7 +1,6 @@
import re
from functools import lru_cache
from html import unescape
from typing import List
from django.core.validators import MaxLengthValidator
from django.db.models import Model
@ -132,7 +131,7 @@ class EntityHandler:
return model._default_manager.get(id=attrs["id"])
@classmethod
def get_many(cls, attrs_list: List[dict]) -> List[Model]:
def get_many(cls, attrs_list: list[dict]) -> list[Model]:
model = cls.get_model()
instance_ids = [attrs.get("id") for attrs in attrs_list]
instances_by_id = model._default_manager.in_bulk(instance_ids)
@ -148,7 +147,7 @@ class EntityHandler:
raise NotImplementedError
@classmethod
def expand_db_attributes_many(cls, attrs_list: List[dict]) -> List[str]:
def expand_db_attributes_many(cls, attrs_list: list[dict]) -> list[str]:
"""
Given a list of attribute dicts from a list of entity tags stored in
the database, return the real HTML representation of each one.

Wyświetl plik

@ -1,5 +1,3 @@
from typing import List
from django.db.models import Model
from django.utils.html import escape
@ -15,7 +13,7 @@ class PageLinkHandler(LinkHandler):
return Page
@classmethod
def get_many(cls, attrs_list: List[dict]) -> List[Model]:
def get_many(cls, attrs_list: list[dict]) -> list[Model]:
# Override LinkHandler.get_many to reduce database queries through the
# use of PageQuerySet.specific() instead of QuerySet.in_bulk().
instance_ids = [attrs.get("id") for attrs in attrs_list]
@ -28,7 +26,7 @@ class PageLinkHandler(LinkHandler):
return cls.expand_db_attributes_many([attrs])[0]
@classmethod
def expand_db_attributes_many(cls, attrs_list: List[dict]) -> List[str]:
def expand_db_attributes_many(cls, attrs_list: list[dict]) -> list[str]:
return [
'<a href="%s">' % escape(page.localized.url) if page else "<a>"
for page in cls.get_many(attrs_list)

Wyświetl plik

@ -4,7 +4,7 @@ Utility classes for rewriting elements of HTML-like strings
import re
from collections import defaultdict
from typing import Callable, Dict, List
from typing import Callable
from django.utils.functional import cached_property
@ -101,7 +101,7 @@ class TagRewriter:
return html
def extract_tags(self, html: str) -> Dict[str, List[TagMatch]]:
def extract_tags(self, html: str) -> dict[str, list[TagMatch]]:
"""Helper method to extract and group HTML tags and their attributes.
Returns a dict of TagMatch objects, mapping tag types to a list of all TagMatch objects of that tag type.

Wyświetl plik

@ -1,5 +1,5 @@
import re
from typing import Any, List, Tuple, Union
from typing import Any, Union
from django.db.backends.base.base import BaseDatabaseWrapper
from django.db.models.expressions import CombinedExpression, Expression, Value
@ -166,7 +166,7 @@ class SearchQuery(SearchQueryCombinable, Expression):
compiler: SQLCompiler,
connection: BaseDatabaseWrapper,
**extra_context: Any,
) -> Tuple[str, List[Any]]:
) -> tuple[str, list[Any]]:
sql, params = compiler.compile(self.value)
return (sql, params)
@ -229,7 +229,7 @@ class MatchExpression(Expression):
def __init__(
self,
query: SearchQueryCombinable,
columns: List[str] = None,
columns: list[str] = None,
output_field: Field = BooleanField(),
) -> None:
super().__init__(output_field=output_field)

Wyświetl plik

@ -1,4 +1,4 @@
from typing import Any, List, Tuple
from typing import Any
from django.db.backends.base.base import BaseDatabaseWrapper
from django.db.models.expressions import CombinedExpression, Expression, Func, Value
@ -149,7 +149,7 @@ class SearchQueryExpression(SearchQueryCombinable, Expression):
compiler: SQLCompiler,
connection: BaseDatabaseWrapper,
**extra_context: Any,
) -> Tuple[str, List[Any]]:
) -> tuple[str, list[Any]]:
sql, params = compiler.compile(self.value)
return (sql, params)
@ -172,7 +172,7 @@ class MatchExpression(Expression):
)
output_field = BooleanField()
def __init__(self, columns: List[str], query: SearchQueryCombinable) -> None:
def __init__(self, columns: list[str], query: SearchQueryCombinable) -> None:
super().__init__(output_field=self.output_field)
self.columns = columns
self.query = query
@ -211,7 +211,7 @@ class AndNot(SearchQuery):
return f"<{repr(self.subquery_a)} AndNot {repr(self.subquery_b)}>"
def normalize(search_query: SearchQuery) -> Tuple[SearchQuery]:
def normalize(search_query: SearchQuery) -> tuple[SearchQuery]:
"""
Turns this query into a normalized version.
For example, And(Not(PlainText("Arepa")), PlainText("Crepe")) would be turned into AndNot(PlainText("Crepe"), PlainText("Arepa")): "Crepe AND NOT Arepa".
@ -222,7 +222,7 @@ def normalize(search_query: SearchQuery) -> Tuple[SearchQuery]:
if isinstance(search_query, PlainText):
return search_query # We can't normalize a PlainText.
if isinstance(search_query, And):
normalized_subqueries: List[SearchQuery] = [
normalized_subqueries: list[SearchQuery] = [
normalize(subquery) for subquery in search_query.subqueries
] # This builds a list of normalized subqueries.
@ -255,7 +255,7 @@ def normalize(search_query: SearchQuery) -> Tuple[SearchQuery]:
return AndNot(And(not_negated_subqueries), Or(negated_subqueries))
if isinstance(search_query, Or):
normalized_subqueries: List[SearchQuery] = [
normalized_subqueries: list[SearchQuery] = [
normalize(subquery) for subquery in search_query.subqueries
] # This builds a list of (subquery, negated) tuples.

Wyświetl plik

@ -7,7 +7,7 @@ class CustomRichTextArea(widgets.Textarea):
# mock rendering for individual custom widget
return mark_safe(
'<template data-controller="custom-editor" data-id="{0}">{1}</template>'.format(
'<template data-controller="custom-editor" data-id="{}">{}</template>'.format(
attrs["id"],
super().render(name, value, attrs),
)
@ -22,7 +22,7 @@ class LegacyRichTextArea(widgets.Textarea):
def render(self, name, value, attrs=None, renderer=None):
# mock rendering for individual custom widget
return mark_safe(
'<template data-controller="legacy-editor" data-id="{0}">{1}</template>'.format(
'<template data-controller="legacy-editor" data-id="{}">{}</template>'.format(
attrs["id"],
super().render(name, value, attrs),
)

Wyświetl plik

@ -1,4 +1,4 @@
from typing import Any, Dict, Optional
from typing import Any, Optional
from unittest import mock
from django.conf import settings
@ -217,8 +217,8 @@ class WagtailPageTestCase(WagtailTestUtils, TestCase):
self,
page: Page,
route_path: Optional[str] = "/",
query_data: Optional[Dict[str, Any]] = None,
post_data: Optional[Dict[str, Any]] = None,
query_data: Optional[dict[str, Any]] = None,
post_data: Optional[dict[str, Any]] = None,
user: Optional[AbstractBaseUser] = None,
accept_404: Optional[bool] = False,
accept_redirect: Optional[bool] = False,
@ -297,7 +297,7 @@ class WagtailPageTestCase(WagtailTestUtils, TestCase):
def assertPageIsEditable(
self,
page: Page,
post_data: Optional[Dict[str, Any]] = None,
post_data: Optional[dict[str, Any]] = None,
user: Optional[AbstractBaseUser] = None,
msg: Optional[str] = None,
):
@ -379,7 +379,7 @@ class WagtailPageTestCase(WagtailTestUtils, TestCase):
self,
page: Page,
mode: Optional[str] = "",
post_data: Optional[Dict[str, Any]] = None,
post_data: Optional[dict[str, Any]] = None,
user: Optional[AbstractBaseUser] = None,
msg: Optional[str] = None,
):

Wyświetl plik

@ -1,4 +1,4 @@
from typing import Dict, List, Union
from typing import Union
from django.test import SimpleTestCase
@ -10,7 +10,7 @@ class AdminTemplateTestUtils:
def assertBreadcrumbsItemsRendered(
self: Union[WagtailTestUtils, SimpleTestCase],
items: List[Dict[str, str]],
items: list[dict[str, str]],
html: Union[str, bytes],
):
soup = self.get_soup(html)