Skip to content

Commit 0bcbe5a

Browse files
committed
move rationale
1 parent bc368bc commit 0bcbe5a

2 files changed

Lines changed: 52 additions & 7 deletions

File tree

pre-pep.rst

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,6 @@ different conditions of Python typing.
2525
Motivation
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-
3428
Python has a gradual type system, but at the heart of it is a fairly
3529
conventional and tame static type system. In Python as a language, on
3630
the 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
4236
case of dataclass-like transformations (:pep:`PEP 681 <681>`).
4337

44-
pydantic, dataclasses, sqlalchemy
38+
Examples: pydantic/fastapi, dataclasses, sqlalchemy
4539

4640
Automatically deriving FastAPI CRUD models
4741
------------------------------------------
@@ -262,6 +256,56 @@ Implementation
262256

263257
We 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

267311
Specification

tests/test_qblike_2.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class MultiLink[T](Link[T]):
5656
else DropProp[T]
5757
)
5858

59+
5960
# XXX: putting list here doesn't work!
6061
def select[K: BaseTypedDict](
6162
rcv: type[User],

0 commit comments

Comments
 (0)