[Python-ideas] Improving the expressivity of function annotations

Masklinn masklinn at masklinn.net
Mon Apr 4 11:56:12 CEST 2011


On 2011-04-04, at 11:02 , Carl M. Johnson wrote:
> On Sun, Apr 3, 2011 at 10:49 PM, Masklinn <masklinn at masklinn.net> wrote:
> 
>> The "issue" is roughly the same as for abcs, in that you still have to give a name (and pre-define a type) for something which may not warrant it, and this naming may even serve to muddy the water some cases when used in type signatures (see Mapping abc example)
>> 
>> Otherwise, sure.
> 
> I guess I'm not getting it then. What's the alternative? We can either
> a) make up an ABC ourselves b) have a prefilled library of ABCs and
> pick one off the shelf or c) not use ABCs at all. In the case that
> something doesn't "warrant" an ABC, then just pick c. In fact, some
> people believe that we should always pick c to be more Pythonic and
> duck type-ish.
> 
> Or am I missing an option? I suppose there could be a factory of some
> sort to make new ABCs based on existing ABCs already in some sort of
> library… Is that what you're proposing?

The problem of option C and not using ABCs (which is indeed what I'm interested in) is that you then lose the possibility to type the object. If you're not using ABCs and you're not using concrete nominative types (e.g. ``dict``, ``list`` or a custom type) what are you left with?

As far as I can tell, nothing, and that's the hole I think needs plugging in the third part of the initial mail.

On 2011-04-04, at 11:09 , Carl M. Johnson wrote:
> OK, reading this again, maybe you mean something more like a Java interface?
> 
> @interface
> class Writer:
>     def write(output: bytes) -> None:
>     "Takes in bytes, returns None. Raises Foo on error."
>     pass
> 
> class DuckWriter(Writer):
>    def write(output):
>       #do something
>        return 1
> 
> d = DuckWriter()
> d.write("hello") #Raises TypeError, output must be bytes
> d.write(b"hello") #Raises TypeError, return type must be NoneType

Yes in that the signature of the methods would be part of the type, no in that the "link" should be implicit (structural) not explicit (nominative).

Your example does not show anything as it would be a function annotation (not a type annotation), but making it write to a file-like object would work: what I'd like is something along those lines (ignore the notation for now)

class Foo:
    def write_to(stream: < write(bytes) -> None >):
        # stuff

class StringWriter:
    def write(output: str) -> None
        # stuff
class BytesWriter:
    def write(output: bytes) -> None
        # stuff

d = DuckWriter()
d.write_to(StringWriter()) -> TypeError, not a structural subtype of what write_to needs
d.write_to(BytesWriter()) -> OK

On 2011-04-04, at 11:17 , Carl M. Johnson wrote:
> On Sun, Apr 3, 2011 at 11:09 PM, Carl M. Johnson <
> cmjohnson.mailinglist at gmail.com> wrote:
>> OK, reading this again, maybe you mean something more like a Java
>> interface?
> 
> Thinking about it a little more (It's bedtime in my timezone! That's my
> excuse!), I think there are two separate things that might be nice to have.
> One is an easy way to declare Go-style duck typing interfaces, the other is
> an easy way to declare Java-style type checking interfaces. I suppose there
> could be two class decorators. Call the first one "interface" and the second
> one "typechecking". Interface makes things reply to issubclass with True so
> long as they have the same methods and parameters. Typechecking creates a
> new class that will raise an error if anything trying to subclass it fails
> to use the proper types for input and output.
> 
> Do those sounds like useful decorators/metaclasses to have?

Maybe, but that's not the scope I'm considering at all, I'm only talking about function annotations.


More information about the Python-ideas mailing list