Ken Jin <kenjin4...@gmail.com> added the comment:

> In short, I will do my best, but I suspect I will need patience and guidance 
> in arriving something acceptable.

Yeah no worries. typing.py is really complex for many historical reasons. I 
still don't grasp all of it and probably never will.

> what about _AnnotatedAlias, _SpecialGenericAlias, _UnionGenericAlias, or 
> _strip_annotations?

They shouldn't need modification. And there's an elegant reason why. Currently 
ParamSpec is only valid in Generic, Callable and Concatenate. We don't care 
about any other types. As long as ParamSpec appears in their __parameters__ and 
the copy_with of those 3 have the correct settings.

Well what about when they're nested? The other types blindly copy over whatever 
they see in __parameters__ of any nested types. So even if you don't pass those 
settings to their copy_with, it doesn't matter (well of course, until someone 
else uses this setting and expands its scope, then proceeds to trip over it :(. 
this seems like a potential trap affecting PEP 646's runtime.)

>>> X = Concatenate[int, ParamSpec('P')]
>>> Container[X]
typing.Container[typing.Concatenate[int, ~P]]
>>> Container[X].copy_with(X).__parameters__
(~P,)
^ Works even though this uses _SpecialGenericAlias, which doesn't properly pass 
in the settings!

> I can't find any tests that deal with copy_with directly, so I'm assuming its 
> use is stressed via higher level code paths, but it's not clear what use 
> cases that method is supposed to serve.

Yeah. If you search for "copy_with" in typing.py. You'll find that it's called 
in __getitem__. Now __getitem__ is used when we subscript an already 
subscripted type. What I mean is:

T = TypeVar('T')
X = List[T] (__class_getitem__ is called, returning a new genericalias object)
X[int] (__getitem__ is called, returning a new genericalias object)

We need copy_with because we want to create a full "copy" of all the args into 
the new GenericAlias object and not face weird problems with mutability. That 
specific use case is tested super often.

> _ConcatenateGenericAlias.copy_with, on the other hand, appears to return a 
> tuple rather than a type until it falls back to the parent implementation. 
> What does one do with that?

Frankly, I was quite lost too until I saw that it was part of bpo-44791, which 
deals with special special (undefined) cases in PEP 612 and Concatenate. 
Basically for a very weird Concatenate, the core dev there has chosen to return 
a tuple of types instead of another type. Let's just ignore those strange tuple 
paths, and only care about the path using the parent implementation.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue46581>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to