On Thu, Sep 10, 2015 at 3:01 AM, Luciano Ramalho
Jukka, thank you very much for working on such a hard topic and being patient enough to respond to issues that I am sure were exhaustively discussed before (but I was not following the discussions then since I was in the final sprint for my book, Fluent Python, at the time).
I have two questions which were probably already asked before, so feel free to point me to relevant past messages:
1) Why is a whole new hierarchy of types being created in the typing module, instead of continuing the hierarchy in the collections module while enhancing the ABCs already there? For example, why weren't the List and Dict type created under the existing MutableSequence and MutableMapping types in collections.abc?
There are two main reasons. First, we wanted typing to be backward compatible down to Python 3.2, and so all the new features had to work without any changes to other standard library modules. Second, the module is provisional and it would be awkward to have non-provisional standard library modules depend on or closely interact with a provisional module. Also, List and Dict are actually type aliases for regular classes (list and dict, respectively) and so they actually represent subclasses of MutableSequence and MutableMapping as defined in collections.abc. They aren't proper classes so they don't directly play a role at runtime outside annotations.
2) Similarly, I note that PEP-484 shuns existing ABCs like those in the numbers module, and the ByteString ABC. The reasons given are pragmatic, so that users don't need to import the numbers module, and would not "have to write typing.ByteString everywhere." as the PEP says... I don not understand these arguments because:
a) as you just wrote in another message, the users will be primarily the authors of libraries and frameworks, who will always be forced to import typing anyhow, so it does not seem such a burden to have them import other modules get the benefits of type hinting;
I meant that protocols will likely be often *defined* in libraries or frameworks (or their stubs). Almost any code can *use* protocols in annotations, but user code might be less likely to define additional protocols. That's just a guess and I could be easily proven wrong, though. b) alternatively, there could be aliases of the relevant ABCs in the
typing module for convenience
There are other reasons for not using ABCs for things like numbers. For example, a lot of standard library functions expect concrete numeric types and won't accept arbitrary subclasses of the ABCs. For example, you couldn't pass a value with the numbers.Integral type to math.sin, because it expects an int or a float. Using ABCs instead of int, float or str wouldn't really work well (or at all) for type checking.
So the second question is: what's wrong with points (a) and (b), and why did PEP-484 keep such a distance form existing ABCs in general?
See above. There are more reasons but those that I mentioned are some of the more important ones. If you are still unconvinced, ask for more details and maybe I'll dig through the archives. :-)
I understand pragmatic choices, but as a teacher and writer I know such choices are often obstacles to learning because they seem arbitrary to anyone who is not privy to the reasons behind them. So I'd like to better understand the reasoning, and I think PEP-484 is not very persuasive when it comes to the issues I mentioned.
Yeah, PEP 484 doesn't go through the rationale and subtleties in much detail. Maybe there should be a separate rationale PEP and we could just link to it when we get asked some of these (quite reasonable, mind you!) questions again. ;-) Jukka