@@ -25,12 +25,6 @@ different conditions of Python typing.
2525Motivation
2626==========
2727
28- [Clearly explain why the existing language specification is inadequate to address the problem that the PEP solves.]
29-
30-
31- Rationale
32- =========
33-
3428Python has a gradual type system, but at the heart of it is a fairly
3529conventional and tame static type system. In Python as a language, on
3630the other hand, it is not unusual to perform complex metaprogramming,
@@ -41,7 +35,7 @@ libraries come with custom mypy plugins, and a special-case
4135``@dataclass_transform `` decorator was added specifically to cover the
4236case of dataclass-like transformations (:pep: `PEP 681 <681 >`).
4337
44- pydantic, dataclasses, sqlalchemy
38+ Examples: pydantic/fastapi , dataclasses, sqlalchemy
4539
4640Automatically deriving FastAPI CRUD models
4741------------------------------------------
@@ -262,6 +256,56 @@ Implementation
262256
263257We have a more `worked example <#qb-test _>`_ in our test suite.
264258
259+ dataclasses-style method generation
260+ -----------------------------------
261+
262+ We would additionally like to be able to generate method signatures
263+ based on the attributes of an object. The most well-known example of
264+ this is probably generating ``__init__ `` methods for dataclasses,
265+ which we present a simplified example of. (In our test suites, this is
266+ merged with the FastAPI-style example above, but it need not be).
267+
268+ This kind of pattern is widespread enough that :pep: `PEP 681 <681 >`
269+ was created to represent a lowest-common denominator subset of what
270+ existing libraries do.
271+
272+ ::
273+ # Generate the Member field for __init__ for a class
274+ type InitFnType[T] = Member[
275+ Literal["__init__"],
276+ Callable[
277+ [
278+ Param[Literal["self"], Self],
279+ *[
280+ Param[
281+ GetName[p],
282+ GetType[p],
283+ # All arguments are keyword-only
284+ # It takes a default if a default is specified in the class
285+ Literal["keyword"]
286+ if Sub[
287+ GetDefault[GetInit[p]],
288+ Never,
289+ ]
290+ else Literal["keyword", "default"],
291+ ]
292+ for p in Iter[Attrs[T]]
293+ ],
294+ ],
295+ None,
296+ ],
297+ Literal["ClassVar"],
298+ ]
299+ type AddInit[T] = NewProtocol[
300+ InitFnType[T],
301+ *[x for x in Iter[Members[T]]],
302+ ]
303+
304+
305+ Rationale
306+ =========
307+
308+ [Describe why particular design decisions were made.]
265309
266310
267311Specification
0 commit comments