473,714 Members | 2,530 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

PEP 3107 Function Annotations for review and comment

(Note: PEPs in the 3xxx number range are intended for Python 3000)

PEP: 3107
Title: Function Annotations
Version: $Revision: 53169 $
Last-Modified: $Date: 2006-12-27 20:59:16 -0800 (Wed, 27 Dec 2006) $
Author: Collin Winter <co*****@gmail. com>,
Tony Lownds <to**@lownds.co m>
Status: Draft
Type: Standards Track
Requires: 362
Content-Type: text/x-rst
Created: 2-Dec-2006
Python-Version: 3.0
Post-History:
Abstract
========

This PEP introduces a syntax for adding arbitrary metadata annotations
to Python functions [#functerm]_.
Rationale
=========

Because Python's 2.x series lacks a standard way of annotating a
function's parameters and return values (e.g., with information about
what type a function's return value should be), a variety of tools
and libraries have appeared to fill this gap [#tailexamp]_. Some
utilise the decorators introduced in "PEP 318", while others parse a
function's docstring, looking for annotations there.

This PEP aims to provide a single, standard way of specifying this
information, reducing the confusion caused by the wide variation in
mechanism and syntax that has existed until this point.
Fundamentals of Function Annotations
=============== =============== ======

Before launching into a discussion of the precise ins and outs of
Python 3.0's function annotations, let's first talk broadly about
what annotations are and are not:

1. Function annotations, both for parameters and return values, are
completely optional.

2. Function annotations are nothing more than a way of associating
arbitrary Python expressions with various parts of a function at
compile-time.

By itself, Python does not attach any particular meaning or
significance to annotations. Left to its own, Python simply makes
these expressions available as described in `Accessing Function
Annotations`_ below.

The only way that annotations take on meaning is when they are
interpreted by third-party libraries. These annotation consumers
can do anything they want with a function's annotations. For
example, one library might use string-based annotations to provide
improved help messages, like so::

def compile(source: "something compilable",
filename: "where the compilable thing comes from",
mode: "is this a single statement or a suite?"):
...

Another library might be used to provide typechecking for Python
functions and methods. This library could use annotations to
indicate the function's expected input and return types, possibly
something like::

def haul(item: Haulable, *vargs: PackAnimal) -Distance:
...

However, neither the strings in the first example nor the
type information in the second example have any meaning on their
own; meaning comes from third-party libraries alone.

3. Following from point 2, this PEP makes no attempt to introduce
any kind of standard semantics, even for the built-in types.
This work will be left to third-party libraries.

There is no worry that these libraries will assign semantics at
random, or that a variety of libraries will appear, each with
varying semantics and interpretations of what, say, a tuple of
strings means. The difficulty inherent in writing annotation
interpreting libraries will keep their number low and their
authorship in the hands of people who, frankly, know what they're
doing.
Syntax
======

Parameters
----------

Annotations for parameters take the form of optional expressions that
follow the parameter name. This example indicates that parameters
'a' and 'c' should both be an ``int``, while parameter 'b' should
be a ``dict``::

def foo(a: int, b: dict, c: int = 5):
...

In pseudo-grammar, parameters now look like ``identifier [:
expression] [= expression]``. That is, annotations always precede a
parameter's default value and both annotations and default values are
optional. Just like how equal signs are used to indicate a default
value, colons are used to mark annotations. All annotation
expressions are evaluated when the function definition is executed.

Annotations for excess parameters (i.e., ``*args`` and ``**kwargs``)
are indicated similarly. In the following function definition,
``*args`` is flagged as a tuple of ``int``, and ``**kwargs`` is
marked as a dict whose keys are strings and whose values are of type
``str``::

def foo(*args: int, **kwargs: str):
...

Note that, depending on what annotation-interpreting library you're
using, the following might also be a valid spelling of the above::

def foo(*args: [int], **kwargs: {str: str}):
...

Only the first, however, has the BDFL's blessing [#blessedexcess]_ as
the One Obvious Way.
Return Values
-------------

The examples thus far have omitted examples of how to annotate the
type of a function's return value. This is done like so::

def sum(*args: int) -int:
...

The parameter list can now be followed by a literal ``->`` and a
Python expression. Like the annotations for parameters, this
expression will be evaluated when the function definition is executed.

The grammar for function definitions [#grammar]_ is now::

decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
decorators: decorator+
funcdef: [decorators] 'def' NAME parameters ['->' test] ':' suite
parameters: '(' [typedargslist] ')'
typedargslist: ((tfpdef ['=' test] ',')*
('*' [tname] (',' tname ['=' test])* [',' '**'
tname]
| '**' tname)
| tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
tname: NAME [':' test]
tfpdef: tname | '(' tfplist ')'
tfplist: tfpdef (',' tfpdef)* [',']

Lambda
------

``lambda``'s syntax does not support annotations. The syntax of
``lambda`` could be changed to support annotations, by requiring
parentheses around the parameter list. However it was decided
[#lambda]_ not to make this change because:

1. It would be an incompatible change.
2. Lambda's are neutered anyway.
3. The lambda can always be changed to a function.
Accessing Function Annotations
=============== ===============

Once compiled, a function's annotations are available via the
function's ``func_annotati ons`` attribute. This attribute is
a dictionary, mapping parameter names to an object representing
the evaluated annotation expression

There is a special key in the ``func_annotati ons`` mapping,
``"return"``. This key is present only if an annotation was supplied
for the function's return value.

For example, the following annotation::

def foo(a: 'x', b: 5 + 6, c: list) -str:
...

would result in a ``func_annotati on`` mapping of ::

{'a': 'x',
'b': 11,
'c': list,
'return': str}

The ``return`` key was chosen because it cannot conflict with the name
of a parameter; any attempt to use ``return`` as a parameter name
would result in a ``SyntaxError`` .

``func_annotati ons`` is an empty dictionary if no there are no
annotations on the function. ``func_annotati ons`` is always an empty
dictionary for functions created from ``lambda`` expressions.
Standard Library
=============== =

pydoc and inspect
-----------------

The ``pydoc`` module should display the function annotations when
displaying help for a function. The ``inspect`` module should change
to support annotations.
Relation to Other PEPs
=============== =======

Function Signature Objects [#pep-362]_
--------------------------------------

Function Signature Objects should expose the function's annotations.
The ``Parameter`` object may change or other changes may be warranted.
Implementation
==============

A sample implementation for the syntax changes has been provided
[#implementation]_ by Tony Lownds.
Rejected Proposals
=============== ===

+ The BDFL rejected the author's idea for a special syntax for adding
annotations to generators as being "too ugly" [#rejectgensyn]_.

+ Though discussed early on ([#threadgen]_, [#threadhof]_), including
special objects in the stdlib for annotating generator functions and
higher-order functions was ultimately rejected as being more
appropriate for third-party libraries; including them in the
standard library raised too many thorny issues.

+ Despite considerable discussion about a standard type
parameterisatio n syntax, it was decided that this should also be
left to third-party libraries. ([#threadimmlist]_,
[#threadmixing]_, [#emphasistpls]_)
References and Footnotes
=============== =========

... [#functerm] Unless specifically stated, "function" is generally
used as a synonym for "callable" throughout this document.

... [#tailexamp] The author's typecheck_ library makes use of
decorators, while `Maxime Bourget's own typechecker`_ utilises
parsed docstrings.

... [#blessedexcess]
http://mail.python.org/pipermail/pyt...ay/002173.html

... [#rejectgensyn]
http://mail.python.org/pipermail/pyt...ay/002103.html

... _typecheck:
http://oakwinter.com/code/typecheck/

... _Maxime Bourget's own typechecker:
http://maxrepo.info/taxonomy/term/3,6/all

... [#threadgen]
http://mail.python.org/pipermail/pyt...ay/002091.html

... [#threadhof]
http://mail.python.org/pipermail/pyt...ay/001972.html

... [#threadimmlist]
http://mail.python.org/pipermail/pyt...ay/002105.html

... [#threadmixing]
http://mail.python.org/pipermail/pyt...ay/002209.html

... [#emphasistpls]
http://mail.python.org/pipermail/pyt...ne/002438.html

... [#implementation]
http://python.org/sf/1607548

... _numeric:
http://docs.python.org/lib/typesnumeric.html

... _mapping:
http://docs.python.org/lib/typesmapping.html

... _sequence protocols:
http://docs.python.org/lib/typesseq.html

... [#grammar]
http://www.python.org/doc/current/ref/function.html

... [#lambda]
http://mail.python.org/pipermail/pyt...ay/001613.html

... [#pep-362]
http://www.python.org/dev/peps/pep-0362/

Copyright
=========

This document has been placed in the public domain.

...
Local Variables:
mode: indented-text
indent-tabs-mode: nil
sentence-end-double-space: t
fill-column: 70
coding: utf-8
End:

Dec 29 '06 #1
4 2491
I have two questions:

1) I don't understand the clause ('*' [tname] (',' tname ['=' test])*
in the grammar rule of typedargslist. Does it stem from another PEP?

2) Is the func_annotation information for def foo(*c: list)
stored as {"*c": list} preserving optional argument information or
{"c":list} ?

Regards,
Kay

Dec 31 '06 #2

On Dec 31, 2006, at 4:26 AM, Kay Schluehr wrote:
I have two questions:

1) I don't understand the clause ('*' [tname] (',' tname ['=' test])*
in the grammar rule of typedargslist. Does it stem from another PEP?
Yes, PEP 3102 Keyword-only Arguments.
2) Is the func_annotation information for def foo(*c: list)
stored as {"*c": list} preserving optional argument information or
{"c":list} ?
{"c": list}

-Tony


Dec 31 '06 #3
Tony Lownds wrote:
On Dec 31, 2006, at 4:26 AM, Kay Schluehr wrote:
I have two questions:

1) I don't understand the clause ('*' [tname] (',' tname ['=' test])*
in the grammar rule of typedargslist. Does it stem from another PEP?

Yes, PEP 3102 Keyword-only Arguments.
2) Is the func_annotation information for def foo(*c: list)
stored as {"*c": list} preserving optional argument information or
{"c":list} ?

{"c": list}

-Tony
Good. There is still one issue. I understand that you don't want to fix
the semantics of function annotations but to be usefull some
annotations are needed to express function types. Using those
consistently with the notation of the enhanced function statement I
suggest introducing an arrow expression and an __arrow__ special
function:

expr: arrow_expr ('->' arrow_expr)*
arrow_expr: xor_expr ('|' xor_expr)*
....

class Algebraic(type) :
'''
Metaclass used to enable operations on classes or subclasses
'''
def __init__(cls, name, bases, dict):
super(Algebraic , cls).__init__(n ame, bases, dict)

def __arrow__(cls, codom):
fntype = Function(*cls.d om)
fntype.codom = codom
return fntype

def Function(*domai ns):
"Function type generator"
class FunType:
__metaclass__ = Algebraic
dom = domains
codom = ()
return FunType

maptype = Function( Function(object )->object, list) -list

Jan 1 '07 #4

On Jan 1, 2007, at 9:48 AM, Kay Schluehr wrote:
Good. There is still one issue. I understand that you don't want to
fix
the semantics of function annotations but to be usefull some
annotations are needed to express function types. Using those
consistently with the notation of the enhanced function statement I
suggest introducing an arrow expression and an __arrow__ special
function:

expr: arrow_expr ('->' arrow_expr)*
arrow_expr: xor_expr ('|' xor_expr)*
I agree with the use case and I am in favor of this addition despite the
drawbacks below. While overloading __eq__ is a decent alternative,
the -operator is so much nicer (IMO).

The precedence seems right:

Function(A) -B | C <= Function(A) -(B | C)

Most operators special method names refer to the action or operation
rather that the symbol, eg __or__, not __vbar__. Also, since the
token is
called RARROW, __arrow__ / __rarrow__ would be potentially easy to
mix up.

There might be opposition to adding an operator whose meaning in C
is very different. Also the operator as suggested does not have any
meaning
on any built in objects, which is odd. We could add a meaning for
ints/bools:

http://mathworld.wolfram.com/Implies.html

If that is reasonable I would suggest calling the special method
__implies__
and putting the slot on PyNumberMethods . If that's just silly, I
suggest calling
the special method __returns__.

We'll see what others say :) Thanks for the suggestion!

-Tony
Jan 1 '07 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
1724
by: Philipp Lenssen | last post by:
I want to do the following (and I suspect the easiest way to be a regular expression that uses a user-function): Given the string... -------- <p>Hello</p> <p class="bla">World</p> <h3>Hello User</h3>
8
1417
by: Johno | last post by:
I have written the two associated base classes below (Digital_camera and Review) to manage digital camera and review objects. They are base classes for which other derived classes can be written to provide more detail. You'll notice that I've also declared the display functions as "virtual" to allow for polymorphism. I now need to write a function to display all the contents of an STL "deque" of pointers to Digital_camera objects. It needs...
17
2422
by: strout | last post by:
function F(e) { return function(){P(e)} } Can anybody tell me what the code is doing? If return another function all in a function I would do function F(e)
0
1302
by: Marcus Hartley | last post by:
I'm looking for a pre-built MS Access application that will track public review comments on large, often controversial documents, such as environmental impact statements. The comments need to contained in the application with senders contact information. Each sender needs and ID number, Each comment needs an ID number, each section of the comment needs to be associated with a Comment Issue. Comment Issues are built by the user and are...
19
872
by: sabarish | last post by:
Hi friend, what is the use of function pointer in c language and where it is useful? tell with simple example...? plz help me.
38
15961
by: Steve Kirsch | last post by:
I need a simple function that can match the number of beginning and ending parenthesis in an expression. Here's a sample expression: ( ( "john" ) and ( "jane" ) and ( "joe" ) ) Does .NET have something built-in that can accomplish this, or do I have to write my own parser? I don't want to reinvent the wheel if possible.
8
2794
by: oripel | last post by:
Hi, I'm trying to attach some attributes to functions and methods, similar to Java annotations and .NET attributes. I also want to use a convenient decorator for it, something along the lines of @attr(name="xander", age=10) def foo(): ...
38
2588
by: britzkrieg | last post by:
Hi, I had write a program for Windows OS and put the following line: system("pause") that use the "pause" command from DOS to pause the screen until I push a button. How to get the same result in Linux's bash ? thanks a lot
17
1741
by: Christoph Zwerschke | last post by:
I'm just reading PEP 3107 (function annotations) and wonder why exceptions are not mentioned there. I think it would be helpful if one could specify which exceptions can be raised by a function, similarly to how it is possible in C++ using the "throw" clause. The syntax would be something like this: def foo(a: expr, b: expr = 5) raises expr -expr: The expr in that "raises" clause should be a list of Exceptions.
0
8802
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8711
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9314
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9075
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9017
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7953
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5948
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
2
2522
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2111
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.