[Python-3000] Draft pre-PEP: function annotations

Talin talin at acm.org
Sat Aug 12 00:39:56 CEST 2006

Josiah Carlson wrote:
> "Phillip J. Eby" <pje at telecommunity.com> wrote:
>> At 06:10 AM 8/11/2006 -0700, Talin <talin at acm.org> wrote:
>>> Or to put it another way: If you create a tool, and you assume that tool
>>> will only be used in certain specific ways, but you fail to enforce that
>>> limitation, then your assumption will be dead wrong. The idea that there
>>> will only be a few type annotation providers who will all nicely
>>> cooperate with one another is just as naive as I was in the SysEx debacle.
>> Are you saying that function annotations are a bad idea because we won't be 
>> able to pickle them?
> That is not what I got out of the message at all.
>> If not, your entire argument seems specious.  Actually, even if that *is* 
>> your argument, it's specious, since all that's needed to support pickling 
>> is to support pickling.  All that's needed to support printing is to 
>> support printing (via __str__), and so on.
> I think you misunderstood Talin.  While it was a pain for him to work
> his way through implementing all of the loading/etc. protocols, I
> believe his point was that if we allow any and all arbitrary metadata to
> be placed on arguments to and from functions, then invariably there will
> be multiple methods of doing as much.  That isn't a problem unto itself,
> but when there ends up being multiple metadata formats, with multiple
> interpretations of them, and a user decides that they want to combine
> the functionality of two metadata formats, they may be stuck due to
> incompatibilities, etc.
> I think that it can be fixed by defining a standard mechanism for
> 'metadata chaining', one involving tuples and/or dictionaries.
> Say, for example, we have the following function definition:
>     def foo(argn:meta=dflt):
>         ...
> Since meta can take on the value of a Python expression (executed during
> compile-time), a tuple-based chaining would work like so:
>     @chainmetadatatuple(meta_fcn1, meta_fcn2)
>     def foo(argn:(meta1, meta2)=dflt):
>         ...
> And a dictionary-based chaining would work like so:
>     @chainmetadatadict(m1=meta_fcn1, m2=meta_fcn2)
>     def foo(argn:{'m1'=meta1, 'm2'=meta2}=dflt):
>         ...
> The reason to include the dict-based option is to allow for annotations
> to be optional.
> This method may or may not be good.  But, if we don't define a standard
> method for metadata to be combined from multiple protocols, etc., then
> we could end up with incompatabilities.  However, if we do define a
> standard chaining mechanism, then it can be used, and presumably
> we shouldn't run into problems relating to incompatible annotation, etc.
>  - Josiah

Josiah is essentially correct in his interpretation of my views. I 
really don't understand what Phillip is talking about here.

Say I want to annotate a specific argument with two pieces of 
information, a type and a docstring. I have two metadata interpreters, 
one which uses the type information to restrict the kinds of arguments 
that can be passed in, and another which uses the docstring to enhance 
the generated documentation.

Now, lets say that these two metadata interpreters were written by two 
people, who are not in communication with each other. Each one decides 
that they would like to "play nice" with other competing metadata.

So Author A, who wrote the annotation decorator that looks for 
docstrings, decides that not only will he accept docstring annotations, 
but if the annotation is a tuple, then he will search that tuple for any 
docstrings, skipping over any annotations that he doesn't understand. 
(Although how he is supposed to manage that is unclear - since there 
could also be other annotations that are simple text strings as well.)

Author B, who wrote the type-enforcement module, also wants to play nice 
with others, but since he doesn't know A, comes up with a different 
solution. His idea is to create a system in which annotations 
automatically chain each other - so that each annotation has a "next" 
attribute referring to the next annotation.

So programmer C, who wants to incorporate both A and B's work into his 
program, has a dilemma - each has a sharing mechanism, but the sharing 
mechanisms are different and incompatible. So he is unable to apply both 
A-type and B-type metadata to any given signature.

What happens next is that C complains to both A and B (and in the 
process introducing them to each other.) A and B exchange emails, and 
reach the conclusion that B will modify his library to confirm to the 
sharing mechanism of A.

What this means is that A and B have created a defacto standard. Anyone 
who wants to interoperate with A and B have to write their interpreter 
to conform to the sharing mechanism defined by A and B.

But it also means that anyone outside of the ABC clique will not know 
about A&B's sharing convention, which means that their metadata 
interpreter will not be able to interoperate with A&B-style metadata. So 
in essence, A&B have now "captured" the space of annotations - that is, 
anyone who conforms to the A&B protocol can combine their annotations 
together; Anyone outside that group is excluded from interoperating.

Finally, lets say that A&B eventually become well-known enough that 
their sharing convention becomes the defacto standard. Any metadata that 
wants to interoperate with other metadata-interpretation libraries will 
have to follow the A&B convention. Any metadata library that chooses to 
use a different convention will be at a severe disadvantage, since they 
won't be able to be used together with other metadata interpreters.

What this means is that, despite the statements that annotations have no 
defined format or meaning, the fact is that they now do: The defacto A&B 
sharing convention. The sharing convention tells metadata interpreters 
how to distinguish between metadata that they can interpret, and how to 
skip over other metadata.

So in other words, since the original author of the annotation system 
failed to provide a convention for multiple annotations, they force the 
community to fill in the parts of the standard that they left out.

-- Talin

More information about the Python-3000 mailing list