From 707b32bf407c8a1b3f017394f06ce74a01f7b7a9 Mon Sep 17 00:00:00 2001
From: Noam Kushinsky <noam.kushinsky@homelend.com>
Date: Wed, 29 May 2024 14:34:45 +0300
Subject: [PATCH] cherry-pick upstream pr #2195

---
 django-stubs/db/models/functions/comparison.pyi | 5 +++--
 django-stubs/db/models/functions/datetime.pyi   | 8 ++++----
 django-stubs/db/models/functions/math.pyi       | 9 +++++++--
 django-stubs/db/models/functions/text.pyi       | 8 ++++----
 scripts/stubtest/allowlist_todo.txt             | 2 --
 5 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/django-stubs/db/models/functions/comparison.pyi b/django-stubs/db/models/functions/comparison.pyi
index 50590a9dc..0d204cb22 100644
--- a/django-stubs/db/models/functions/comparison.pyi
+++ b/django-stubs/db/models/functions/comparison.pyi
@@ -1,16 +1,17 @@
 from typing import Any, ClassVar
 
 from django.db.models import Func
+from django.db.models.expressions import Combinable
 from django.db.models.fields import Field
 from django.db.models.fields.json import JSONField
 
 class Cast(Func):
-    def __init__(self, expression: Any, output_field: str | Field) -> None: ...
+    def __init__(self, expression: Combinable | str, output_field: str | Field) -> None: ...
 
 class Coalesce(Func): ...
 
 class Collate(Func):
-    def __init__(self, expression: Any, collation: str) -> None: ...
+    def __init__(self, expression: Combinable | str, collation: str) -> None: ...
 
 class Greatest(Func): ...
 
diff --git a/django-stubs/db/models/functions/datetime.pyi b/django-stubs/db/models/functions/datetime.pyi
index ea013ef5c..fde368f62 100644
--- a/django-stubs/db/models/functions/datetime.pyi
+++ b/django-stubs/db/models/functions/datetime.pyi
@@ -4,7 +4,7 @@ from typing import Any, ClassVar
 from django.db import models
 from django.db.backends.base.base import BaseDatabaseWrapper
 from django.db.models import Func, Transform
-from django.db.models.expressions import Expression
+from django.db.models.expressions import Combinable
 from django.db.models.fields import Field
 from django.db.models.sql.compiler import SQLCompiler, _AsSqlType
 
@@ -16,7 +16,7 @@ class Extract(TimezoneMixin, Transform):
     lookup_name: str
     output_field: ClassVar[models.IntegerField]
     def __init__(
-        self, expression: Any, lookup_name: str | None = ..., tzinfo: Any | None = ..., **extra: Any
+        self, expression: Combinable | str, lookup_name: str | None = ..., tzinfo: Any | None = ..., **extra: Any
     ) -> None: ...
 
 class ExtractYear(Extract): ...
