[Python-3000] Adaptation and type declarations

Jim Jewett jimjjewett at gmail.com
Tue Apr 11 20:58:08 CEST 2006


On 4/10/06, Guido van Rossum <guido at python.org> wrote:

> I don't want to assign *any* semantics to the type markers;

> ... I'd like to be able to have a decorator that
> requires the convention of using concrete types
> (e.g. list, int, file) as type markers; calling these
> would be a mistake, they should be used
> in isinstance() calls for example.

list is indeed a corner case, because of the copying.

To me, the answer is to instead create a similar List that doesn't
copy unless it has to.

    def List(val):  return val if isinstance(val, list) else list(val)

It would be nicer to use list directly, but I'm not sure it is worth
having to also add a decorator every time I use a type marker.  That
starts to look too much like boilerplate.

Alternatively, if you're assuming a decorator anyhow, then a decorator
for only-these-odd-cases could wrap the function with a different
signature and its own isinstance check.

> You're thinking of the type markers as adapters
> exclusively.

No, but I am saying that they should be constrained to be callables
which can be used as (possibly faulty) adapters.

> Several people (in a previous round of discussion)
> have agreed that they'd be totally happy if
> [the type annotations were ignored], so ...

    >>> def f(x: int):
    ...     print x*2
    >>> f("abc")
    'abcabc'

I think "satisfied" is more accurate that "totally happy".

That call is arguably an error, and there are certainly execution
contexts where it isn't worthwhile checking for errors.  I think the
same people would be just as happy if the call raised a TypeError
(particularly in debug mode).  In optimized mode, they might even be
willing to live with undefined results, to avoid the try-except
overhead.

What they don't want is for

(a)  Every type marker to be an annoyance to create,

particularly if

(b)  Every parameter has to be marked up (in a likely useless
fashion), because of style expectations imported from other languages.

So the fact that users might want any of:

    def MyType(val): return val  # no run-time overhead

    class MyType(RealType):     # copyless adapter
        def __new__(self, other):
            if isinstance(other, MyType):
                return other
            return RealType(other)

    def MyType(val):                   # checker
        if not isinstance(val, _MySecretType):
            raise TypeError("%s is not a MyType" % (val,))
        return val

shouldn't mean that type providers have to write all of the above.

Having to provide "a callable" isn't nearly so restrictive.  Even
meeting a full "type annotation API" isn't so bad, if inheritance lets
them mostly not bother.

-jJ


More information about the Python-3000 mailing list