4 ms·
> 1. You can define a function type somewhat clumsily (`Callable[[Arg1T, Arg2T], ReturnT]`), but if your callback uses keyword arguments (pervasive among Python
by davidfstr 6y ago
> 1. You can define a function type somewhat clumsily (`Callable[[Arg1T, Arg2T], ReturnT]`), but if your callback uses keyword arguments (pervasive among Python programs), you're out of luck.
I've personally never missed the ability to add keyword arguments to a Callable. If you want to anyway, I understand that at least mypy has syntax for this:
* https://mypy.readthedocs.io/en/stable/protocols.html#callback-protocols https://mypy.readthedocs.io/en/stable/protocols.html#callbac...
* https://mypy.readthedocs.io/en/stable/additional_features.html?highlight=keyword#extended-callable-types https://mypy.readthedocs.io/en/stable/additional_features.ht...
> Beyond that, it's just the general usability issues that ultimately derive from Python's election to shoehorn a lot of typing functionality into minimal syntax changes
Many syntax niceities will be introduced in upcoming Python releases. From the article:
* Union types are shortened to X | Y (PEP 604)
* (?) Optional types shortened to X? (PEP 645)
* Type Hinting Generics In Standard Collections (PEP 585) - Can use list[T], dict[K, V], etc in place of List[T] and Dict[K, V].
With those changes, you won't generally need to import the `typing` module at all anymore.
> there just isn't enough investment to move it forward.
Dropbox has dedicated engineers maintaining mypy. And of course a few volunteers such as myself. And Guido. :)
- throwaway894345 6y ago> I've personally never missed the ability to add keyword arguments to a Callable. If you want to anyway, I understand that at least mypy has syntax for this Neat, I didn't realize this. This is far from desirable, but nice to know it's possible. > Many syntax niceities will be introduced in upcoming Python releases. From the article: I mean, typing out "Union" and "Option" or even having to import generic types from the typing module aren't really the syntactic pain points I was referring to. It's more like "Where do I define the TypeVar for a generic method on a class? Do I define it inside of the class or at the top-level module? In either case, if I reference that variable in another method, does it imply that these two types are the same? No doubt there are answers, but Python is the only language in which I have to navigate these kinds of questions. Similarly, having to create a protocol for kwarg callbacks seems really heavy. These are the kinds of things I would like to see improved. > Dropbox has dedicated engineers maintaining mypy. And of course a few volunteers such as myself. And Guido. :) Yes, I didn't mean to suggest there was no investment, only that the progress seems really slow (also, I didn't realize Guido was a volunteer? I thought he was employed by DropBox to work on Python). How long have recursive types been in a holding pattern, for example? I don't mean to disrespect you or any of the other maintainers--no doubt you're doing great work.
- jacobr1 6y agoMore annoying for our codebase is the inability to specify optional/default arguments with closures. We often use functions that return other functions and you can't persist the "optional state" without using a protocol. It would be great just to match the current state of vanilla defs with optional params. For example: def make_fun1(a: int) -> Callable[[int, Optional[int]], str]: def fun(b: int, c: Optional[int] = None) -> str: if c: b += c return f"{a+b}" return fun fun = make_fun(1) fun(2) Will give you `Too few arguments` for `fun(2)` You can fix this with something like: class FunC(Protocol): def __call__(self, b: int, c: Optional[int] = None) -> str: ... def make_fun(a: int) -> FunC: ... But that that seems like unnecessary overhead, because the non-nested def case can happily understand the optional parameter.