title: Static methods and designing for inheritance
body: <p>I am unclear on what is the best way to design a class with static methods that are meant to be overridable.  I will try to explain with an example.</p>
  
  <hr>
  
  <p>We have a class <code>Goat</code> with a method <code>can_climb</code>.  (By the way this is Python 3, in Python 2 I would write <code>class Goat(object):</code>.)</p>
  
  <pre><code>class Goat:
      def __init__(self, *args):
          ...
  
      def can_climb(self, mountain):
          return mountain.steepness &lt; 10
  
  billy = Goat("Billy")
  if billy.can_climb(mount_everest):
      print("wow Billy, impressive")
  </code></pre>
  
  <p>This works as intended, but the method <code>can_climb</code> doesn't use <code>self</code>.  It seems cleaner to make it a static method, and pylint even gives a warning for the above method. So let's change that:</p>
  
  <pre><code>class Goat:
      def __init__(self, *args):
          ...
  
      @staticmethod
      def can_climb(mountain):
          return mountain.steepness &lt; 10
  
  billy = Goat("Billy")
  if billy.can_climb(mount_everest):
      print("wow Billy, impressive")
  </code></pre>
  
  <p><code>billy.can_climb</code> near the end can instead be <code>Goat.can_climb</code> and it won't make a difference in this example.  Some people might even see it as being clearer and more direct to call a static method via its class and not an instance.</p>
  
  <p>However, this leads to a subtle error when we use inheritance and polymorphism is introduced:</p>
  
  <pre><code>class Goat:
      def __init__(self, *args):
          ...
  
      @staticmethod
      def can_climb(mountain):
          return mountain.steepness &lt; 10
  
  class MountaineeringGoat(Goat):
      @staticmethod
      def can_climb(mountain):
          return True
  
  billy = get_ourselves_a_goat_called_billy()
  if Goat.can_climb(mount_everest):     # bug
      print("wow Billy, impressive")
  </code></pre>
  
  <p>The code that calls <code>Goat.can_climb</code> knows that <code>billy</code> is an instance of <code>Goat</code> and makes the erroneous assumption that its type is <code>Goat</code>, when it could really be any subtype of <code>Goat</code>.  Or maybe it incorrectly assumes that subclasses won't override a static method.</p>
  
  <p>This seems to me like an easy mistake to make; perhaps <code>Goat</code> didn't have any subclasses at the time this bug was introduced, so the bug was not noticed.</p>
  
  <hr>
  
  <p>How can we design and document a class so that this sort of bug is avoided?  In particular, should <code>can_climb</code> from this example be a static method or should something else be used instead?</p>