Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions django/forms/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ def merge(*lists):
return list(dict.fromkeys(chain.from_iterable(filter(None, lists))))

def __add__(self, other):
if not isinstance(other, Media):
return NotImplemented
combined = Media()
combined._css_lists = self._css_lists[:]
combined._js_lists = self._js_lists[:]
Expand Down
2 changes: 1 addition & 1 deletion django/utils/html.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ def unquote_quote(segment):

class CountsDict(dict):
def __init__(self, *args, word, **kwargs):
super().__init__(*args, *kwargs)
super().__init__(*args, **kwargs)
self.word = word

def __missing__(self, key):
Expand Down
2 changes: 1 addition & 1 deletion docs/make.bat
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ if "%1" == "clean" (
)

if "%1" == "html" (
%SPHINXBUILD% -b djangohtml %ALLSPHINXOPTS% %BUILDDIR%/html
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
Expand Down
7 changes: 7 additions & 0 deletions tests/forms_tests/tests/test_media.py
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,13 @@ def test_add_empty(self):
self.assertEqual(merged._css_lists, [{"screen": ["a.css"]}])
self.assertEqual(merged._js_lists, [["a"]])

def test_add_invalid_type(self):
class InvalidType:
pass

with self.assertRaises(TypeError):
Media() + InvalidType()

def test_render_js_with_attrs(self):
media = Media(js=[Script("/path/to/js", integrity="sha256-abc")])
self.assertHTMLEqual(
Expand Down
41 changes: 25 additions & 16 deletions tests/signals/tests.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import contextvars
import gc
from inspect import markcoroutinefunction
from unittest import mock

Expand All @@ -14,26 +15,34 @@


class BaseSignalSetup:
def _signal_counts(self):
# Clear dead receivers before counting.
counts = []
for signal in (
signals.pre_save,
signals.post_save,
signals.pre_delete,
signals.post_delete,
):
with signal.lock:
signal._clear_dead_receivers()
counts.append(len(signal.receivers))
return tuple(counts)

def setUp(self):
# Save up the number of connected signals so that we can check at the
# end that all the signals we register get properly unregistered
# (#9989)
self.pre_signals = (
len(signals.pre_save.receivers),
len(signals.post_save.receivers),
len(signals.pre_delete.receivers),
len(signals.post_delete.receivers),
)
# The count comparison in tearDown() is a regression check for
# Signal.disconnect() failing to remove entries (#9989). Collect first
# so the baseline contains only reachable receivers; a receiver
# connected elsewhere in the suite and then garbage-collected could
# linger as a dead weakref, inflating the count (#29187). No collection
# in tearDown(): a weak receiver kept alive by a cycle should be
# counted, to catch a forgotten disconnect.
gc.collect()
self.pre_signals = self._signal_counts()

def tearDown(self):
# All our signals got disconnected properly.
post_signals = (
len(signals.pre_save.receivers),
len(signals.post_save.receivers),
len(signals.pre_delete.receivers),
len(signals.post_delete.receivers),
)
self.assertEqual(self.pre_signals, post_signals)
self.assertEqual(self.pre_signals, self._signal_counts())


class SignalTests(BaseSignalSetup, TestCase):
Expand Down
Loading