In Python 3.9.5+ urllib.parse() automatically removes ASCII newlines
and tabs from URLs [1, 2]. Unfortunately it created an issue in
the URLValidator. URLValidator uses urllib.urlsplit() and
urllib.urlunsplit() for creating a URL variant with Punycode which no
longer contains newlines and tabs in Python 3.9.5+. As a consequence,
the regular expression matched the URL (without unsafe characters) and
the source value (with unsafe characters) was considered valid.
[1] https://bugs.python.org/issue43882 and
[2] 76cd81d603
The validate_file_name() sanitation introduced in
0b79eb3691 correctly rejects the example
file name as containing path elements on Windows. This breaks the test
introduced in 914c72be2a to allow path
components for storages that may allow them.
Test is skipped pending a discussed storage refactoring to support this
use-case.
Having lookups group by subquery right-hand-sides is likely unnecessary
in the first place but relatively large amount of work would be needed
to achieve that such as making Lookup instances proper resolvable
expressions.
Regression in 3543129822.
Thanks James A. Munsch for the report.
In Query.join() the argument reuse_with_filtered_relation was used to
determine whether to use == or .equals(). As this area of code is
related to aliases, we only expect an instance of Join or BaseTable to
be provided - the only two classes that provide .equals().
In both cases, the implementations of __eq__() and equals() are based
on use of the "identity" property. __eq__() performs an isinstance()
check first, returning NotImplemented if required. BaseTable.equals()
then does a straightforward equality check on "identity". Join.equals()
is a little bit different as it skips checking the last element of the
"identity" property: filtered_relation. This was only included
previously when the with_filtered_relation argument was True, impossible
since bbf141bcdc.
Subquery deconstruction support required implementing complex and
expensive equality rules for sql.Query objects for little benefit as
the latter cannot themselves be made deconstructible to their reference
to model classes.
Making Expression @deconstructible and not BaseExpression allows
interested parties to conform to the "expression" API even if they are
not deconstructible as it's only a requirement for expressions allowed
in Model fields and meta options (e.g. constraints, indexes).
Thanks Phillip Cutter for the report.
This also fixes a performance regression in bbf141bcdc.
Thanks Zain Patel for the report and Simon Charette for reviews.
The exception introduced in 6307c3f1a1
revealed a possible data loss issue in the admin.
Regression in 3a505c70e7.
Nonlitteral right-hand-sides of lookups need to be wrapped in
parentheses to avoid operator precedence ambiguities.
Thanks Charles Lirsac for the detailed report.