title: Typing: declaring classmethod-like decorators
body: <p>mypy has the binding semantics for <code>@classmethod</code> baked into it (in fact from looking at the source code I believe it is hard-coded for <code>builtins.classmethod</code>) so this works:</p>
  <pre class="lang-py prettyprint-override"><code>from __future__ import annotations
  from typing import Any
  
  
  class Foo:
      def __init__(self, x: Any) -&gt; None:
          self.x = x
  
      @classmethod
      def create(cls, x: Any) -&gt; Foo:
          return cls(x)
  
  
  if __name__ == '__main__':
      foo = Foo.create(1)
      print(foo)
  </code></pre>
  <pre><code>$ mypy a0.py
  Success: no issues found in 1 source file
  </code></pre>
  <p>But say, for valid reasons, I have a decorator that has <code>classmethod</code>-like binding behavior on the first argument (expecting it to be a class).  To give a simple example that approximates <code>classmethod</code> itself:</p>
  <pre class="lang-py prettyprint-override"><code>class myclassmethod:
      def __init__(self, func):
          self.func = func
  
      def __get__(self, obj, cls):
          return partial(self.func, cls)
  
  
  class Foo:
      def __init__(self, x: Any) -&gt; None:
          self.x = x
  
      @myclassmethod
      def create(cls, x: Any) -&gt; Foo:
          return cls(x)
  </code></pre>
  <p>Unsurprisingly this does not check out; mypy assumes the first argument is bound to a <code>Foo</code> instance, and errors out at the call site of <code>cls(x)</code>:</p>
  <pre><code>$ mypy a1.py
  a1.py:20: error: &quot;Foo&quot; not callable
  </code></pre>
  <p>If I try to explicitly give the &quot;cls&quot; a type in contradicts the default <code>bind_self</code> behavior for instance methods:</p>
  <pre class="lang-py prettyprint-override"><code>class Foo:
      def __init__(self, x: Any) -&gt; None:
          self.x = x
  
      @myclassmethod
      def create(cls: Type[Foo], x: Any) -&gt; Foo:
          return cls(x)
  </code></pre>
  <pre><code>$ mypy a2.py 
  a2.py:19: error: The erased type of self &quot;Type[a2.Foo]&quot; is not a supertype of its class &quot;a2.Foo&quot;
  </code></pre>
  <p>The only workaround I've found is to not declare the type of <code>cls</code> in the signature, but instead to cast it at the call site:</p>
  <pre class="lang-py prettyprint-override"><code>class Foo:
      def __init__(self, x: Any) -&gt; None:
          self.x = x
  
      @myclassmethod
      def create(cls, x: Any) -&gt; Foo:
          return cast(Type[Foo], cls)(x)
  </code></pre>
  <p>This passes as far as type checking goes, but is a little inconvenient and error-prone since this will have to be done by any user of <code>@myclassmethod</code>.</p>
  <p>I see that there is a <code>is_classmethod</code> argument to mypy's <code>bind_self</code>, but this is really only applied in the <em>specific</em> case of functions decorated with <code>builtins.classmethod</code>.  Subclassing <code>classmethod</code> doesn't help either (I guess mypy is making the conservative assumption that a subclass of <code>classmethod</code> may have arbitrary behavior).</p>
  <p>I just wonder if there's a way, without digging deep into mypy internals, to explicitly override the self-binding behavior of functions that are arguments to a decorator.</p>