1111)
1212
1313from typemap .type_eval import eval_typing
14- from typemap .typing import (
15- NewProtocol ,
16- Iter ,
17- Attrs ,
18- IsSub ,
19- FromUnion ,
20- GetArg ,
21- GetMemberType ,
22- GetType ,
23- GetName ,
24- GetQuals ,
25- GetInit ,
26- InitField ,
27- Member ,
28- Members ,
29- Param ,
30- )
14+ from typemap import typing
3115
3216from . import format_helper
3317
@@ -39,15 +23,15 @@ class FieldArgs(TypedDict, total=False):
3923 default : ReadOnly [object ]
4024
4125
42- class Field [T : FieldArgs ](InitField [T ]):
26+ class Field [T : FieldArgs ](typing . InitField [T ]):
4327 pass
4428
4529
4630####
4731
4832# TODO: Should this go into the stdlib?
49- type GetFieldItem [T : InitField , K ] = GetMemberType [
50- GetArg [T , InitField , Literal [0 ]], K
33+ type GetFieldItem [T : typing . InitField , K ] = typing . GetMemberType [
34+ typing . GetArg [T , typing . InitField , Literal [0 ]], K
5135]
5236
5337
@@ -56,59 +40,96 @@ class Field[T: FieldArgs](InitField[T]):
5640# Strip `| None` from a type by iterating over its union components
5741# and filtering
5842type NotOptional [T ] = Union [
59- * [x for x in Iter [FromUnion [T ]] if not IsSub [x , None ]]
43+ * [x for x in typing . Iter [typing . FromUnion [T ]] if not typing . IsSub [x , None ]]
6044]
6145
6246# Adjust an attribute type for use in Public below by dropping | None for
6347# primary keys and stripping all annotations.
6448type FixPublicType [T , Init ] = (
6549 NotOptional [T ]
66- if IsSub [Literal [True ], GetFieldItem [Init , Literal ["primary_key" ]]]
50+ if typing . IsSub [Literal [True ], GetFieldItem [Init , Literal ["primary_key" ]]]
6751 else T
6852)
6953
7054# Strip out everything that is Hidden and also make the primary key required
7155# Drop all the annotations, since this is for data getting returned to users
7256# from the DB, so we don't need default values.
73- type Public [T ] = NewProtocol [
57+ type Public [T ] = typing . NewProtocol [
7458 * [
75- Member [GetName [p ], FixPublicType [GetType [p ], GetInit [p ]], GetQuals [p ]]
76- for p in Iter [Attrs [T ]]
77- if not IsSub [Literal [True ], GetFieldItem [GetInit [p ], Literal ["hidden" ]]]
59+ typing .Member [
60+ typing .GetName [p ],
61+ FixPublicType [typing .GetType [p ], typing .GetInit [p ]],
62+ typing .GetQuals [p ],
63+ ]
64+ for p in typing .Iter [typing .Attrs [T ]]
65+ if not typing .IsSub [
66+ Literal [True ], GetFieldItem [typing .GetInit [p ], Literal ["hidden" ]]
67+ ]
7868 ]
7969]
8070
71+ # Begin PEP section: Automatically deriving FastAPI CRUD models
72+ """
73+ We have a more `fully-worked example <#fastapi-test_>`_ in our test
74+ suite, but here is a possible implementation of just ``Public``
75+ """
76+
8177# Extract the default type from an Init field.
8278# If it is a Field, then we try pulling out the "default" field,
8379# otherwise we return the type itself.
8480type GetDefault [Init ] = (
85- GetFieldItem [Init , Literal ["default" ]] if IsSub [Init , Field ] else Init
81+ GetFieldItem [Init , Literal ["default" ]]
82+ if typing .IsSub [Init , Field ]
83+ else Init
8684)
8785
8886# Create takes everything but the primary key and preserves defaults
89- type Create [T ] = NewProtocol [
87+ type Create [T ] = typing . NewProtocol [
9088 * [
91- Member [GetName [p ], GetType [p ], GetQuals [p ], GetDefault [GetInit [p ]]]
92- for p in Iter [Attrs [T ]]
93- if not IsSub [
94- Literal [True ], GetFieldItem [GetInit [p ], Literal ["primary_key" ]]
89+ typing .Member [
90+ typing .GetName [p ],
91+ typing .GetType [p ],
92+ typing .GetQuals [p ],
93+ GetDefault [typing .GetInit [p ]],
94+ ]
95+ for p in typing .Iter [typing .Attrs [T ]]
96+ if not typing .IsSub [
97+ Literal [True ],
98+ GetFieldItem [typing .GetInit [p ], Literal ["primary_key" ]],
9599 ]
96100 ]
97101]
98102
103+ """
104+ The ``Create`` type alias creates a new type (via ``NewProtocol``) by
105+ iterating over the attributes of the original type. It has access to
106+ names, types, qualifiers, and the literal types of initializers (in
107+ part through new facilities to handle the extremely common
108+ ``= Field(...)`` like pattern used here.
109+
110+ Here, we filter out attributes that have ``primary_key=True`` in their
111+ ``Field`` as well as extracting default arguments (which may be either
112+ from a ``default`` argument to a field or specified directly as an
113+ initializer).
114+ """
115+
116+ # End PEP section: CRUD
117+
118+
99119# Update takes everything but the primary key, but makes them all have
100120# None defaults
101- type Update [T ] = NewProtocol [
121+ type Update [T ] = typing . NewProtocol [
102122 * [
103- Member [
104- GetName [p ],
105- GetType [p ] | None ,
106- GetQuals [p ],
123+ typing . Member [
124+ typing . GetName [p ],
125+ typing . GetType [p ] | None ,
126+ typing . GetQuals [p ],
107127 Literal [None ],
108128 ]
109- for p in Iter [Attrs [T ]]
110- if not IsSub [
111- Literal [True ], GetFieldItem [GetInit [p ], Literal ["primary_key" ]]
129+ for p in typing .Iter [typing .Attrs [T ]]
130+ if not typing .IsSub [
131+ Literal [True ],
132+ GetFieldItem [typing .GetInit [p ], Literal ["primary_key" ]],
112133 ]
113134 ]
114135]
@@ -117,40 +138,39 @@ class Field[T: FieldArgs](InitField[T]):
117138
118139# Begin PEP section: dataclass like __init__
119140
120-
121141# Generate the Member field for __init__ for a class
122- type InitFnType [T ] = Member [
142+ type InitFnType [T ] = typing . Member [
123143 Literal ["__init__" ],
124144 Callable [
125145 [
126- Param [Literal ["self" ], Self ],
146+ typing . Param [Literal ["self" ], Self ],
127147 * [
128- Param [
129- GetName [p ],
130- GetType [p ],
148+ typing . Param [
149+ typing . GetName [p ],
150+ typing . GetType [p ],
131151 # All arguments are keyword-only
132152 # It takes a default if a default is specified in the class
133153 Literal ["keyword" ]
134- if IsSub [
135- GetDefault [GetInit [p ]],
154+ if typing . IsSub [
155+ GetDefault [typing . GetInit [p ]],
136156 Never ,
137157 ]
138158 else Literal ["keyword" , "default" ],
139159 ]
140- for p in Iter [Attrs [T ]]
160+ for p in typing . Iter [typing . Attrs [T ]]
141161 ],
142162 ],
143163 None ,
144164 ],
145165 Literal ["ClassVar" ],
146166]
147- type AddInit [T ] = NewProtocol [
167+ type AddInit [T ] = typing . NewProtocol [
148168 InitFnType [T ],
149- * [x for x in Iter [Members [T ]]],
169+ * [x for x in typing . Iter [typing . Members [T ]]],
150170]
151171
152172
153- # End PEP section
173+ # End PEP section: __init__
154174
155175
156176####
0 commit comments