Skip to content

Commit a51462f

Browse files
committed
Rework alternate syntax ideas a bit
1 parent aaf48cb commit a51462f

File tree

1 file changed

+53
-28
lines changed

1 file changed

+53
-28
lines changed

pep.rst

Lines changed: 53 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,7 @@ values too?
799799
.. _generic-callable:
800800

801801
Generic Callable
802-
""""""""""""""""
802+
''''''''''''''''
803803

804804
* ``GenericCallable[Vs, lambda <vs>: Ty]``: A generic callable. ``Vs`` are a tuple
805805
type of unbound type variables and ``Ty`` should be a ``Callable``,
@@ -819,7 +819,7 @@ TODO: Decide if we have any mechanisms to inspect/destruct
819819
maybe can apply it to concrete types?
820820

821821
Overloaded function types
822-
"""""""""""""""""""""""""
822+
'''''''''''''''''''''''''
823823

824824
* ``Overloaded[*Callables]`` - An overloaded function type, with the
825825
underlying types in order.
@@ -1319,21 +1319,26 @@ Support dot notation to access ``Member`` components
13191319
----------------------------------------------------
13201320

13211321
Code would read quite a bit nicer if we could write ``m.name`` instead
1322-
of ``GetName[m]``. A general mechanism to support that might look
1323-
like::
1322+
of ``GetName[m]``.
1323+
With dot notation, ``PropsOnly`` (from
1324+
:ref:`the query builder example <qb-impl>`) would look like::
13241325

1325-
class Member[N: str, T, Q: MemberQuals = typing.Never, I = typing.Never, D = typing.Never]:
1326-
type name = N
1327-
type tp = T
1328-
type quals = Q
1329-
type init = I
1330-
type definer = D
1326+
type PropsOnly[T] = typing.NewProtocol[
1327+
*[
1328+
typing.Member[p.name, PointerArg[p.type]]
1329+
for p in typing.Iter[typing.Attrs[T]]
1330+
if typing.IsAssignable[p.type, Property]
1331+
]
1332+
]
13311333

1332-
We considered this but rejected it due to runtime implementation
1333-
concerns: an expression like ``Member[Literal["x"], int].name`` would
1334-
need to return an object that captures both the content of the type
1335-
alias while maintaining the ``_GenericAlias`` of the applied class so
1336-
that type variables may be substituted for.
1334+
Which is a fair bit nicer.
1335+
1336+
1337+
We considered this but initially rejected it in part due to runtime
1338+
implementation concerns: an expression like ``Member[Literal["x"],
1339+
int].name`` would need to return an object that captures both the
1340+
content of the type alias while maintaining the ``_GenericAlias`` of
1341+
the applied class so that type variables may be substituted for.
13371342

13381343
We were mistaken about the runtime evaluation difficulty,
13391344
though: if we required a special base class in order for a type to use
@@ -1344,23 +1349,37 @@ We wouldn't be able to have the operation lift over unions or the like
13441349
(unless we were willing to modify ``__getattr__`` for
13451350
``types.UnionType`` and ``typing._UnionGenericAlias`` to do so!)
13461351

1352+
Or maybe it would be fine to have it only work on variables, and then
1353+
no special support would be required at the definition site.
1354+
13471355
That just leaves semantic and philosophical concerns: it arguably makes
13481356
the model more complicated, but a lot of code will read much nicer.
13491357

1350-
Another option would be to skip introducing a general mechanism (for
1351-
now, at least), but at least make dot notation work on ``Member``,
1352-
which will be extremely common.
1358+
What would the mechanism be?
1359+
''''''''''''''''''''''''''''
13531360

1354-
With dot notation, ``PropsOnly`` (from
1355-
:ref:`the query builder example <qb-impl>`) would look like::
1361+
A general mechanism to support this might look
1362+
like::
13561363

1357-
type PropsOnly[T] = typing.NewProtocol[
1358-
*[
1359-
typing.Member[p.name, PointerArg[p.type]]
1360-
for p in typing.Iter[typing.Attrs[T]]
1361-
if typing.IsAssignable[p.type, Property]
1362-
]
1363-
]
1364+
class Member[
1365+
N: str,
1366+
T,
1367+
Q: MemberQuals = typing.Never,
1368+
I = typing.Never,
1369+
D = typing.Never
1370+
]:
1371+
type name = N
1372+
type tp = T
1373+
type quals = Q
1374+
type init = I
1375+
type definer = D
1376+
1377+
Where ``type`` aliases defined in a class can be accessed by dot notation.
1378+
1379+
1380+
Another option would be to skip introducing a general mechanism (for
1381+
now, at least), but at least make dot notation work on ``Member`` and
1382+
``Param``, which will be extremely common.
13641383

13651384

13661385
Dictionary comprehension based syntax for creating typed dicts and protocols
@@ -1395,6 +1414,12 @@ annotation expression in an arm of a conditional type?
13951414
The main downside of this proposal is just complexity: it requires
13961415
introducing another kind of weird type form.
13971416

1417+
We'd also need to figure out the exact interaction between typeddicts
1418+
and new protocols. Would the dictionary syntax always produce a typed
1419+
dict, and then ``NewProtocol`` converts it to a protocol, or would
1420+
``NewProtocol[<dict type expr>]`` be a special form? Would we try to
1421+
allow ``ClassVar`` and ``Final``?
1422+
13981423
Destructuring?
13991424
''''''''''''''
14001425

@@ -1431,7 +1456,7 @@ Call type operators using parens
14311456
--------------------------------
14321457

14331458
If people are having a bad time in Bracket City, we could also
1434-
consider making the builtin type operators use parens instead of
1459+
consider making the built-in type operators use parens instead of
14351460
brackets.
14361461

14371462
Obviously this has some consistency issues but also maybe signals a

0 commit comments

Comments
 (0)