<div dir="ltr"><div>Can you add your example to the issue? <a href="https://github.com/ambv/typehinting/issues/107">https://github.com/ambv/typehinting/issues/107</a><br><br></div>We're trying to finish up PEP 484 in the next few days (wait for an announcement :-) and we just don't have time for every use case; but over the course of 3.5 we will be adding features that are considered useful, and we'll keep the issue open to remind us of it. Until then you'll have to use plain "type" as the annotation (still better than "Any". :-)<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, May 18, 2015 at 11:01 AM, Alex Grönholm <span dir="ltr"><<a href="mailto:alex.gronholm@nextday.fi" target="_blank">alex.gronholm@nextday.fi</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  
    
  
  <div bgcolor="#FFFFFF" text="#000000"><span class="">
    <br>
    <br>
    <div>18.05.2015, 18:05, Guido van Rossum
      kirjoitti:<br>
    </div>
    <blockquote 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 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> <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 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><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 href="https://github.com/JukkaL/mypy/issues/393" target="_blank">https://github.com/JukkaL/mypy/issues/393</a>
              -- but it is allowed by the PEP.)<br>
            </div>
          </div>
        </div>
      </div>
    </blockquote></span>
    Here's one example, straight from the code of my new framework:<br>
    <tt><br>
    </tt>
    
    <tt>
      
      @typechecked<br>
      def register_extension_type(ext_type: str, extension_class: type,
      replace: bool=False):</tt><tt><br>
    </tt>
    
    <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]]".<span class=""><br>
    <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"><span>
                  <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></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>--Guido van Rossum (<a href="http://python.org/%7Eguido" target="_blank">python.org/~guido</a>)</div>
        </div>
      </div>
    </blockquote>
    <br>
  </span></div>

<br>_______________________________________________<br>
Python-Dev mailing list<br>
<a href="mailto:Python-Dev@python.org">Python-Dev@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-dev" target="_blank">https://mail.python.org/mailman/listinfo/python-dev</a><br>
Unsubscribe: <a href="https://mail.python.org/mailman/options/python-dev/guido%40python.org" target="_blank">https://mail.python.org/mailman/options/python-dev/guido%40python.org</a><br>
<br></blockquote></div><br><br clear="all"><br>-- <br><div class="gmail_signature">--Guido van Rossum (<a href="http://python.org/~guido" target="_blank">python.org/~guido</a>)</div>
</div>