kopia lustrzana https://github.com/wagtail/wagtail
				
				
				
			Bump ruff to 0.9.6
							rodzic
							
								
									8998549807
								
							
						
					
					
						commit
						a81b119821
					
				| 
						 | 
				
			
			@ -3,7 +3,7 @@ default_language_version:
 | 
			
		|||
  python: python3
 | 
			
		||||
repos:
 | 
			
		||||
  - repo: https://github.com/astral-sh/ruff-pre-commit
 | 
			
		||||
    rev: 'v0.1.5'
 | 
			
		||||
    rev: 'v0.9.6'
 | 
			
		||||
    hooks:
 | 
			
		||||
      - id: ruff
 | 
			
		||||
        args: [--fix, --exit-non-zero-on-fix]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								ruff.toml
								
								
								
								
							
							
						
						
									
										17
									
								
								ruff.toml
								
								
								
								
							| 
						 | 
				
			
			@ -1,3 +1,14 @@
 | 
			
		|||
exclude = [
 | 
			
		||||
  "wagtail/project_template/*",
 | 
			
		||||
  "node_modules",
 | 
			
		||||
  "venv",
 | 
			
		||||
  ".venv",
 | 
			
		||||
  "migrations",
 | 
			
		||||
]
 | 
			
		||||
line-length = 88
 | 
			
		||||
target-version = "py39" # minimum target version
 | 
			
		||||
 | 
			
		||||
[lint]
 | 
			
		||||
# D100: Missing docstring in public module
 | 
			
		||||
# D101: Missing docstring in public class
 | 
			
		||||
# D102: Missing docstring in public method
 | 
			
		||||
| 
						 | 
				
			
			@ -5,11 +16,7 @@
 | 
			
		|||
# D105: Missing docstring in magic method
 | 
			
		||||
# N806: Variable in function should be lowercase
 | 
			
		||||
# E501: Line too long
 | 
			
		||||
ignore = ["D100","D101","D102","D103","D105","N806","E501"]
 | 
			
		||||
exclude = ["wagtail/project_template/*","node_modules","venv",".venv","migrations"]
 | 
			
		||||
line-length = 88
 | 
			
		||||
 | 
			
		||||
target-version = "py38"  # minimum target version
 | 
			
		||||
ignore = ["D100", "D101", "D102", "D103", "D105", "N806", "E501"]
 | 
			
		||||
 | 
			
		||||
# E: pycodestyle errors
 | 
			
		||||