@@ -41,14 +41,14 @@ class TruncBase(TimezoneMixin, Transform):
     tzinfo: Any
 
     def __init__(
-        self, expression: Expression, output_field: Field | None = ..., tzinfo: tzinfo | None = ..., **extra: Any
+        self, expression: Combinable | str, output_field: Field | None = ..., tzinfo: tzinfo | None = ..., **extra: Any
     ) -> None: ...
     def as_sql(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper) -> _AsSqlType: ...  # type: ignore[override]
 
 class Trunc(TruncBase):
     def __init__(
         self,
-        expression: Expression,
+        expression: Combinable | str,
         kind: str,
         output_field: Field | None = ...,
         tzinfo: tzinfo | None = ...,
diff --git a/django-stubs/db/models/functions/math.pyi b/django-stubs/db/models/functions/math.pyi
index 36adeb0d4..97f08307c 100644
--- a/django-stubs/db/models/functions/math.pyi
+++ b/django-stubs/db/models/functions/math.pyi
@@ -1,4 +1,6 @@
-from django.db.models.expressions import Func
+from typing import Any
+
+from django.db.models.expressions import Combinable, Func
 from django.db.models.functions.mixins import FixDecimalInputMixin, NumericOutputFieldMixin
 from django.db.models.lookups import Transform
 
@@ -19,7 +21,10 @@ class Mod(FixDecimalInputMixin, NumericOutputFieldMixin, Func): ...
 class Pi(NumericOutputFieldMixin, Func): ...
 class Power(NumericOutputFieldMixin, Func): ...
 class Radians(NumericOutputFieldMixin, Transform): ...
-class Round(Transform): ...
+
+class Round(Transform):
+    def __init__(self, expression: Combinable | str, precision: int = ..., **extra: Any) -> None: ...
+
 class Sin(NumericOutputFieldMixin, Transform): ...
 class Sqrt(NumericOutputFieldMixin, Transform): ...
 class Tan(NumericOutputFieldMixin, Transform): ...
diff --git a/django-stubs/db/models/functions/text.pyi b/django-stubs/db/models/functions/text.pyi
index 9800ec497..78d6093e6 100644
--- a/django-stubs/db/models/functions/text.pyi
+++ b/django-stubs/db/models/functions/text.pyi
@@ -32,7 +32,7 @@ class Concat(Func):
 
 class Left(Func):
     output_field: ClassVar[models.CharField]
-    def __init__(self, expression: Expression | str, length: Expression | int, **extra: Any) -> None: ...
+    def __init__(self, expression: Combinable | str, length: Expression | int, **extra: Any) -> None: ...
     def get_substr(self) -> Substr: ...
     def as_oracle(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ...
     def as_sqlite(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ...
@@ -46,7 +46,7 @@ class Lower(Transform): ...
 class LPad(Func):
     output_field: ClassVar[models.CharField]
     def __init__(
-        self, expression: Expression | str, length: Expression | int | None, fill_text: Expression = ..., **extra: Any
+        self, expression: Combinable | str, length: Expression | int | None, fill_text: Expression = ..., **extra: Any
     ) -> None: ...
 
 class LTrim(Transform): ...
@@ -59,7 +59,7 @@ class Ord(Transform):
 
 class Repeat(Func):
     output_field: ClassVar[models.CharField]
-    def __init__(self, expression: Expression | str, number: Expression | int | None, **extra: Any) -> None: ...
+    def __init__(self, expression: Combinable | str, number: Expression | int | None, **extra: Any) -> None: ...
     def as_oracle(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ...
 
 class Replace(Func):
@@ -91,7 +91,7 @@ class StrIndex(Func):
 class Substr(Func):
     output_field: ClassVar[models.CharField]
     def __init__(
-        self, expression: Expression | str, pos: Expression | int, length: Expression | int | None = ..., **extra: Any
+        self, expression: Combinable | str, pos: Expression | int, length: Expression | int | None = ..., **extra: Any
     ) -> None: ...
     def as_sqlite(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ...
     def as_oracle(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ...
diff --git a/scripts/stubtest/allowlist_todo.txt b/scripts/stubtest/allowlist_todo.txt
index 0b64ba25b..4f0723427 100644
--- a/scripts/stubtest/allowlist_todo.txt
+++ b/scripts/stubtest/allowlist_todo.txt
@@ -1060,7 +1060,6 @@ django.db.models.functions.NullIf.as_oracle
 django.db.models.functions.Pi.as_oracle
 django.db.models.functions.Radians.as_oracle
 django.db.models.functions.Random
-django.db.models.functions.Round.__init__
 django.db.models.functions.comparison.Cast.as_mysql
 django.db.models.functions.comparison.Cast.as_oracle
 django.db.models.functions.comparison.Cast.as_postgresql
@@ -1084,7 +1083,6 @@ django.db.models.functions.math.Degrees.as_oracle
 django.db.models.functions.math.Pi.as_oracle
 django.db.models.functions.math.Radians.as_oracle
 django.db.models.functions.math.Random
-django.db.models.functions.math.Round.__init__
 django.db.models.functions.mixins.FixDecimalInputMixin.as_postgresql
 django.db.models.functions.mixins.FixDurationInputMixin.as_mysql
 django.db.models.functions.mixins.FixDurationInputMixin.as_oracle