[Python-ideas] Proposal: Use mypy syntax for function annotations

Dennis Brakhane brakhane at googlemail.com
Thu Aug 14 21:28:11 CEST 2014


Allow me to chime in.

Am 13.08.2014 22:19, schrieb Guido van Rossum:
> On Wed, Aug 13, 2014 at 12:59 PM, Ethan Furman <ethan at stoneleaf.us
> <mailto:ethan at stoneleaf.us>> wrote:
>
> -1 on deprecating alternative uses of annotations.
>
>
> Do you have a favorite alternative annotation use that you actually
> use (or are likely to)?
>
I would be very sad to see annotations being limited to convey type
information. But I think I have a solution that
will make all happy (see end of mail)


I've programmed Java web application for many years now (hoping to
finally switch to Python), and "method parameter
annotations" as they are called in Java would be one thing I'd really
miss, as they can be very useful.

Let me give you two examples:

1. Annotations can be used to communicate additional restrictions on
values that must be checked on run time

Let's assume a simple Web service that is called via HTTP to register a
user, and the underlying framework decodes
the request and finally calls a simple controller function, it could
look like this

(Java code, @ signifies an annotation)

  public Response register(@Range(18,100) int age, @ValidEmail String
email) { ... }

The framework would check the range of the age parameter and the
validity of the email and if there are validation errors,
refusing the request with a suitable error message without ever calling
our function.

Even if we assume that mypy's type system will be incredibly complex and
allowing to specify all kinds of restrictions on a type,
it won't help because those checks have to be done at run time, and are
not optional.

Of course those checks could be hard coded into the function, but using
annotation also provides a simple and immediate
documentation about the allowed values, and avoids boilerplate (I do not
have to write
"if (emailNotvalie(email) throw ValidationError("Field email is not a
valid email")"  in every method that uses an email)


2. They can give meta information to a framework

An admittedly contrieved example, let's expand our register function:

public Response register( int age, @Inject @Scope("session") UserService
userService, @Authenticated User user) ....

Here I can tell the dependency injection framework that I want an
instance of the UserService injected, but one instance
that has session scope instead of the normal "singleton" scope.
I also ask the framework to inject me the currently authenticated user
object (let's assume if I'd write
"@Authenticated String user" I could get the login name as string etc.)


The flexibility annotations give in Java makes programming much less
frustrating. It also took quite some time before
annotations were widly used (they were only available starting in Java
5) and people started finding more uses for them.
I think this will also be true for Python, it will take time before
people find useful ways for them. Redefining them now to
be "not much more" than static type information feels wrong to me.


My proposed solution:

If an annotation is a tuple, mypy will take a look at each item and do
it's usual thing. If it doesn't recognise an item, it is skipped.

Every framework that uses annotations should also iterate over entries
of a tuple to find the ones it is interested in.

This also allows more than one annotation at a time, and is completely
backwards compatible (as far as Python itself is concerned)


for example, my first example could be written as

  def register(age: (int, range(18,100)), email: (str, ValidEmail))

also, it will allow me to add annotations to existing "typed" functions,

  def foo(bar: int) -> int

could become

  def foo(bar: (int, MyAnnotation)) -> (int, AnotherOfMyAnnotations)

I'm not sure what should happen if two conflicting types are given, like
(int, str); I think it should be treated as a union
type (either int or str).

-- 
Dennis


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 834 bytes
Desc: OpenPGP digital signature
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20140814/0d7d284f/attachment.sig>


More information about the Python-ideas mailing list