From 1d18895370d706e6cd44f50988fcfe63e0b72c69 Mon Sep 17 00:00:00 2001 From: "Michael J. Sullivan" Date: Thu, 8 Jan 2026 16:39:43 -0800 Subject: [PATCH 1/3] Propose direct associated type access --- spec-draft.rst | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/spec-draft.rst b/spec-draft.rst index b456b75..eaf7633 100644 --- a/spec-draft.rst +++ b/spec-draft.rst @@ -281,3 +281,31 @@ Oh, we could maybe do better but it would require some new machinery. * ``Member[T]``, when statically checking a type alias, could be treated as having some type like ``tuple[Member[KeyOf[T], object???, str], ...]`` * ``GetAttr[T, S: KeyOf[T]]`` - but this isn't supported yet. TS supports it. * We would also need to do context sensitive type bound inference + +---- + + +============================= +Direct associated type access +============================= + +What we *really* want for this is to write:: + + class Member[N: str, T, Q: MemberQuals = typing.Never, D = typing.Never]: + type name = N + type tp = T + type quals = Q + type definer = D + +And then we could just write ``m.name`` and have it do the right thing. (Ties broken by MRO of course). +This would be super nice. + +The problem is that if the LHS isn't already evaluated, we'll get back just an alias with no idea what the LHS was, and we won't be able to substitute in the variables. + +TODO: DECIDE + +Ideas: + 1. Have it only work if the LHS is an evaluated variable somehow. That is kind of unsatisfying. + 2. Use something other than ``type foo =`` to do this. Like, ``name: N = associated_type()`` and have that be a descriptor. (Use ``__set_name__`` to be able to track things.) + 3. Add a decorator or base class that replaces the GenericTypeAliases with the descriptor from above. + 4. Make ``GenericTypeAlias`` a descriptor (do the above for testing). From f69f4c7bdaffe74dc02d4567cebb864a45b9f64a Mon Sep 17 00:00:00 2001 From: "Michael J. Sullivan" Date: Mon, 12 Jan 2026 09:42:58 -0800 Subject: [PATCH 2/3] The __set_name__ thing is nonsense --- spec-draft.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec-draft.rst b/spec-draft.rst index eaf7633..7cf560c 100644 --- a/spec-draft.rst +++ b/spec-draft.rst @@ -306,6 +306,6 @@ TODO: DECIDE Ideas: 1. Have it only work if the LHS is an evaluated variable somehow. That is kind of unsatisfying. - 2. Use something other than ``type foo =`` to do this. Like, ``name: N = associated_type()`` and have that be a descriptor. (Use ``__set_name__`` to be able to track things.) + 2. Use something other than ``type name =`` to do this. Like, ``name = associated_type(N)`` and have that be a descriptor. 3. Add a decorator or base class that replaces the GenericTypeAliases with the descriptor from above. 4. Make ``GenericTypeAlias`` a descriptor (do the above for testing). From 713a599964bc9b63c7b33cc0390693380d338cc8 Mon Sep 17 00:00:00 2001 From: "Michael J. Sullivan" Date: Mon, 12 Jan 2026 10:12:28 -0800 Subject: [PATCH 3/3] Update: this doesn't work --- spec-draft.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spec-draft.rst b/spec-draft.rst index 7cf560c..dc9cddc 100644 --- a/spec-draft.rst +++ b/spec-draft.rst @@ -309,3 +309,9 @@ Ideas: 2. Use something other than ``type name =`` to do this. Like, ``name = associated_type(N)`` and have that be a descriptor. 3. Add a decorator or base class that replaces the GenericTypeAliases with the descriptor from above. 4. Make ``GenericTypeAlias`` a descriptor (do the above for testing). + +UPDATE: None of this works except maybe the first one, because the descriptor will get called on the *origin class* and not the instantiated ``_GenericAlias``. + +We could probably kind of make it work by having a descriptor and having the descriptor *walk the stack* and get the ``self`` from the ``_BaseGenericAlias.__getattr__`` stack frame but that is a horror show... + +Yury thinks we don't want to propose anything that requires much modifying of the descriptors...