[python] dataclass_transform: use the annotated class as a resolve anchor for resolving the field specifiers

(cherry picked from commit f15a07836e7aeac7c46b489b4742e8248a0e6ef4)

GitOrigin-RevId: edf8399741cc5d62ba2fb04f9314eb620f83abae
This commit is contained in:
Daniil Kalinin
2024-10-16 14:28:41 +02:00
committed by intellij-monorepo-bot
parent 24d6509dcd
commit 0cb148129f
3 changed files with 15 additions and 2 deletions

View File

@@ -566,7 +566,7 @@ private fun resolveDataclassParameters(
if (dataclassTransformStub != null) {
val resolvedFieldSpecifiers = dataclassTransformStub.fieldSpecifiers
.flatMap { PyResolveUtil.resolveQualifiedNameInScope(it, ScopeUtil.getScopeOwner(dataclassTransformDecorator)!!, context) }
.flatMap { PyResolveUtil.resolveQualifiedNameInScope(it, ScopeUtil.getScopeOwner(pyClass)!!, context) }
.filterIsInstance<PyQualifiedNameOwner>()
.mapNotNull { it.qualifiedName }
.map { QualifiedName.fromDottedString(it) }

View File

@@ -1,8 +1,9 @@
import dataclasses
from typing import ClassVar
from decorator import my_dataclass, my_field, MyField
from decorator import my_dataclass, my_field, MyField, registry
reg = registry()
@my_dataclass()
class A1:
@@ -106,3 +107,9 @@ class D1:
class E1:
foo = "bar" # <- has no type annotation, so doesn't count.
baz: str
# see https://docs.sqlalchemy.org/en/20/orm/dataclasses.html
@reg.mapped_as_dataclass
class B5:
<error descr="Fields with a default value must come after any fields without a default.">a</error>: int = MyField(default_factory=int)
b: int = MyField()

View File

@@ -11,6 +11,12 @@ class MyField:
def __init__(self, **kwargs):
...
class registry:
@dataclass_transform(field_specifiers=(my_field, MyField,))
def mapped_as_dataclass(**kwargs) -> Callable[[type[T]], type[T]]:
...
@dataclass_transform(field_specifiers=(my_field, MyField,))
def my_dataclass(**kwargs) -> Callable[[type[T]], type[T]]: