[Python-ideas] Structural type checking for PEP 484

Steven D'Aprano steve at pearwood.info
Fri Sep 18 05:00:26 CEST 2015

On Thu, Sep 17, 2015 at 11:24:53PM +0200, Sven R. Kunze wrote:
> On 17.09.2015 05:59, Steven D'Aprano wrote:
> >People will use the same sort of heuristic for deciding which functions
> >get annotated:
> >
> >- does the function need annotations/documentation/tests?
> >- do I have time to write annotations/documentation/tests?
> >- is my manager telling me to add annotations/documentation/tests?
> >- if I don't, will bad things happen?
> >- if it easy or interesting to add them?
> >- or difficult and boring?
> I fear I am not convinced of that analogy.
> Tests and documentation is all or nothing. Either you have them or you 
> don't and one is not worthier than another.

I don't think they are all or nothing. I think it is possible to have 
incomplete documentation and partial test coverage -- it isn't like you 
go from "no documentation at all and zero tests" to "fully documented 
and 100% test coverage" in a single step. Unless you are religiously 
following something like Test Driven Development, where code is always 
written to follow a failed test, there will be times where you have to 
decide between writing new code or improving test coverage.

Other choices may include:

- improve documentation;
- fix bugs;
- run a linter and fix the warnings it generates;

Adding "fix type errors found by the type checker" doesn't fundamentally 
change the nature of the work. You are still deciding what your 
priorities are, according to the needs of the project, your own personal 
preferences, and the instructions of your project manager (if you have 

> Type annotations (as far as I understand them) are basically completing 
> a picture of 40%-of-already-inferred types. 

That's one use-case for them. Another use-case is as documentation:

def agm(x:float, y:float)->float:
    """Return the arithmetic-geometric mean of x and y."""


def agm(x, y):
    """Return the arithmetic-geometric mean of x and y.

        x (float): A number.
        y (float): A number.

        float: The agm of the two numbers.

> So, I have difficulties to 
> infer which parameters actually would benefit from annotating. 

The simplest process may be something like this:

- run the type-checker in a mode where it warns about variables 
  with unknown types;
- add just enough annotations so that the warnings go away.

This is, in part, a matter of the quality of your tools. A good type 
checker should be able to tell you where it can, or can't, infer a type.

> I am 
> either doing redundant work (because the typechecker is already very 
> well aware of the type) or I actually insert explicit knowledge (which 
> might become redundant in case typecheckers actually become better).

You make it sound like, alone out of everything else in Python 
programming, once a type annotation is added to a function it is carved 
in stone forever, never to be removed or changed :-)

If you add redundant type annotations, no harm is done. For example:

def spam(n=3):
    return "spam"*n

A decent type-checker should be able to infer that n is an int. What if 
you add a type annotation?

def spam(n:int=3):
    return "spam"*n

Is that really such a big problem that you need to worry about this? I 
don't think so. The choice whether to rigorously stamp out all redundant 
type annotations, or leave them in, is a decision for your project. 
There is no universal right or wrong answer.


More information about the Python-ideas mailing list