# F: Pyflakes
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								setup.py
								
								
								
								
							
							
						
						
									
										2
									
								
								setup.py
								
								
								
								
							| 
						 | 
				
			
			@ -51,7 +51,7 @@ testing_extras = [
 | 
			
		|||
    # For coverage and PEP8 linting
 | 
			
		||||
    "coverage>=3.7.0",
 | 
			
		||||
    "doc8==0.8.1",
 | 
			
		||||
    "ruff==0.1.5",
 | 
			
		||||
    "ruff==0.9.6",
 | 
			
		||||
    # For enforcing string formatting mechanism in source files
 | 
			
		||||
    "semgrep==1.40.0",
 | 
			
		||||
    # For templates linting
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -215,10 +215,10 @@ class CopyPageAction:
 | 
			
		|||
                            self.reset_translation_key
 | 
			
		||||
                            and "translation_key" in child_object
 | 
			
		||||
                        ):
 | 
			
		||||
                            child_object[
 | 
			
		||||
                                "translation_key"
 | 
			
		||||
                            ] = self.generate_translation_key(
 | 
			
		||||
                                child_object["translation_key"]
 | 
			
		||||
                            child_object["translation_key"] = (
 | 
			
		||||
                                self.generate_translation_key(
 | 
			
		||||
                                    child_object["translation_key"]
 | 
			
		||||
                                )
 | 
			
		||||
                            )
 | 
			
		||||
 | 
			
		||||
                for exclude_field in specific_page.exclude_fields_in_copy:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,5 @@
 | 
			
		|||
"""Handles rendering of the list of actions in the footer of the page create/edit views."""
 | 
			
		||||
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
from django.forms import Media
 | 
			
		||||
from django.template.loader import render_to_string
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
import functools
 | 
			
		||||
import types
 | 
			
		||||
 | 
			
		||||
import zoneinfo
 | 
			
		||||
 | 
			
		||||
from django import VERSION as DJANGO_VERSION
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
from django.utils.dates import MONTHS, WEEKDAYS, WEEKDAYS_ABBR
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -110,8 +110,7 @@ class FieldPanel(Panel):
 | 
			
		|||
            labels = dict(choices)
 | 
			
		||||
            display_values = [
 | 
			
		||||
                str(labels.get(v, v))  # Use raw value if no match found
 | 
			
		||||
                for v in
 | 
			
		||||
                (
 | 
			
		||||
                for v in (
 | 
			
		||||
                    # Account for single AND multiple choice fields
 | 
			
		||||
                    tuple(value) if isinstance(value, (list, tuple)) else (value,)
 | 
			
		||||
                )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,9 +38,9 @@ class MultipleChooserPanel(InlinePanel):
 | 
			
		|||
        def get_context_data(self, parent_context=None):
 | 
			
		||||
            context = super().get_context_data(parent_context)
 | 
			
		||||
            context["chooser_field_name"] = self.panel.chooser_field_name
 | 
			
		||||
            context[
 | 
			
		||||
                "chooser_widget_definition"
 | 
			
		||||
            ] = self.chooser_widget_telepath_definition
 | 
			
		||||
            context["chooser_widget_definition"] = (
 | 
			
		||||
                self.chooser_widget_telepath_definition
 | 
			
		||||
            )
 | 
			
		||||
            return context
 | 
			
		||||
 | 
			
		||||
        @property
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -121,12 +121,12 @@ class BlockElementHandler:
 | 
			
		|||
        state.has_preceding_nonatomic_block = True
 | 
			
		||||
 | 
			
		||||
    def handle_endtag(self, name, state, contentState):
 | 
			
		||||
        assert (
 | 
			
		||||
            not state.current_inline_styles
 | 
			
		||||
        ), "End of block reached without closing inline style elements"
 | 
			
		||||
        assert (
 | 
			
		||||
            not state.current_entity_ranges
 | 
			
		||||
        ), "End of block reached without closing entity elements"
 | 
			
		||||
        assert not state.current_inline_styles, (
 | 
			
		||||
            "End of block reached without closing inline style elements"
 | 
			
		||||
        )
 | 
			
		||||
        assert not state.current_entity_ranges, (
 | 
			
		||||
            "End of block reached without closing entity elements"
 | 
			
		||||
        )
 | 
			
		||||
        state.current_block = None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -246,10 +246,10 @@ def test_collection_is_public(context, collection):
 | 
			
		|||
    DB queries on repeated calls.
 | 
			
		||||
    """
 | 
			
		||||
    if "all_collection_view_restrictions" not in context:
 | 
			
		||||
        context[
 | 
			
		||||
            "all_collection_view_restrictions"
 | 
			
		||||
        ] = CollectionViewRestriction.objects.select_related("collection").values_list(
 | 
			
		||||
            "collection__name", flat=True
 | 
			
		||||
        context["all_collection_view_restrictions"] = (
 | 
			
		||||
            CollectionViewRestriction.objects.select_related("collection").values_list(
 | 
			
		||||
                "collection__name", flat=True
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    is_private = collection.name in context["all_collection_view_restrictions"]
 | 
			
		||||
| 
						 | 
				
			
			@ -1269,9 +1269,9 @@ def formattedfield(
 | 
			
		|||
 | 
			
		||||
    if field:
 | 
			
		||||
        context["rendered_field"] = rendered_field or render_with_errors(field)
 | 
			
		||||
        context[
 | 
			
		||||
            "field_classname"
 | 
			
		||||
        ] = f"w-field--{ fieldtype(field) } w-field--{ widgettype(field) }"
 | 
			
		||||
        context["field_classname"] = (
 | 
			
		||||
            f"w-field--{fieldtype(field)} w-field--{widgettype(field)}"
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        errors = field.errors
 | 
			
		||||
        has_errors = bool(errors)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,8 +36,7 @@ class TestRevisions(WagtailTestUtils, TestCase):
 | 
			
		|||
        self.christmas_event.title = "This Christmas"
 | 
			
		||||
        self.christmas_event.date_from = "2014-12-25"
 | 
			
		||||
        self.christmas_event.body = (
 | 
			
		||||
            "<p>This year, to save me from tears, "
 | 
			
		||||
            "I'll give it to someone special</p>"
 | 
			
		||||
            "<p>This year, to save me from tears, I'll give it to someone special</p>"
 | 
			
		||||
        )
 | 
			
		||||
        self.this_christmas_revision = self.christmas_event.save_revision()
 | 
			
		||||
        self.this_christmas_revision.created_at = local_datetime(2014, 12, 25)
 | 
			
		||||
| 
						 | 
				
			
			@ -226,8 +225,7 @@ class TestCompareRevisions(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
 | 
			
		|||
        self.christmas_event.title = "This Christmas"
 | 
			
		||||
        self.christmas_event.date_from = "2014-12-25"
 | 
			
		||||
        self.christmas_event.body = (
 | 
			
		||||
            "<p>This year, to save me from tears, "
 | 
			
		||||
            "I'll give it to someone special</p>"
 | 
			
		||||
            "<p>This year, to save me from tears, I'll give it to someone special</p>"
 | 
			
		||||
        )
 | 
			
		||||
        self.this_christmas_revision = self.christmas_event.save_revision()
 | 
			
		||||
        self.this_christmas_revision.created_at = local_datetime(2014, 12, 25)
 | 
			
		||||
| 
						 | 
				
			
			@ -311,7 +309,7 @@ class TestCompareRevisions(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
 | 
			
		|||
    def test_compare_revisions_live(self):
 | 
			
		||||
        # Mess with the live version, bypassing revisions
 | 
			
		||||
        self.christmas_event.body = (
 | 
			
		||||
            "<p>This year, to save me from tears, " "I'll just feed it to the dog</p>"
 | 
			
		||||
            "<p>This year, to save me from tears, I'll just feed it to the dog</p>"
 | 
			
		||||
        )
 | 
			
		||||
        self.christmas_event.save(update_fields=["body"])
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -480,8 +478,7 @@ class TestRevisionsUnschedule(WagtailTestUtils, TestCase):
 | 
			
		|||
        self.christmas_event.title = "This Christmas"
 | 
			
		||||
        self.christmas_event.date_from = "2014-12-25"
 | 
			
		||||
        self.christmas_event.body = (
 | 
			
		||||
            "<p>This year, to save me from tears, "
 | 
			
		||||
            "I'll give it to someone special</p>"
 | 
			
		||||
            "<p>This year, to save me from tears, I'll give it to someone special</p>"
 | 
			
		||||
        )
 | 
			
		||||
        self.this_christmas_revision = self.christmas_event.save_revision()
 | 
			
		||||
        self.this_christmas_revision.created_at = local_datetime(2014, 12, 24)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
import unittest
 | 
			
		||||
 | 
			
		||||
import zoneinfo
 | 
			
		||||
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
from django.contrib.auth import get_user_model
 | 
			
		||||
from django.contrib.auth import views as auth_views
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
"""
 | 
			
		||||
Tests for the search box in the admin side menu, and the custom search hooks.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
from django.contrib.auth.models import Permission
 | 
			
		||||
from django.template import Context, Template
 | 
			
		||||
from django.test import RequestFactory, SimpleTestCase, TestCase
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -87,11 +87,16 @@ class TestPageListingMoreButtonsHooks(TestButtonsHooks):
 | 
			
		|||
                priority=10,
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
        with hooks.register_temporarily(
 | 
			
		||||
            "register_page_listing_more_buttons", page_listing_more_buttons
 | 
			
		||||
        ), self.assertWarnsMessage(
 | 
			
		||||
            RemovedInWagtail70Warning,
 | 
			
		||||
            "`register_page_listing_more_buttons` hook functions should accept a `user` argument instead of `page_perms`",
 | 
			
		||||
        with (
 | 
			
		||||
            hooks.register_temporarily(
 | 
			
		||||
                "register_page_listing_more_buttons",
 | 
			
		||||
                page_listing_more_buttons,
 | 
			
		||||
            ),
 | 
			
		||||
            self.assertWarnsMessage(
 | 
			
		||||
                RemovedInWagtail70Warning,
 | 
			
		||||
                "`register_page_listing_more_buttons` hook functions should "
 | 
			
		||||
                "accept a `user` argument instead of `page_perms`",
 | 
			
		||||
            ),
 | 
			
		||||
        ):
 | 
			
		||||
            response = self.client.get(
 | 
			
		||||
                reverse("wagtailadmin_explore", args=(self.root_page.id,))
 | 
			
		||||
| 
						 | 
				
			
			@ -173,14 +178,20 @@ class TestPageListingMoreButtonsHooks(TestButtonsHooks):
 | 
			
		|||
                priority=10,
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
        with hooks.register_temporarily(
 | 
			
		||||
            "register_page_listing_buttons", page_custom_listing_buttons
 | 
			
		||||
        ), hooks.register_temporarily(
 | 
			
		||||
            "register_page_listing_one_more_more_buttons",
 | 
			
		||||
            page_custom_listing_more_buttons,
 | 
			
		||||
        ), self.assertWarnsMessage(
 | 
			
		||||
            RemovedInWagtail70Warning,
 | 
			
		||||
            "`register_page_listing_one_more_more_buttons` hook functions should accept a `user` argument instead of `page_perms`",
 | 
			
		||||
        with (
 | 
			
		||||
            hooks.register_temporarily(
 | 
			
		||||
                "register_page_listing_buttons",
 | 
			
		||||
                page_custom_listing_buttons,
 | 
			
		||||
            ),
 | 
			
		||||
            hooks.register_temporarily(
 | 
			
		||||
                "register_page_listing_one_more_more_buttons",
 | 
			
		||||
                page_custom_listing_more_buttons,
 | 
			
		||||
            ),
 | 
			
		||||
            self.assertWarnsMessage(
 | 
			
		||||
                RemovedInWagtail70Warning,
 | 
			
		||||
                "`register_page_listing_one_more_more_buttons` hook functions "
 | 
			
		||||
                "should accept a `user` argument instead of `page_perms`",
 | 
			
		||||
            ),
 | 
			
		||||
        ):
 | 
			
		||||
            response = self.client.get(
 | 
			
		||||
                reverse("wagtailadmin_explore", args=(self.root_page.id,))
 | 
			
		||||
| 
						 | 
				
			
			@ -220,11 +231,15 @@ class TestPageListingMoreButtonsHooks(TestButtonsHooks):
 | 
			
		|||
                priority=10,
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
        with hooks.register_temporarily(
 | 
			
		||||
            "register_page_listing_buttons", page_custom_listing_buttons
 | 
			
		||||
        ), hooks.register_temporarily(
 | 
			
		||||
            "register_page_listing_one_more_more_buttons",
 | 
			
		||||
            page_custom_listing_more_buttons,
 | 
			
		||||
        with (
 | 
			
		||||
            hooks.register_temporarily(
 | 
			
		||||
                "register_page_listing_buttons",
 | 
			
		||||
                page_custom_listing_buttons,
 | 
			
		||||
            ),
 | 
			
		||||
            hooks.register_temporarily(
 | 
			
		||||
                "register_page_listing_one_more_more_buttons",
 | 
			
		||||
                page_custom_listing_more_buttons,
 | 
			
		||||
            ),
 | 
			
		||||
        ):
 | 
			
		||||
            response = self.client.get(
 | 
			
		||||
                reverse("wagtailadmin_explore", args=(self.root_page.id,))
 | 
			
		||||
| 
						 | 
				
			
			@ -327,11 +342,16 @@ class TestPageHeaderButtonsHooks(TestButtonsHooks):
 | 
			
		|||
                "Another useless header button", "/custom-url", priority=10
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
        with hooks.register_temporarily(
 | 
			
		||||
            "register_page_header_buttons", custom_page_header_buttons
 | 
			
		||||
        ), self.assertWarnsMessage(
 | 
			
		||||
            RemovedInWagtail70Warning,
 | 
			
		||||
            "`register_page_header_buttons` hook functions should accept a `user` argument instead of `page_perms`",
 | 
			
		||||
        with (
 | 
			
		||||
            hooks.register_temporarily(
 | 
			
		||||
                "register_page_header_buttons",
 | 
			
		||||
                custom_page_header_buttons,
 | 
			
		||||
            ),
 | 
			
		||||
            self.assertWarnsMessage(
 | 
			
		||||
                RemovedInWagtail70Warning,
 | 
			
		||||
                "`register_page_header_buttons` hook functions should accept a "
 | 
			
		||||
                "`user` argument instead of `page_perms`",
 | 
			
		||||
            ),
 | 
			
		||||
        ):
 | 
			
		||||
            response = self.client.get(
 | 
			
		||||
                reverse("wagtailadmin_pages:edit", args=(self.root_page.id,))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,7 @@ from wagtail.embeds.models import Embed
 | 
			
		|||
 | 
			
		||||
def content_state_equal(v1, v2, match_keys=False):
 | 
			
		||||
    "Test whether two contentState structures are equal, ignoring 'key' properties if match_keys=False"
 | 
			
		||||
    if type(v1) != type(v2):
 | 
			
		||||
    if type(v1) is not type(v2):
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
    if isinstance(v1, dict):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -997,7 +997,7 @@ class TestChooserExternalLinkWithNonRootServePath(TestChooserExternalLink):
 | 
			
		|||
        self.assertEqual(response_json["internal"]["id"], self.internal_page.pk)
 | 
			
		||||
 | 
			
		||||
    def test_convert_external_link_with_query_parameters_to_internal_link_with_serve_path(
 | 
			
		||||
        self
 | 
			
		||||
        self,
 | 
			
		||||
    ):
 | 
			
		||||
        # https://github.com/wagtail/wagtail/issues/11996
 | 
			
		||||
        # New behaviour: when using a non-root serve path, entering a full
 | 
			
		||||
| 
						 | 
				
			
			@ -1067,7 +1067,7 @@ class TestChooserExternalLinkWithNonRootServePath(TestChooserExternalLink):
 | 
			
		|||
 | 
			
		||||
    @override_settings(WAGTAILADMIN_EXTERNAL_LINK_CONVERSION="")
 | 
			
		||||
    def test_no_conversion_external_to_internal_link_when_disabled_with_serve_path(
 | 
			
		||||
        self
 | 
			
		||||
        self,
 | 
			
		||||
    ):
 | 
			
		||||
        url = f"http://localhost/{self.prefix}about/"
 | 
			
		||||
        title = "about"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -120,7 +120,8 @@ class TestSetPrivacyView(WagtailTestUtils, TestCase):
 | 
			
		|||
        )
 | 
			
		||||
        html = response.json()["html"]
 | 
			
		||||
        self.assertIn(
 | 
			
		||||
            f'<span>Privacy is inherited from the ancestor page - <a href="{parent_edit_url }">Private page (simple page)</a></span>',
 | 
			
		||||
            f"<span>Privacy is inherited from the ancestor page - "
 | 
			
		||||
            f'<a href="{parent_edit_url}">Private page (simple page)</a></span>',
 | 
			
		||||
            html,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -793,13 +793,14 @@ class TestFilteredLogEntriesView(BaseReportViewTestCase):
 | 
			
		|||
    def test_decorated_queryset(self):
 | 
			
		||||
        # Ensure that decorate_paginated_queryset is only called with the queryset for the current
 | 
			
		||||
        # page, instead of all objects over all pages.
 | 
			
		||||
        with mock.patch.object(
 | 
			
		||||
            LogEntriesView,
 | 
			
		||||
            "decorate_paginated_queryset",
 | 
			
		||||
            side_effect=LogEntriesView.decorate_paginated_queryset,
 | 
			
		||||
            autospec=True,
 | 
			
		||||
        ) as decorate_paginated_queryset, mock.patch.object(
 | 
			
		||||
            LogEntriesView, "paginate_by", return_value=1
 | 
			
		||||
        with (
 | 
			
		||||
            mock.patch.object(
 | 
			
		||||
                LogEntriesView,
 | 
			
		||||
                "decorate_paginated_queryset",
 | 
			
		||||
                side_effect=LogEntriesView.decorate_paginated_queryset,
 | 
			
		||||
                autospec=True,
 | 
			
		||||
            ) as decorate_paginated_queryset,
 | 
			
		||||
            mock.patch.object(LogEntriesView, "paginate_by", return_value=1),
 | 
			
		||||
        ):
 | 
			
		||||
            response = self.get()
 | 
			
		||||
            decorate_paginated_queryset.assert_called_once()
 | 
			
		||||
| 
						 | 
				
			
			@ -810,16 +811,19 @@ class TestFilteredLogEntriesView(BaseReportViewTestCase):
 | 
			
		|||
 | 
			
		||||
    def test_deprecated_title_attribute(self):
 | 
			
		||||
        # Remove this test when the deprecation ends
 | 
			
		||||
        with mock.patch.object(
 | 
			
		||||
            LogEntriesView,
 | 
			
		||||
            "page_title",
 | 
			
		||||
            return_value=None,
 | 
			
		||||
            new_callable=mock.PropertyMock,
 | 
			
		||||
        ), mock.patch.object(
 | 
			
		||||
            LogEntriesView,
 | 
			
		||||
            "title",
 | 
			
		||||
            return_value="Deprecated page title",
 | 
			
		||||
            new_callable=mock.PropertyMock,
 | 
			
		||||
        with (
 | 
			
		||||
            mock.patch.object(
 | 
			
		||||
                LogEntriesView,
 | 
			
		||||
                "page_title",
 | 
			
		||||
                return_value=None,
 | 
			
		||||
                new_callable=mock.PropertyMock,
 | 
			
		||||
            ),
 | 
			
		||||
            mock.patch.object(
 | 
			
		||||
                LogEntriesView,
 | 
			
		||||
                "title",
 | 
			
		||||
                return_value="Deprecated page title",
 | 
			
		||||
                new_callable=mock.PropertyMock,
 | 
			
		||||
            ),
 | 
			
		||||
        ):
 | 
			
		||||
            with self.assertWarnsMessage(
 | 
			
		||||
                RemovedInWagtail70Warning,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -479,12 +479,16 @@ class TestUserbarInPageServe(WagtailTestUtils, TestCase):
 | 
			
		|||
            kwargs["called"] = True
 | 
			
		||||
            return items
 | 
			
		||||
 | 
			
		||||
        with self.assertWarnsMessage(
 | 
			
		||||
            RemovedInWagtail70Warning,
 | 
			
		||||
            "`construct_wagtail_userbar` hook functions should accept a `page` argument in third position",
 | 
			
		||||
        ), hooks.register_temporarily(
 | 
			
		||||
            "construct_wagtail_userbar",
 | 
			
		||||
            construct_wagtail_userbar,
 | 
			
		||||
        with (
 | 
			
		||||
            self.assertWarnsMessage(
 | 
			
		||||
                RemovedInWagtail70Warning,
 | 
			
		||||
                "`construct_wagtail_userbar` hook functions should accept a "
 | 
			
		||||
                "`page` argument in third position",
 | 
			
		||||
            ),
 | 
			
		||||
            hooks.register_temporarily(
 | 
			
		||||
                "construct_wagtail_userbar",
 | 
			
		||||
                construct_wagtail_userbar,
 | 
			
		||||
            ),
 | 
			
		||||
        ):
 | 
			
		||||
            response = self.page.serve(self.request)
 | 
			
		||||
            response.render()
 | 
			
		||||
| 
						 | 
				
			
			@ -522,12 +526,16 @@ class TestUserbarHooksForChecksPanel(WagtailTestUtils, TestCase):
 | 
			
		|||
            kwargs["called"] = True
 | 
			
		||||
            return items
 | 
			
		||||
 | 
			
		||||
        with self.assertWarnsMessage(
 | 
			
		||||
            RemovedInWagtail70Warning,
 | 
			
		||||
            "`construct_wagtail_userbar` hook functions should accept a `page` argument in third position",
 | 
			
		||||
        ), hooks.register_temporarily(
 | 
			
		||||
            "construct_wagtail_userbar",
 | 
			
		||||
            construct_wagtail_userbar,
 | 
			
		||||
        with (
 | 
			
		||||
            self.assertWarnsMessage(
 | 
			
		||||
                RemovedInWagtail70Warning,
 | 
			
		||||
                "`construct_wagtail_userbar` hook functions should accept a "
 | 
			
		||||
                "`page` argument in third position",
 | 
			
		||||
            ),
 | 
			
		||||
            hooks.register_temporarily(
 | 
			
		||||
                "construct_wagtail_userbar",
 | 
			
		||||
                construct_wagtail_userbar,
 | 
			
		||||
            ),
 | 
			
		||||
        ):
 | 
			
		||||
            response = self.client.get(
 | 
			
		||||
                reverse("wagtailadmin_pages:edit", args=(self.homepage.id,))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4633,7 +4633,7 @@ class TestWorkflowStateEmailNotifier(BasePageWorkflowTests):
 | 
			
		|||
        self.object.save_revision()
 | 
			
		||||
 | 
			
		||||
    def test_workflowstate_email_notifier_get_recipient_users__without_triggering_user(
 | 
			
		||||
        self
 | 
			
		||||
        self,
 | 
			
		||||
    ):
 | 
			
		||||
        self.workflow.start(self.object, user=self.submitter)
 | 
			
		||||
        workflow_state = self.object.current_workflow_state
 | 
			
		||||
| 
						 | 
				
			
			@ -4648,7 +4648,7 @@ class TestWorkflowStateEmailNotifier(BasePageWorkflowTests):
 | 
			
		|||
                )
 | 
			
		||||
 | 
			
		||||
    def test_workflowstate_email_notifier_get_recipient_users__with_triggering_user(
 | 
			
		||||
        self
 | 
			
		||||
        self,
 | 
			
		||||
    ):
 | 
			
		||||
        self.workflow.start(self.object, user=self.submitter)
 | 
			
		||||
        workflow_state = self.object.current_workflow_state
 | 
			
		||||
| 
						 | 
				
			
			@ -4664,7 +4664,7 @@ class TestWorkflowStateEmailNotifier(BasePageWorkflowTests):
 | 
			
		|||
                )
 | 
			
		||||
 | 
			
		||||
    def test_workflowstate_email_notifier_get_recipient_users__without_requested_by(
 | 
			
		||||
        self
 | 
			
		||||
        self,
 | 
			
		||||
    ):
 | 
			
		||||
        self.workflow.start(self.object, user=self.submitter)
 | 
			
		||||
        workflow_state: WorkflowState = self.object.current_workflow_state
 | 
			
		||||
| 
						 | 
				
			
			@ -4683,7 +4683,7 @@ class TestWorkflowStateEmailNotifier(BasePageWorkflowTests):
 | 
			
		|||
                )
 | 
			
		||||
 | 
			
		||||
    def test_workflowstate_email_notifier_get_recipient_users__with_same_requested_by_and_triggering_user(
 | 
			
		||||
        self
 | 
			
		||||
        self,
 | 
			
		||||
    ):
 | 
			
		||||
        self.workflow.start(self.object, user=self.submitter)
 | 
			
		||||
        workflow_state: WorkflowState = self.object.current_workflow_state
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -723,9 +723,9 @@ class CreateEditViewOptionalFeaturesMixin:
 | 
			
		|||
        context["draftstate_enabled"] = self.draftstate_enabled
 | 
			
		||||
        context["workflow_enabled"] = self.workflow_enabled
 | 
			
		||||
        context["workflow_history_url"] = self.get_workflow_history_url()
 | 
			
		||||
        context[
 | 
			
		||||
            "confirm_workflow_cancellation_url"
 | 
			
		||||
        ] = self.get_confirm_workflow_cancellation_url()
 | 
			
		||||
        context["confirm_workflow_cancellation_url"] = (
 | 
			
		||||
            self.get_confirm_workflow_cancellation_url()
 | 
			
		||||
        )
 | 
			
		||||
        context["publishing_will_cancel_workflow"] = getattr(
 | 
			
		||||
            settings, "WAGTAIL_WORKFLOW_CANCEL_ON_PUBLISH", True
 | 
			
		||||
        ) and bool(self.workflow_tasks)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,7 +73,6 @@ class IndexView(
 | 
			
		|||
    inspect_url_name = None
 | 
			
		||||
    delete_url_name = None
 | 
			
		||||
    any_permission_required = ["add", "change", "delete", "view"]
 | 
			
		||||
    columns = None  # If not explicitly specified, will be derived from list_display
 | 
			
		||||
    list_display = ["__str__", UpdatedAtColumn()]
 | 
			
		||||
    list_filter = None
 | 
			
		||||
    show_other_searches = False
 | 
			
		||||
| 
						 | 
				
			
			@ -258,6 +257,7 @@ class IndexView(
 | 
			
		|||
 | 
			
		||||
    @cached_property
 | 
			
		||||
    def columns(self):
 | 
			
		||||
        # If not explicitly overridden, derive from list_display
 | 
			
		||||
        columns = []
 | 
			
		||||
        for i, field in enumerate(self.list_display):
 | 
			
		||||
            if isinstance(field, Column):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -637,7 +637,6 @@ def select_task_type(request):
 | 
			
		|||
 | 
			
		||||
class CreateTask(CreateView):
 | 
			
		||||
    permission_policy = task_permission_policy
 | 
			
		||||
    model = None
 | 
			
		||||
    page_title = _("New workflow task")
 | 
			
		||||
    template_name = "wagtailadmin/workflows/create_task.html"
 | 
			
		||||
    success_message = _("Task '%(object)s' created.")
 | 
			
		||||
| 
						 | 
				
			
			@ -694,8 +693,6 @@ class CreateTask(CreateView):
 | 
			
		|||
 | 
			
		||||
class EditTask(EditView):
 | 
			
		||||
    permission_policy = task_permission_policy
 | 
			
		||||
    model = None
 | 
			
		||||
    page_title = _("Editing workflow task")
 | 
			
		||||
    template_name = "wagtailadmin/workflows/edit_task.html"
 | 
			
		||||
    success_message = _("Task '%(object)s' updated.")
 | 
			
		||||
    add_url_name = "wagtailadmin_workflows:select_task_type"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -305,10 +305,10 @@ class BaseAPIViewSet(GenericViewSet):
 | 
			
		|||
                child_endpoint_class = (
 | 
			
		||||
                    child_endpoint_class[1] if child_endpoint_class else BaseAPIViewSet
 | 
			
		||||
                )
 | 
			
		||||
                child_serializer_classes[
 | 
			
		||||
                    field_name
 | 
			
		||||
                ] = child_endpoint_class._get_serializer_class(
 | 
			
		||||
                    router, child_model, child_sub_fields, nested=True
 | 
			
		||||
                child_serializer_classes[field_name] = (
 | 
			
		||||
                    child_endpoint_class._get_serializer_class(
 | 
			
		||||
                        router, child_model, child_sub_fields, nested=True
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
            else:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,7 +9,7 @@ try:
 | 
			
		|||
    AUTH_USER_APP_LABEL, AUTH_USER_MODEL_NAME = AUTH_USER_MODEL.rsplit(".", 1)
 | 
			
		||||
except ValueError:
 | 
			
		||||
    raise ImproperlyConfigured(
 | 
			
		||||
        "AUTH_USER_MODEL must be of the form" " 'app_label.model_name'"
 | 
			
		||||
        "AUTH_USER_MODEL must be of the form 'app_label.model_name'"
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,6 +23,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		|||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
# Copied from: https://raw.githubusercontent.com/django-import-export/django-import-export/5795e114210adf250ac6e146db2fa413f38875de/import_export/tmp_storages.py
 | 
			
		||||
import os
 | 
			
		||||
import tempfile
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -654,8 +654,7 @@ class TestSearchPromotionsAddView(AdminTemplateTestUtils, WagtailTestUtils, Test
 | 
			
		|||
            response.context["searchpicks_formset"],
 | 
			
		||||
            0,
 | 
			
		||||
            "page",
 | 
			
		||||
            "Select a valid choice. "
 | 
			
		||||
            "That choice is not one of the available choices.",
 | 
			
		||||
            "Select a valid choice. That choice is not one of the available choices.",
 | 
			
		||||
        )
 | 
			
		||||
        # Should not raise an error anywhere else
 | 
			
		||||
        self.assertFormSetError(response.context["searchpicks_formset"], 0, None, [])
 | 
			
		||||
| 
						 | 
				
			
			@ -992,8 +991,7 @@ class TestSearchPromotionsEditView(AdminTemplateTestUtils, WagtailTestUtils, Tes
 | 
			
		|||
            response.context["searchpicks_formset"],
 | 
			
		||||
            1,
 | 
			
		||||
            "page",
 | 
			
		||||
            "Select a valid choice. "
 | 
			
		||||
            "That choice is not one of the available choices.",
 | 
			
		||||
            "Select a valid choice. That choice is not one of the available choices.",
 | 
			
		||||
        )
 | 
			
		||||
        # Should not raise an error anywhere else
 | 
			
		||||
        self.assertFormSetError(response.context["searchpicks_formset"], 0, None, [])
 | 
			
		||||
| 
						 | 
				
			
			@ -1560,7 +1558,8 @@ class TestQueryStringNormalisation(TestCase):
 | 
			
		|||
    def test_different_queries(self):
 | 
			
		||||
        queries = [
 | 
			
		||||
            "HelloWorld",
 | 
			
		||||
            "HelloWorld!" "  Hello  World!  ",
 | 
			
		||||
            "HelloWorld!",
 | 
			
		||||
            "  Hello  World  ",
 | 
			
		||||
            "Hello",
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
"""
 | 
			
		||||
Draftail / contentstate conversion
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
from draftjs_exporter.dom import DOM
 | 
			
		||||
 | 
			
		||||
from wagtail.admin.rich_text.converters.html_to_contentstate import LinkElementHandler
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
"""
 | 
			
		||||
editor-html conversion for contenteditable editors
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
from django.utils.html import escape
 | 
			
		||||
 | 
			
		||||
from wagtail.admin.rich_text.converters import editor_html
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -111,7 +111,7 @@ class TestCollectionPrivacyDocument(WagtailTestUtils, TestCase):
 | 
			
		|||
        WAGTAILDOCS_PASSWORD_REQUIRED_TEMPLATE="tests/custom_docs_password_required.html"
 | 
			
		||||
    )
 | 
			
		||||
    def test_anonymous_user_must_authenticate_with_custom_password_required_template(
 | 
			
		||||
        self
 | 
			
		||||
        self,
 | 
			
		||||
    ):
 | 
			
		||||
        secret_document = Document.objects.create(
 | 
			
		||||
            title="Test document",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,7 +7,6 @@ from wagtail.documents import models
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
class TestCorrectDownloadUrlSerialization(TestCase):
 | 
			
		||||
 | 
			
		||||
    """Test asserts that in case of both `redirect` and `direct`
 | 
			
		||||
    WAGTAILDOCS_SERVE_METHOD settings `download_url` field
 | 
			
		||||
    is correctly serialized by DocumentDownloadUrlField."""
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
"""
 | 
			
		||||
Draftail / contentstate conversion
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
from draftjs_exporter.dom import DOM
 | 
			
		||||
 | 
			
		||||
from wagtail.admin.rich_text.converters.contentstate_models import Entity
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
"""
 | 
			
		||||
editor-html conversion for contenteditable editors
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
from wagtail.admin.rich_text.converters import editor_html
 | 
			
		||||
from wagtail.embeds import format
 | 
			
		||||
from wagtail.embeds.exceptions import EmbedException
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,7 +16,7 @@ def progress_bar(current, total, bar_length=50):
 | 
			
		|||
 | 
			
		||||
    ending = "\n" if current == total else "\r"
 | 
			
		||||
 | 
			
		||||
    return (f"Progress: [{arrow}{padding}] {int(fraction*100)}%", ending)
 | 
			
		||||
    return (f"Progress: [{arrow}{padding}] {int(fraction * 100)}%", ending)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Command(BaseCommand):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -446,7 +446,7 @@ class TestImageIndexViewSearch(WagtailTestUtils, TransactionTestCase):
 | 
			
		|||
        answer_list = []
 | 
			
		||||
        for i in range(10):
 | 
			
		||||
            self.image = Image.objects.create(
 | 
			
		||||
                title=f"{title_list[i%2]} {i}",
 | 
			
		||||
                title=f"{title_list[i % 2]} {i}",
 | 
			
		||||
                file=get_test_image_file(size=(1, 1)),
 | 
			
		||||
                collection=child_collection[i % 2],
 | 
			
		||||
            )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -67,9 +67,9 @@ class BaseViewRestriction(models.Model):
 | 
			
		|||
        )
 | 
			
		||||
        if self.id not in passed_restrictions:
 | 
			
		||||
            passed_restrictions.append(self.id)
 | 
			
		||||
            request.session[
 | 
			
		||||
                self.passed_view_restrictions_session_key
 | 
			
		||||
            ] = passed_restrictions
 | 
			
		||||
            request.session[self.passed_view_restrictions_session_key] = (
 | 
			
		||||
                passed_restrictions
 | 
			
		||||
            )
 | 
			
		||||
        if not has_existing_session:
 | 
			
		||||
            # if this is a session we've created, set it to expire at the end
 | 
			
		||||
            # of the browser session
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1169,8 +1169,7 @@ class WorkflowMixin:
 | 
			
		|||
    def _check_draftstate_and_revision_mixins(cls):
 | 
			
		||||
        mro = cls.mro()
 | 
			
		||||
        error = checks.Error(
 | 
			
		||||
            "WorkflowMixin requires DraftStateMixin and RevisionMixin "
 | 
			
		||||
            "(in that order).",
 | 
			
		||||
            "WorkflowMixin requires DraftStateMixin and RevisionMixin (in that order).",
 | 
			
		||||
            hint=(
 | 
			
		||||
                "Make sure your model's inheritance order is as follows: "
 | 
			
		||||
                "WorkflowMixin, DraftStateMixin, RevisionMixin."
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -180,8 +180,8 @@ class TestParseQueryString(SimpleTestCase):
 | 
			
		|||
        self.assertEqual(filters.dict(), {"a" * 60_000: "foo bar"})
 | 
			
		||||
 | 
			
		||||
    def test_long_filter_value(self):
 | 
			
		||||
        filters, _ = parse_query_string(f'foo:ba{"r" * 60_000}')
 | 
			
		||||
        self.assertEqual(filters.dict(), {"foo": f'ba{"r" * 60_000}'})
 | 
			
		||||
        filters, _ = parse_query_string(f"foo:ba{'r' * 60_000}")
 | 
			
		||||
        self.assertEqual(filters.dict(), {"foo": f"ba{'r' * 60_000}"})
 | 
			
		||||
 | 
			
		||||
    def test_joined_filters(self):
 | 
			
		||||
        filters, query = parse_query_string("foo:bar:baz")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,5 @@
 | 
			
		|||
"""Handles rendering of the list of actions in the footer of the snippet create/edit views."""
 | 
			
		||||
 | 
			
		||||
from functools import lru_cache
 | 
			
		||||
from warnings import warn
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -354,12 +354,15 @@ class TestSnippetListView(WagtailTestUtils, TestCase):
 | 
			
		|||
            self.assertEqual(user, self.user)
 | 
			
		||||
            self.assertEqual(context, {})
 | 
			
		||||
 | 
			
		||||
        with hooks.register_temporarily(
 | 
			
		||||
            "construct_snippet_listing_buttons",
 | 
			
		||||
            register_snippet_listing_button_item,
 | 
			
		||||
        ), self.assertWarnsMessage(
 | 
			
		||||
            RemovedInWagtail70Warning,
 | 
			
		||||
            "construct_snippet_listing_buttons hook no longer accepts a context argument",
 | 
			
		||||
        with (
 | 
			
		||||
            hooks.register_temporarily(
 | 
			
		||||
                "construct_snippet_listing_buttons",
 | 
			
		||||
                register_snippet_listing_button_item,
 | 
			
		||||
            ),
 | 
			
		||||
            self.assertWarnsMessage(
 | 
			
		||||
                RemovedInWagtail70Warning,
 | 
			
		||||
                "construct_snippet_listing_buttons hook no longer accepts a context argument",
 | 
			
		||||
            ),
 | 
			
		||||
        ):
 | 
			
		||||
            response = self.get()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -536,8 +539,10 @@ class TestListViewOrdering(WagtailTestUtils, TestCase):
 | 
			
		|||
    @classmethod
 | 
			
		||||
    def setUpTestData(cls):
 | 
			
		||||
        for i in range(1, 10):
 | 
			
		||||
            advert = Advert.objects.create(text=f"{i*'a'}dvert {i}")
 | 
			
		||||
            draft = DraftStateModel.objects.create(text=f"{i*'d'}raft {i}", live=False)
 | 
			
		||||
            advert = Advert.objects.create(text=f"{i * 'a'}dvert {i}")
 | 
			
		||||
            draft = DraftStateModel.objects.create(
 | 
			
		||||
                text=f"{i * 'd'}raft {i}", live=False
 | 
			
		||||
            )
 | 
			
		||||
            if i % 2 == 0:
 | 
			
		||||
                ModelLogEntry.objects.create(
 | 
			
		||||
                    content_type=ContentType.objects.get_for_model(Advert),
 | 
			
		||||
| 
						 | 
				
			
			@ -1972,12 +1977,13 @@ class TestSnippetEditView(BaseTestSnippetEditView):
 | 
			
		|||
            return DeleteMenuItem(order=900)
 | 
			
		||||
 | 
			
		||||
        get_base_snippet_action_menu_items.cache_clear()
 | 
			
		||||
        with self.register_hook(
 | 
			
		||||
            "register_snippet_action_menu_item", hook_func
 | 
			
		||||
        ), self.assertWarnsMessage(
 | 
			
		||||
            RemovedInWagtail70Warning,
 | 
			
		||||
            "DeleteMenuItem is deprecated. "
 | 
			
		||||
            "The delete option is now provided via EditView.get_header_more_buttons().",
 | 
			
		||||
        with (
 | 
			
		||||
            self.register_hook("register_snippet_action_menu_item", hook_func),
 | 
			
		||||
            self.assertWarnsMessage(
 | 
			
		||||
                RemovedInWagtail70Warning,
 | 
			
		||||
                "DeleteMenuItem is deprecated. "
 | 
			
		||||
                "The delete option is now provided via EditView.get_header_more_buttons().",
 | 
			
		||||
            ),
 | 
			
		||||
        ):
 | 
			
		||||
            response = self.get()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1989,7 +1995,7 @@ class TestSnippetEditView(BaseTestSnippetEditView):
 | 
			
		|||
        )
 | 
			
		||||
        self.assertContains(
 | 
			
		||||
            response,
 | 
			
		||||
            f'<a class="button" href="{ delete_url }"><svg class="icon icon-bin icon" aria-hidden="true"><use href="#icon-bin"></use></svg>Delete</a>',
 | 
			
		||||
            f'<a class="button" href="{delete_url}"><svg class="icon icon-bin icon" aria-hidden="true"><use href="#icon-bin"></use></svg>Delete</a>',
 | 
			
		||||
            html=True,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,9 +76,9 @@ STORAGES = {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
if os.environ.get("STATICFILES_STORAGE", "") == "manifest":
 | 
			
		||||
    STORAGES["staticfiles"][
 | 
			
		||||
        "BACKEND"
 | 
			
		||||
    ] = "django.contrib.staticfiles.storage.ManifestStaticFilesStorage"
 | 
			
		||||
    STORAGES["staticfiles"]["BACKEND"] = (
 | 
			
		||||
        "django.contrib.staticfiles.storage.ManifestStaticFilesStorage"
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
USE_TZ = not os.environ.get("DISABLE_TIMEZONE")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@ page types, it can be difficult to construct this data structure by hand;
 | 
			
		|||
the ``wagtail.test.utils.form_data`` module provides a set of helper
 | 
			
		||||
functions to assist with this.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import bs4
 | 
			
		||||
from django.http import QueryDict
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -83,7 +83,7 @@ class TestPagePrivacy(WagtailTestUtils, TestCase):
 | 
			
		|||
        WAGTAIL_PASSWORD_REQUIRED_TEMPLATE="tests/custom_page_password_required.html"
 | 
			
		||||
    )
 | 
			
		||||
    def test_anonymous_user_must_authenticate_with_custom_password_required_template(
 | 
			
		||||
        self
 | 
			
		||||
        self,
 | 
			
		||||
    ):
 | 
			
		||||
        response = self.client.get("/secret-plans/")
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,7 +53,7 @@ class TestStringToAscii(TestCase):
 | 
			
		|||
    def test_string_to_ascii(self):
 | 
			
		||||
        test_cases = [
 | 
			
		||||
            ("30 \U0001d5c4\U0001d5c6/\U0001d5c1", "30 km/h"),
 | 
			
		||||
            ("\u5317\u4EB0", "BeiJing"),
 | 
			
		||||
            ("\u5317\u4eb0", "BeiJing"),
 | 
			
		||||
            ("ぁ あ ぃ い ぅ う ぇ", "a a i i u u e"),
 | 
			
		||||
            (
 | 
			
		||||
                "Ա Բ Գ Դ Ե Զ Է Ը Թ Ժ Ի Լ Խ Ծ Կ Հ Ձ Ղ Ճ Մ Յ Ն",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -110,9 +110,7 @@ class UserForm(UsernameForm):
 | 
			
		|||
    is_superuser = forms.BooleanField(
 | 
			
		||||
        label=_("Administrator"),
 | 
			
		||||
        required=False,
 | 
			
		||||
        help_text=_(
 | 
			
		||||
            "Administrators have full access to manage any object " "or setting."
 | 
			
		||||
        ),
 | 
			
		||||
        help_text=_("Administrators have full access to manage any object or setting."),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@
 | 
			
		|||
A generic HTML whitelisting engine, designed to accommodate subclassing to override
 | 
			
		||||
specific rules.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
from bs4 import BeautifulSoup, Comment, NavigableString, Tag
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue