From 7819165e429183bc7912e874937814c535dd7923 Mon Sep 17 00:00:00 2001 From: Aleksander Vognild Burkow Date: Mon, 4 Feb 2019 16:51:56 +0100 Subject: [PATCH 1/5] Add decimal field typings --- django-stubs/db/models/fields/__init__.pyi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/django-stubs/db/models/fields/__init__.pyi b/django-stubs/db/models/fields/__init__.pyi index 62c594f..758c570 100644 --- a/django-stubs/db/models/fields/__init__.pyi +++ b/django-stubs/db/models/fields/__init__.pyi @@ -1,4 +1,5 @@ from typing import Any, Optional, Tuple, Iterable, Callable, Dict, Union, Type +import decimal from django.db.models import Model from django.db.models.query_utils import RegisterLookupMixin @@ -66,7 +67,7 @@ class SmallIntegerField(IntegerField): ... class BigIntegerField(IntegerField): ... class FloatField(Field): ... -class DecimalField(IntegerField): +class DecimalField(Field): def __init__( self, verbose_name: Optional[str] = ..., @@ -89,6 +90,7 @@ class DecimalField(IntegerField): validators: Iterable[_ValidatorCallable] = ..., error_messages: Optional[_ErrorMessagesToOverride] = ..., ): ... + def __get__(self, instance, owner) -> decimal.Decimal: ... class AutoField(Field): def __get__(self, instance, owner) -> int: ... From 08bf5660bf2818d86e1af0acda52709464469c7c Mon Sep 17 00:00:00 2001 From: Aleksander Vognild Burkow Date: Mon, 4 Feb 2019 16:48:47 +0100 Subject: [PATCH 2/5] Add additional django field __get__ types These are taken from the corresponding django/contrib/postgres/fields/ranges.py file. --- .../contrib/postgres/fields/ranges.pyi | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/django-stubs/contrib/postgres/fields/ranges.pyi b/django-stubs/contrib/postgres/fields/ranges.pyi index caf923b..b4af716 100644 --- a/django-stubs/contrib/postgres/fields/ranges.pyi +++ b/django-stubs/contrib/postgres/fields/ranges.pyi @@ -2,6 +2,8 @@ from typing import Any from django.db import models +from psycopg2.extras import DateRange, DateTimeTZRange, NumericRange + class RangeField(models.Field): empty_strings_allowed: bool = ... base_field: Any = ... @@ -10,8 +12,17 @@ class RangeField(models.Field): def to_python(self, value: Any): ... def value_to_string(self, obj: Any): ... -class IntegerRangeField(RangeField): ... -class BigIntegerRangeField(RangeField): ... -class FloatRangeField(RangeField): ... -class DateTimeRangeField(RangeField): ... -class DateRangeField(RangeField): ... +class IntegerRangeField(RangeField): + def __get__(self, instance, owner) -> NumericRange: ... + +class BigIntegerRangeField(RangeField): + def __get__(self, instance, owner) -> NumericRange: ... + +class FloatRangeField(RangeField): + def __get__(self, instance, owner) -> NumericRange: ... + +class DateTimeRangeField(RangeField): + def __get__(self, instance, owner) -> DateTimeTZRange: ... + +class DateRangeField(RangeField): + def __get__(self, instance, owner) -> DateRange: ... From 6c87ccf2281f6a1b2d26500347bb059af3528016 Mon Sep 17 00:00:00 2001 From: Aleksander Vognild Burkow Date: Mon, 4 Feb 2019 17:02:23 +0100 Subject: [PATCH 3/5] Add tests for the new fields --- test-data/typecheck/fields.test | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test-data/typecheck/fields.test b/test-data/typecheck/fields.test index 96c0e9b..46977d7 100644 --- a/test-data/typecheck/fields.test +++ b/test-data/typecheck/fields.test @@ -37,6 +37,22 @@ reveal_type(user.name) # E: Revealed type is 'builtins.str' reveal_type(user.slug) # E: Revealed type is 'builtins.str' reveal_type(user.text) # E: Revealed type is 'builtins.str' +[CASE test_model_field_classes_from_exciting_locations] +from django.db import models +from django.contrib.postgres import fields as pg_fields +from psycopg2.extras import DateTimeTZRange +from decimal import Decimal + +class Booking(models.Model): + id = models.AutoField(primary_key=True) + time_range = pg_fields.DateTimeRangeField(null=False) + some_decimal = models.DecimalField(max_digits=10, decimal_places=5) + +booking = Booking() +reveal_type(booking.id) # E: Revealed type is 'builtins.int' +reveal_type(booking.time_range) # E: Revealed type is 'DateTimeTZRange' +reveal_type(booking.some_decimal) # E: Revealed type is 'Decimal' + [CASE test_add_id_field_if_no_primary_key_defined] from django.db import models From 4ea4c3eddd7a88212ada49351cd869162d3e3736 Mon Sep 17 00:00:00 2001 From: Aleksander Vognild Burkow Date: Tue, 5 Feb 2019 14:23:06 +0100 Subject: [PATCH 4/5] Ignore external psycopg2 types --- django-stubs/contrib/postgres/fields/ranges.pyi | 2 +- test-data/typecheck/fields.test | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/django-stubs/contrib/postgres/fields/ranges.pyi b/django-stubs/contrib/postgres/fields/ranges.pyi index b4af716..2a26f7c 100644 --- a/django-stubs/contrib/postgres/fields/ranges.pyi +++ b/django-stubs/contrib/postgres/fields/ranges.pyi @@ -2,7 +2,7 @@ from typing import Any from django.db import models -from psycopg2.extras import DateRange, DateTimeTZRange, NumericRange +from psycopg2.extras import DateRange, DateTimeTZRange, NumericRange # type: ignore class RangeField(models.Field): empty_strings_allowed: bool = ... diff --git a/test-data/typecheck/fields.test b/test-data/typecheck/fields.test index 46977d7..60f482e 100644 --- a/test-data/typecheck/fields.test +++ b/test-data/typecheck/fields.test @@ -40,7 +40,6 @@ reveal_type(user.text) # E: Revealed type is 'builtins.str' [CASE test_model_field_classes_from_exciting_locations] from django.db import models from django.contrib.postgres import fields as pg_fields -from psycopg2.extras import DateTimeTZRange from decimal import Decimal class Booking(models.Model): @@ -50,7 +49,7 @@ class Booking(models.Model): booking = Booking() reveal_type(booking.id) # E: Revealed type is 'builtins.int' -reveal_type(booking.time_range) # E: Revealed type is 'DateTimeTZRange' +reveal_type(booking.time_range) # E: Revealed type is 'Any' reveal_type(booking.some_decimal) # E: Revealed type is 'Decimal' [CASE test_add_id_field_if_no_primary_key_defined] From a9c1f35494670eca45ca30c3577854975ed1599f Mon Sep 17 00:00:00 2001 From: Aleksander Vognild Burkow Date: Tue, 5 Feb 2019 14:30:23 +0100 Subject: [PATCH 5/5] Update decimal reveal_type test --- test-data/typecheck/fields.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-data/typecheck/fields.test b/test-data/typecheck/fields.test index 60f482e..047677b 100644 --- a/test-data/typecheck/fields.test +++ b/test-data/typecheck/fields.test @@ -50,7 +50,7 @@ class Booking(models.Model): booking = Booking() reveal_type(booking.id) # E: Revealed type is 'builtins.int' reveal_type(booking.time_range) # E: Revealed type is 'Any' -reveal_type(booking.some_decimal) # E: Revealed type is 'Decimal' +reveal_type(booking.some_decimal) # E: Revealed type is 'decimal.Decimal' [CASE test_add_id_field_if_no_primary_key_defined] from django.db import models