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
4 changes: 2 additions & 2 deletions mypy_django_plugin/transformers/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,11 @@ def set_descriptor_types_for_field(
if not (isinstance(mapped_set_type, UninhabitedType) or isinstance(mapped_get_type, UninhabitedType)):
# always replace set_type and get_type with (non-Any) mapped types
set_type = helpers.convert_any_to_type(mapped_set_type, set_type)
get_type = helpers.convert_any_to_type(mapped_get_type, get_type)
get_type = get_proper_type(helpers.convert_any_to_type(mapped_get_type, get_type))

# the get_type must be optional if the field is nullable
if (is_get_nullable or is_nullable) and not (
isinstance(get_proper_type(get_type), NoneType) or helpers.is_optional(get_type)
isinstance(get_type, NoneType) or helpers.is_optional(get_type) or isinstance(get_type, AnyType)
):
ctx.api.fail(
f"{default_return_type.type.name} is nullable but its generic get type parameter is not optional",
Expand Down
30 changes: 19 additions & 11 deletions tests/typecheck/fields/test_custom_fields.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@
reveal_type(user.my_custom_field13) # N: Revealed type is "Union[myapp.models.CustomFieldValue, None]"
reveal_type(user.my_custom_field14) # N: Revealed type is "Union[builtins.bool, None]"
reveal_type(user.my_custom_field15) # N: Revealed type is "None"

reveal_type(user.my_custom_field_any1) # N: Revealed type is "Any"
reveal_type(user.my_custom_field_any2) # N: Revealed type is "Any"
reveal_type(user.my_custom_field_any3) # N: Revealed type is "Any"
reveal_type(user.my_custom_field_any4) # N: Revealed type is "Any"
monkeypatch: true
out: |
myapp/models:31: error: GenericField is nullable but its generic get type parameter is not optional [misc]
myapp/models:32: error: CustomValueField is nullable but its generic get type parameter is not optional [misc]
myapp/models:33: error: SingleTypeField is nullable but its generic get type parameter is not optional [misc]
myapp/models:34: error: AdditionalTypeVarField is nullable but its generic get type parameter is not optional [misc]
myapp/models:35: error: Field is nullable but its generic get type parameter is not optional [misc]
installed_apps:
- myapp
files:
Expand Down Expand Up @@ -53,19 +52,24 @@

class CustomSmallIntegerField(fields.SmallIntegerField[_ST, _GT]): ...

class FieldImplicitAny(fields.Field): ...
class FieldExplicitAny(fields.Field[Any, Any]): ...

class User(models.Model):
id = models.AutoField(primary_key=True)
my_custom_field1 = GenericField[Union[CustomFieldValue, int], CustomFieldValue]()
my_custom_field2 = CustomValueField()
my_custom_field3 = SingleTypeField[bool]()
my_custom_field4 = AdditionalTypeVarField[Union[CustomFieldValue, int], CustomFieldValue, bool]()
my_custom_field_any1 = FieldImplicitAny()
my_custom_field_any2 = FieldExplicitAny()

# test null=True on fields with non-optional generic types throw error
my_custom_field5 = GenericField[Union[CustomFieldValue, int], CustomFieldValue](null=True)
my_custom_field6 = CustomValueField(null=True)
my_custom_field7 = SingleTypeField[bool](null=True)
my_custom_field8 = AdditionalTypeVarField[Union[CustomFieldValue, int], CustomFieldValue, bool](null=True)
my_custom_field9 = fields.Field[Union[CustomFieldValue, int], CustomFieldValue](null=True)
my_custom_field5 = GenericField[Union[CustomFieldValue, int], CustomFieldValue](null=True) # E: GenericField is nullable but its generic get type parameter is not optional [misc]
my_custom_field6 = CustomValueField(null=True) # E: CustomValueField is nullable but its generic get type parameter is not optional [misc]
my_custom_field7 = SingleTypeField[bool](null=True) # E: SingleTypeField is nullable but its generic get type parameter is not optional [misc]
my_custom_field8 = AdditionalTypeVarField[Union[CustomFieldValue, int], CustomFieldValue, bool](null=True) # E: AdditionalTypeVarField is nullable but its generic get type parameter is not optional [misc]
my_custom_field9 = fields.Field[Union[CustomFieldValue, int], CustomFieldValue](null=True) # E: Field is nullable but its generic get type parameter is not optional [misc]

# test overriding fields that set _pyi_private_set_type or _pyi_private_get_type
my_custom_field10 = fields.SmallIntegerField[bool, bool]()
Expand All @@ -76,3 +80,7 @@
my_custom_field13 = GenericField[Union[CustomFieldValue, int], Union[CustomFieldValue, None]](null=True)
my_custom_field14 = SingleTypeField[Union[bool, None]](null=True)
my_custom_field15 = fields.Field[None, None](null=True)

# test null=True on Any does not raise
my_custom_field_any3 = FieldImplicitAny(null=True)
my_custom_field_any4 = FieldExplicitAny(null=True)
Loading