Skip to content

Commit 159a0e4

Browse files
committed
Adds docs for how Field access works
1 parent eb70238 commit 159a0e4

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

django-stubs/db/models/fields/__init__.pyi

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,64 @@ _ST = TypeVar("_ST", contravariant=True)
4343
_GT = TypeVar("_GT", covariant=True)
4444

4545
class Field(RegisterLookupMixin, Generic[_ST, _GT]):
46+
"""
47+
Typing model fields.
48+
49+
How does this work?
50+
Let's take a look at the self-contained example
51+
(it is way easier than our django implementation, but has the same concept).
52+
53+
To understand this example you need:
54+
1. Be familiar with descriptors: https://docs.python.org/3/howto/descriptor.html
55+
2. Follow our explanation bellow
56+
57+
Let's start with defining our fake model class and fake integer field.
58+
59+
.. code:: python
60+
61+
from typing import Generic, Union
62+
63+
class Model(object):
64+
...
65+
66+
_SetType = Union[int, float] # You can assign ints and floats
67+
_GetType = int # access type is always `int`
68+
69+
class IntField(object):
70+
def __get__(self, instance: Model, owner) -> _GetType:
71+
...
72+
73+
def __set__(self, instance, value: _SetType) -> None:
74+
...
75+
76+
Now, let's create our own example model,
77+
this would be something like ``User`` in your own apps:
78+
79+
.. code:: python
80+
81+
class Example(Model):
82+
count = IntField()
83+
84+
And now, lets test that our reveal type works:
85+
86+
.. code:: python
87+
88+
example = Example()
89+
reveal_type(example.count)
90+
# Revealed type is "builtins.int"
91+
92+
example.count = 1.5 # ok
93+
example.count = 'a'
94+
# Incompatible types in assignment
95+
# (expression has type "str", variable has type "Union[int, float]")
96+
97+
Notice, that this is not magic. This is how descriptors work with ``mypy``.
98+
99+
We also need ``_pyi_private_set_type`` attributes
100+
and friends to help inside our plugin.
101+
It is required to enhance parts like ``filter`` queries.
102+
"""
103+
46104
_pyi_private_set_type: Any
47105
_pyi_private_get_type: Any
48106
_pyi_lookup_exact_type: Any

0 commit comments

Comments
 (0)