adding warnings for __isnull (#3033)#3174
adding warnings for __isnull (#3033)#3174DeXtAr47-oss wants to merge 8 commits intotypeddjango:masterfrom
Conversation
ngnpope
left a comment
There was a problem hiding this comment.
A few quick drive-by comments...
|
|
||
| try: | ||
| field, _ = django_context.resolve_lookup_into_field(model_cls, lookup) | ||
| except (LookupsAreUnsupported, Exception): |
There was a problem hiding this comment.
to skip for invalid fields or unsupported lookup chains instead of raising an error
There was a problem hiding this comment.
We should use more narrow exception types then, this catches too many things
| provided_type = get_proper_type(provided_type) | ||
|
|
||
| if lookup_kwarg.endswith("__isnull"): | ||
| is_true_literal = isinstance(provided_type, LiteralType) |
There was a problem hiding this comment.
This checks that it's a literal type, but not that it's True.
There was a problem hiding this comment.
thanks for pointing that out I would make the changes by checking the provided_type.value is True
| if lookup_kwarg.endswith("__isnull"): | ||
| is_true_literal = isinstance(provided_type, LiteralType) | ||
|
|
||
| if is_true_literal: | ||
| lookup = lookup_kwarg[:-8] | ||
|
|
||
| try: | ||
| field, _ = django_context.resolve_lookup_into_field(model_cls, lookup) | ||
| except (LookupsAreUnsupported, Exception): | ||
| field = None | ||
|
|
||
| if field is not None and not getattr(field, "null", False): | ||
| ctx.api.fail( | ||
| f'Filed "{field.name}" does not allow NULL;' | ||
| f'using "__isnull=True" will always return an empty queryset.', | ||
| ctx.context, | ||
| ) |
There was a problem hiding this comment.
Instead of the fragility of slicing 8 characters from the end of the string, this could be made more legible, e.g.
lookup_path, sep, lookup_name = lookup_kwarg.rpartition(LOOKUP_SEP)
is_true_literal = isinstance(provided_type, LiteralType) and provided_type.value is True
if lookup_name == "isnull" and is_true_literal:
try:
field, _ = django_context.resolve_lookup_into_field(model_cls, lookup_path)
except LookupsAreUnsupported:
pass
else:
if field is not None and field.null is False:
ctx.api.fail(
f'Field "{field.name}" does not allow NULL;'
f'using "__isnull=True" will always return an empty queryset.',
ctx.context,
)LOOKUP_SEP can be imported via from django.db.models.constants import LOOKUP_SEP.
There was a problem hiding this comment.
ok sure I will do that
|
@DeXtAr47-oss Thanks for the work on this! |
This PR adds the feature to generate warnings while incorrectly using __isnull feature,
__isnullLiteral[True]__isnullsuffix to obtain the field lookup path.django_context.resolve_lookup_into_field.Field.nullattribute.null=False, emit a mypy error.Related issues
__isnullfilters #3033