[Python-Dev] Re: Proto-PEP part 1: Forward declaration of classes
The forward class annotations would not need need to be processed at runtime and could be no-ops. forward class A: x: int y: list[int] A.__annotations__ could be empty. For a more complete example you could have, forward class A: value: B # This annotation is solely for type checker and is not actually saved at runtime. class B: value: A # Real annotation that is saved. continue class A: value: B # Real annotation that is saved. The rule would then be that any annotation inside forward class is equivalent to a noop. Continue class would still need to have same annotation repeated to actually set it at runtime. ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/O3HMCIWUM6NGTSCGL7HFRBSDT7A4KFHP/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: Proto-PEP part 1: Forward declaration of classes
The problem comes solely from runtime introspection of type annotations. Static typing does not need this nor do any exceptional cases occur. From mypy/pyright/other type checker perspective there is not an issue to solve here. dataclasses, pydantic, cattrs, click, and other libraries that inspect type annotations at runtime is where cyclic or undefined nature of some annotations is causing edge cases. For most users of typing world they primarily think of former and not the latter. ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/GCNP5YVHC4EY4XLXQ3F5MLMCGM5FPDAQ/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: Proto-PEP part 1: Forward declaration of classes
We could have forward part include all of method signatures/attributes which is what a type checker needs. In theory we could do, forward class Foo: x: int y: list[str] def __init__(self, ...) def process(self, data: list[float]) -> float: ... and then later do continue class. If we're willing to write a full header equivalent of c++ then I think static typing side will work. It'll be a lot more verbose then normal that I'd probably pick other solutions, but I it should make it tractable for a type checker. ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/YP6Y7XE7HSKAEQM4KUDSLBBHOEIKE3UT/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: Proto-PEP part 1: Forward declaration of classes
My main question for this approach is how would this work with type checkers? Is there any restriction that forward class's continuation must appear in same module? If it's allowed that a forward class may be continued in a different module I do not see how type checker like mypy/pyright could handle that. Classes are generally viewed as closed and fully defined within type checker. Monkey patching at runtime later is not supported. Libraries/techniques that rely on extending a class later tend to be sources of type errors/poor type checking coverage. ABC.register for dynamically declaring subclass relationship is similarly not supported by checkers. So without constraint that forward class must be continued within same module I think it's unlikely any type checker would support this technique. As main motivation is related to type annotations I think usage should be supported by type checkers. One other edge case here is how would you forward declare an annotation for a type that like this, if TYPE_CHECKING: import numpy def f(x: numpy.ndarray) -> None: ... forward declaring ndarray here would not make numpy.ndarray available. Would you forward declare modules? Is that allowed? Looking at sourcegraph I do see a some module imports in TYPE_CHECKING blocks for purpose of using them as annotations. I'm confused in general how if TYPE_CHECKING issue is handled by this approach. Usually class being imported in those blocks is defined normally (without continue class) somewhere else. My current leaning lies towards pep 649 + smart eval strategy by get_type_hints that Carl proposed. ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/XNYKAEI6TSZU2EKQEM6AXDZOMVD3CPLS/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: RFC on Callable Syntax PEP
I don’t see how this helps much in situations with nested callables which are very common for decorators. I’m also unsure how this will work with situations where input and output are both callables and the signature is modified using paramspec. An example would be a decorator that adds/removes one argument. Is Concatenate[int, InttoIntFunction] a thing? I also would ideally want a very light weight way to handle simple callables like (int) -> bool. This decorator solution of @Callable seems roughly as readable as existing solution of using callback protocols or a type alias. I took a quick scan of my team’s codebase and see about 150 callable vs like 1.5k optional. Optional is fairly high as a lot of our code has many arguments that can be disabled which I think is normal for ml/numerical libraries with tons of tuning settings. The most complex callable signatures tend to be decorators/decorator factories for us. Main place I find this useful is skimming other libraries type signatures and hovering in ides. Nice hover type hints is helpful over large blocks of callable brackets. I do find this syntactic sugar nice. I’m +0.5, mainly as while I think current callable generic is messy, I also think most of the people that write those type annotations are the ones that write a lot of them. Maybe that would change with better readability but right now heavy callable type usage feel like an advanced, uncommon thing. Part of it is also heavy functional style code isn’t that common in python. ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/EVE274LSWE5CDPJYW3VVVPJENVQIQMVM/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: PEP-646 question: unpacking into single Generic parameter
I don't believe this is supported in pep 646 today. It was originally going to be supported with a Map operator. With a Map operator it would let you do something like, T = TypeVar('T') Ts = TypeVarTuple("Ts") IndexedTuple = Tuple[Int, T] def enumerage_args(*args: *Ts) -> *Map[IndexedTuple, Ts] return enumerate(args) Map operator takes two arguments, a generic type and type var tuple. This document describes map operator in more detail and an older version of the pep had it. https://docs.google.com/document/d/1szTVcFyLznoDT7phtT-6Fpvp27XaBw9DmbTLHrB6BE4/edit The reason it is missing is original version of 646 was becoming too complex for a single pep. My understanding is your example/similar examples are intended for the future to be supported, but that Map operator and other extensions to variadic generics will be future peps. ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/YBJXIAGODKH4NB5OD4YBZUZPA7NV6T73/ Code of Conduct: http://python.org/psf/codeofconduct/