title: boost::python: How can I override a static property?
body: <p>I have a base class and a derived class, both of which have an identically named static method. Is it possible to expose both of them while keeping the names the same? This compiles, but throws an exception upon import of the module.</p>
  
  <pre><code>struct Base
  {
      static std::string say_hi() { return "Hi"; }
  };
  
  struct Derived : public Base
  {
      static std::string say_hi() { return "Hello"; }
  };
  
  BOOST_PYTHON_MODULE(HelloBoostPython)
  {
      namespace py = boost::python;
  
      py::class_&lt;Base&gt;("Base").add_static_property("say_hi", &amp;Base::say_hi);
  
      py::class_&lt;Derived, py::bases&lt;Base&gt;&gt;("Derived").add_static_property("say_hi", &amp;Derived::say_hi);
  }
  </code></pre>
  
  <p>Upon import:</p>
  
  <pre><code>&gt;&gt;&gt; import HelloBoostPython
  Traceback (most recent call last):
    File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  SystemError: initialization of HelloBoostPython raised unreported exception
  </code></pre>
  
  <p>Changing the last line to a different name works, but I'd rather have the base class's property be overridden:</p>
  
  <pre><code>py::class_&lt;Derived, py::bases&lt;Base&gt;&gt;("Derived").add_static_property("say_hello", &amp;Derived::say_hi);
  </code></pre>
  
  <p>This works, but I get class methods instead of properties:</p>
  
  <pre><code>BOOST_PYTHON_MODULE(HelloBoostPython)
  {
      namespace py = boost::python;
  
      py::object base = py::class_&lt;Base&gt;("Base");
      base.attr("say_hi") = Base::say_hi;
  
      py::object derived = py::class_&lt;Derived, py::bases&lt;Base&gt;&gt;("Derived");
      derived.attr("say_hi") = Derived::say_hi;
  }
  </code></pre>
  
  <p>This will give me properties but won't work in the general case if the static methods aren't constant:</p>
  
  <pre><code>BOOST_PYTHON_MODULE(HelloBoostPython)
  {
      namespace py = boost::python;
  
      py::object base = py::class_&lt;Base&gt;("Base");
      base.attr("say_hi") = Base::say_hi();
  
      py::object derived = py::class_&lt;Derived, py::bases&lt;Base&gt;&gt;("Derived");
      derived.attr("say_hi") = Derived::say_hi();
  }
  </code></pre>
  
  <p>Hmm</p>