[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