<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<br>
<br>
<div class="moz-cite-prefix">18.05.2015, 18:05, Guido van Rossum
kirjoitti:<br>
</div>
<blockquote
cite="mid:CAP7+vJK-s97bRPQ6nkV1ZN0FBhyND2Vw7OS_gUh6AoN4eibrAw@mail.gmail.com"
type="cite">
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">On Mon, May 18, 2015 at 12:14 AM,
Alex Grönholm <span dir="ltr"><<a moz-do-not-send="true"
href="mailto:alex.gronholm@nextday.fi" target="_blank">alex.gronholm@nextday.fi</a>></span>
wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div><span class=""> <br>
<br>
<div>18.05.2015, 02:50, Guido van Rossum kirjoitti:<br>
</div>
<blockquote type="cite">
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">On Sun, May 17, 2015 at
3:07 PM, Alex Grönholm <span dir="ltr"><<a
moz-do-not-send="true"
href="mailto:alex.gronholm@nextday.fi"
target="_blank">alex.gronholm@nextday.fi</a>></span>
wrote:<br>
<blockquote class="gmail_quote"
style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div bgcolor="#FFFFFF" text="#000000">
Looking at PEP 484, I came up with two use
cases that I felt were not catered for:<br>
<ol>
<li>Specifying that a parameter should
be a subclass of another (example:
Type[dict] would match dict or
OrderedDict; plain "Type" would equal
"type" from builtins)</li>
</ol>
</div>
</blockquote>
<div><br>
</div>
<div>I don't understand. What is "Type"? Can
you work this out in a full example? This
code is already okay:<br>
<br>
</div>
<div>def foo(a: dict):<br>
...<br>
<br>
</div>
<div>foo(OrderedDict())<br>
</div>
</div>
</div>
</div>
</blockquote>
</span> This code is passing an <i>instance</i> of
OrderedDict. But how can I specify that foo() accepts a
<i>subclass</i> of dict, and not an instance thereof?<br>
<br>
A full example:<br>
<br>
def foo(a: Type[dict]):<br>
...<br>
<br>
</div>
</blockquote>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div bgcolor="#FFFFFF" text="#000000"> foo(dict) # ok<br>
foo(OrderedDict) # ok<br>
foo({'x': 1}) # error<span class=""><br>
</span></div>
</blockquote>
<div><br>
</div>
<div>You want the argument to be a *class*. We currently
don't support that beyond using 'type' as the annotation.
We may get to this in a future version; it is relatively
uncommon. As to what notation to use, perhaps it would
make more sense to use Class and Class[dict], since in the
world of PEP 484, a class is a concrete thing that you can
instantiate, while a type is an abstraction used to
describe the possible values of a variable/argument/etc.<br>
<br>
Also, what you gave is still not a full example, since you
don't show what you are going to do with that type. Not
every class can be easily instantiated (without knowing
the specific signature). So if you were planning to
instantiate it, perhaps you should use Callable[..., dict]
as the type instead. (The ellipsis is not yet supported by
mypy -- <a moz-do-not-send="true"
href="https://github.com/JukkaL/mypy/issues/393">https://github.com/JukkaL/mypy/issues/393</a>
-- but it is allowed by the PEP.)<br>
</div>
</div>
</div>
</div>
</blockquote>
Here's one example, straight from the code of my new framework:<br>
<tt><br>
</tt>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<tt>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
@typechecked<br>
def register_extension_type(ext_type: str, extension_class: type,
replace: bool=False):</tt><tt><br>
</tt>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<tt> """</tt><tt><br>
</tt><tt> Adds a new extension type that can be used with a
dictionary based configuration.</tt><tt><br>
</tt><tt><br>
</tt><tt> :param ext_type: the extension type identifier</tt><tt><br>
</tt><tt> :param extension_class: a class that implements
IExtension</tt><tt><br>
</tt><tt> :param replace: ``True`` to replace an existing type</tt><tt><br>
</tt><tt> """</tt><tt><br>
</tt><tt><br>
</tt><tt> assert_subclass('extension_class', extension_class,
IExtension)</tt><tt><br>
</tt><tt> if ext_type in extension_types and not replace:</tt><tt><br>
</tt><tt> raise ValueError('Extension type "{}" already
exists'.format(ext_type))</tt><tt><br>
</tt><tt><br>
</tt><tt> extension_types[ext_type] = extension_class</tt><tt><br>
</tt><br>
I would like to declare the second argument as "extension_class:
Type[IExtension]" (or Class[IExtension], doesn't matter to me).
Likewise, the type hint for "extension_types" should be "Dict[str,
Type[IExtension]]".<br>
<blockquote
cite="mid:CAP7+vJK-s97bRPQ6nkV1ZN0FBhyND2Vw7OS_gUh6AoN4eibrAw@mail.gmail.com"
type="cite">
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">
<div> </div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div bgcolor="#FFFFFF" text="#000000"><span class="">
<blockquote type="cite">
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">
<div> </div>
<blockquote class="gmail_quote"
style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div bgcolor="#FFFFFF" text="#000000">
<ol>
<li>Specifying that a callable should
take at least the specified arguments
but would not be limited to them:
Callable[[str, int, ...], Any]</li>
</ol>
<p>Case #2 works already (Callable[[str,
int], Any] if the unspecified arguments
are optional, but not if they're
mandatory. Any thoughts?<br>
</p>
</div>
</blockquote>
<div>For #2 we explicitly debated this and
found that there aren't use cases known that
are strong enough to need additional
flexibility in the args of a callable. (How
is the code calling the callable going to
know what arguments are safe to pass?) If
there really is a need we can address in a
future revision.<br>
</div>
</div>
</div>
</div>
</blockquote>
</span> Consider a framework where a request handler
always takes a Request object as its first argument, but
the rest of the arguments could be anything. If you want
to only allow registration of such callables, you could
do this:<br>
<br>
def calculate_sum(request: Request, *values):<br>
return sum(values)<br>
<br>
def register_request_handler(handler: Callable[[Request,
...], Any]):<br>
... <span class=""></span></div>
</blockquote>
<div><br>
</div>
<div>Hm... Yeah, you'd be stuck with using Callable[...,
Any] for now. Maybe in a future version of the PEP. (We
can't boil the ocean of typing in one PEP. :-) <br>
</div>
</div>
<br>
-- <br>
<div class="gmail_signature">--Guido van Rossum (<a
moz-do-not-send="true" href="http://python.org/%7Eguido"
target="_blank">python.org/~guido</a>)</div>
</div>
</div>
</blockquote>
<br>
</body>
</html>