<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>