[Python-ideas] Type Hinting Kick-off

Steven D'Aprano steve at pearwood.info
Sat Dec 20 08:59:45 CET 2014


On Fri, Dec 19, 2014 at 04:55:37PM -0800, Guido van Rossum wrote:
> A few months ago we had a long discussion about type hinting. I've thought
> a lot more about this. I've written up what I think is a decent "theory"
> document -- writing it down like this certainly helped *me* get a lot of
> clarity about some of the important issues.
> 
> https://quip.com/r69HA9GhGa7J

Very interesting indeed.

Some questions, which you may not have answers to yet :-)

(1) Under "General rules", you state "No type can be subclassed unless 
stated." That's not completely clear to me. I presume you are talking 
about the special types like Union, Generic, Sequence, Tuple, Any etc. 
Is that correct?


(2) Under "Types", you give an example Tuple[t1, t2, ...], a tuple 
whose items are instances of t1 etc. To be more concrete, a declaration 
of Tuple[int, float, str] will mean "a tuple with exactly three items, 
the first item must be an int, the second item must be a float, the 
third item must be a string." Correct?


(3) But there's no way of declaring "a tuple of any length, which each 
item is of type t". We can declare it as Sequence[t], but cannot specify 
that it must be a tuple, not a list. Example:

class MyStr(str):
    def startswith(self, prefix:Union[str, ???])->bool:
        pass

There's nothing I can use instead of ??? to capture the current 
behaviour of str.startswith. Correct?


(4) Under "Pragmatics", you say "Don't use dynamic type expressions; use 
builtins and imported types only. No 'if'." What's the reason for this 
rule? Will it be enforced by the compiler?


(5) I presume (4) above also applies to things like this:

    if condition():
        X = Var('X', str)
    else:
        X = Var('X', bytes)

    # Later on
    def spam(arg: X)-> X:
        ...

How about this?

    try:
        from condition_is_true import X  # str
    except ImportError:
        from condition_is_false import X  # bytes


(6) Under "Generic types", you have:

    X = Var('X'). Declares a unique type variable. 
    The name must match the variable name.

To be clear, X is a type used only for declarations, right? By (1) 
above, it cannot be instantiated? But doesn't that make it impossible to 
satisfy the declaration? I must be misunderstanding something.

I imagine the declaration X = Var("X") to be something equivalent to:

    class X(type):
        pass

except that X cannot be instantiated.


(7) You have an example:

    AnyStr = Var('AnyStr', str, bytes)
    def longest(a: AnyStr, b: AnyStr) -> AnyStr:


Would this be an acceptable syntax?

    def longest(a:str|bytes, b:str|bytes) -> str|bytes

It seems a shame to have to invent a name for something you might only 
use once or twice.



-- 
Steve


More information about the Python-ideas mailing list