On 31 December 2015 at 04:09, Sven R. Kunze firstname.lastname@example.org wrote:
On 29.12.2015 03:59, Nick Coghlan wrote:
On 28 December 2015 at 03:04, Guido van Rossum email@example.com wrote:
[ABCs are one honking great idea -- let's do more of those!]
[collections.abc.Indexable would be a good one.]
Maybe, I still cannot wrap my mind enough around the types-everywhere-in-python-please world.
But, what's so wrong about checking for __getitem__ or __len__ if necessary?
Most of the time when I care, it's for early error detection. For normal function calls, your best bet is to just try the operation, and let the interpreter generate the appropriate exception - the traceback will give the appropriate context for the error, so there's little gain in doing your own check.
Things change when you're handing a callable off to be invoked later, whether that's through an object queue, atexit, context manager, thread pool, process pool, or something else. In those cases, a delayed exception will trigger in the invocation context, and so the traceback won't give the reader any information about which part of the code provided the bad arguments.
There are two main remedies for this:
1. Use runtime argument checking at the point the arguments are passed in 2. Use some form of structural type checking that allows code to be analysed for correctness without running it
The abc module provides a framework for the former task - if you know an algorithm needs a sequence (for example), you can write "isinstance(arg, Sequence)" before submitting the operation for execution and raise TypeError if the check fails. Folks passing in the wrong kind of argument then get a nice error message with a traceback at the point where they provided the incorrect data, rather than an obscure traceback that they then have to debug. As Andrew explains in his reply, this can be as simple as checking for a specific attribute, but it also extends to more complex criteria without changing the way you perform the runtime check.
Static analysers like mypy, pytypedecl and pylint provide support for the latter approach, by checking for consistency between the way objects are defined and created and the way they're used. While it's possible for incorrect code to pass static analysis, the vast majority of correct code will pass it (and any which fails would likely be confusing to a human reader as well). Since the analysis is static, runtime dynamism isn't relevant - the analyser can point out both sides of the inconsistency, even if they're encountered at different times or in different threads or processes when executed.