[Python-ideas] Conventions for function annotations

Thomas Kluyver thomas at kluyver.me.uk
Sat Dec 1 13:28:50 CET 2012


Function annotations (PEP 3107) are a very interesting new feature, but so
far have gone largely unused. The only project I've seen using them is
plac, a command-line option parser. One reason for this is that because
function annotations can be used to mean anything, we're wary of doing
anything in case we interfere with some other use case. A recent thread on
ipython-dev touched on this [1], and we'd like to suggest some conventions
to make annotations useful for everyone.

1. Code inspecting annotations should be prepared to ignore annotations it
can't understand.

2. Code creating annotations should use wrapper classes to indicate what
the annotation means. For instance, we are contemplating a way to specify
options for a parameter, to be used in tab completion, so we would do
something like this:

from IPython.core.completer import options
def my_io(filename, mode: options('read','write') ='read'):
    ...

3. There are a couple of important exceptions to 2:
- Annotations that are simply a string can be used like a docstring, to be
displayed to the user. Inspecting code should not expect to be able to
parse any machine-readable information out of these strings.
- Annotations that are a built-in type (int, str, etc.) indicate that the
value should always be an instance of that type. Inspecting code may use
these for type checking, introspection, optimisation, or other such
purposes. Note that for now, I have limited this to built-in types, so
other types can be used for other purposes, but this could be extended. For
instance, the ABCs from collections (collections.Mapping et al.) could well
be added to this category.

4. There should be a convention for attaching multiple annotations to one
value. I propose that all code using annotations expects to handle
tuples/lists of annotations. (We also considered dictionaries, but the
result is long and ugly). So in this definition:

def my_io(filename, mode: (options('read','write'), str, 'The mode in which
to open the file') ='read'):
    ...

the mode parameter has a set of options (ignored by frameworks that don't
recognise it), should always be a string, and has a description.

Any thoughts and suggestions are welcome.

As an aside, we may also create a couple of decorators to fill in
__annotations__ on Python 2, something like:

@return_annotation('A file obect')
@annotations(mode=(options('read','write'), str, 'The mode in which to open
the file'))
def my_io(filename, mode='read'):
    ...

[1] http://mail.scipy.org/pipermail/ipython-dev/2012-November/010697.html


Thanks,
Thomas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20121201/237f224c/attachment.html>


More information about the Python-ideas mailing list