mirror of
https://github.com/davidhalter/django-stubs.git
synced 2025-12-07 20:54:29 +08:00
Make CharField(blank=True) not be considered nullable (#39)
* Make CharField(blank=True) not be considered nullable The documentation on [blank](https://docs.djangoproject.com/en/2.1/ref/models/fields/#blank) says that it "will allow the entry of an empty value", which for a string is just a 0-length string. This patch allows `CharField(blank=True,...)` to no longer be considered `Optional`. closes #38 * fixed tests for `CharField(blank=True)` * allow blank CharField to be nullable in the constructor, but the underlying type is str (unless `null=True`)
This commit is contained in:
committed by
Maxim Kurnikov
parent
627daa55f5
commit
f7dfbefbd6
@@ -101,10 +101,6 @@ def get_private_descriptor_type(type_info: TypeInfo, private_field_name: str, is
|
|||||||
def set_descriptor_types_for_field(ctx: FunctionContext) -> Instance:
|
def set_descriptor_types_for_field(ctx: FunctionContext) -> Instance:
|
||||||
default_return_type = cast(Instance, ctx.default_return_type)
|
default_return_type = cast(Instance, ctx.default_return_type)
|
||||||
is_nullable = helpers.parse_bool(helpers.get_argument_by_name(ctx, 'null'))
|
is_nullable = helpers.parse_bool(helpers.get_argument_by_name(ctx, 'null'))
|
||||||
if not is_nullable and default_return_type.type.has_base(helpers.CHAR_FIELD_FULLNAME):
|
|
||||||
# blank=True for CharField can be interpreted as null=True
|
|
||||||
is_nullable = helpers.parse_bool(helpers.get_argument_by_name(ctx, 'blank'))
|
|
||||||
|
|
||||||
set_type = get_private_descriptor_type(default_return_type.type, '_pyi_private_set_type',
|
set_type = get_private_descriptor_type(default_return_type.type, '_pyi_private_set_type',
|
||||||
is_nullable=is_nullable)
|
is_nullable=is_nullable)
|
||||||
get_type = get_private_descriptor_type(default_return_type.type, '_pyi_private_get_type',
|
get_type = get_private_descriptor_type(default_return_type.type, '_pyi_private_get_type',
|
||||||
|
|||||||
@@ -183,6 +183,13 @@ def extract_expected_types(ctx: FunctionContext, model: TypeInfo,
|
|||||||
False):
|
False):
|
||||||
field_type = helpers.make_optional(field_type)
|
field_type = helpers.make_optional(field_type)
|
||||||
|
|
||||||
|
# if CharField(blank=True,...) and not nullable, then field can be None in __init__
|
||||||
|
elif (
|
||||||
|
helpers.has_any_of_bases(typ.type, (helpers.CHAR_FIELD_FULLNAME,)) and is_init and
|
||||||
|
field_metadata.get('blank', False) and not field_metadata.get('null', False)
|
||||||
|
):
|
||||||
|
field_type = helpers.make_optional(field_type)
|
||||||
|
|
||||||
expected_types[name] = field_type
|
expected_types[name] = field_type
|
||||||
|
|
||||||
return expected_types
|
return expected_types
|
||||||
|
|||||||
@@ -110,9 +110,22 @@ class MyModel(ParentModel):
|
|||||||
reveal_type(MyModel().id) # E: Revealed type is 'uuid.UUID*'
|
reveal_type(MyModel().id) # E: Revealed type is 'uuid.UUID*'
|
||||||
[/CASE]
|
[/CASE]
|
||||||
|
|
||||||
[CASE blank_for_charfield_is_the_same_as_null]
|
[CASE blank_and_null_char_field_allows_none]
|
||||||
from django.db import models
|
from django.db import models
|
||||||
class MyModel(models.Model):
|
class MyModel(models.Model):
|
||||||
text = models.CharField(max_length=30, blank=True)
|
nulltext=models.CharField(max_length=1, blank=True, null=True)
|
||||||
MyModel(text=None)
|
MyModel(nulltext="")
|
||||||
|
MyModel(nulltext=None)
|
||||||
|
MyModel().nulltext=None
|
||||||
|
reveal_type(MyModel().nulltext) # E: Revealed type is 'Union[builtins.str, None]'
|
||||||
|
[/CASE]
|
||||||
|
|
||||||
|
[CASE blank_and_not_null_charfield_does_not_allow_none]
|
||||||
|
from django.db import models
|
||||||
|
class MyModel(models.Model):
|
||||||
|
notnulltext=models.CharField(max_length=1, blank=True, null=False)
|
||||||
|
MyModel(notnulltext=None) # Should allow None in constructor
|
||||||
|
MyModel(notnulltext="")
|
||||||
|
MyModel().notnulltext = None # E: Incompatible types in assignment (expression has type "None", variable has type "Union[str, int, Combinable]")
|
||||||
|
reveal_type(MyModel().notnulltext) # E: Revealed type is 'builtins.str*'
|
||||||
[/CASE]
|
[/CASE]
|
||||||
|
|||||||
Reference in New Issue
Block a user