On Sun, Aug 24, 2014 at 10:00:32AM +0200, Georg Brandl wrote:
On 08/24/2014 07:54 AM, Greg Ewing wrote:
Steven D'Aprano wrote:
I don't really understand what you're trying to say here, so I may be misinterpreting you. I *think* that you're trying to say that for every type in the standard library, and every class created by third parties (including subclasses), the author will have to "declare" (in some unknown sense) that it can be used for type annotations like MyList[T], for some type T.
I suppose the run-time incarnations of the type descriptions could be looser, but if you want to use them for static checking, the static checker is going to have to know what MyList[T] means in some detail (what effect the parameter has on the method types, etc.) The programmer will have to specify all that somehow.
The way this is done in other languages with static type checking is to give the class declaration a parameter list. I was envisaging that the mypy type description syntax would have something equivalent. Not sure what form it would take, though.
Exactly. Does mypy handle that? For example, for a custom mapping type
class Mapping(object): def setitem(self, key, value): ...
how would one specify a) that you can use Mapping[T1, T2] as a type annotation and b) the type annotations for the "key" and "value" arguments?
I'm not an expert on Mypy, but I think the answer is, you can't. In order for Mypy to recognise your Mapping as an actual mapping, you have to either inherit from dict or some other mapping which Mypy knows about, or from typing.Generic. http://mypy-lang.org/tutorial.html#genericclasses from typing import typevar, Generic T = typevar('T') class Mapping(Generic[T, T]): ... Now Mypy will know that your Mapping class should be considered a mapping from some type to another type, and you can use it: def func(x:Mapping[int, str], n:int)->str: return x[n+1] which will pass the static type checker. (This is just what I understand from reading some of the docs, I welcome correction from anyone who knows better.) But that's just Mypy. Another type checker might just trust you, regardless of what terrible lies you tell it, so long as they're consistent lies: def func(x:set[int, str], n:int)->str: return x[n+1] Since you've said x is a set which maps ints to strs, the code will pass the static check, but fail at run-time since sets don't actually support __getitem__. A third type checker might do structural typing instead of nominal typing, and be able to recognise that set doesn't have __getitem__ but Mapping does. Remember that this proposal isn't about adding Mypy to the standard library or merging it with CPython. It remains a third-party implementation. People are encouraged to work on Mypy, or fork it, or build their own static tools, which may or may not do a better job of static analysis. Or runtime tools for that matter. -- Steven