
On 4/5/22 8:25 PM, Erik De Bonte wrote:
dataclass_transform(field_descriptors=...) does not currently support string-based forward references to types, which it looks like Django will require.
What is it about Django's code that makes a forward reference required? Is there a circular reference?
Looks like I was able to do a direct import of Field after all, rather than using a forward reference. 👌 I suppose my instincts were worried about introducing an import because I try very hard to not introduce imports from low-level "utility" modules (like django.db.models.base) to other modules that might be higher level (like django.db.models.fields). Such imports often create circular reference problems, although apparently not in this case.
It would be useful to have syntax to describe what the "value type" of a particular field descriptor is, so that I don't have to use cast()s everywhere. See the above proposed syntax:
Dataclass solves this by having a field() function that returns their Field objects rather than having consumers use the Field type directly. The field() function returns Any but has overloads to return a more specific type when default or default_factory are provided.
Oof. I expect it would be a bigger ask to introduce a similar field() function in Django. Django users have been accustomed to directly assigning Field instances to attributes, being able to write: class Question(Model): question_text = CharField(max_length=200) It sounds like introducing that kind of field() function would require users to write instead: class Question(Model): question_text = field(CharField(max_length=200)) That could be a larger ask. Granted it would only apply to users of Django who opt-in to using a type checker. For my own reference, I expect a field() method would be implemented as something like: V = TypeVar("V") class Field(Generic[V]): ... # django.db.models.fields class CharField(Field[str]): ... # django.db.models.fields def field(field: Field[T]) -> T: return typing.cast(T, field) -- David Foster | Seattle, WA, USA Contributor to TypedDict, mypy, and Python's typing system