For what it&#x27;s worth, I prefer the approach you describe.  I have advocated for it for a long time.  I&#x27;ve been writing C extensions to accelerate parsing in dynamic languages for 10 years, and I&#x27;m very familiar with this sort of dynamism.<p>It&#x27;s interesting though that you describe this approach as more Pythonic, because one of the most outspoken critics of this approach is a hard-core Python guy that I work with who has lots of experience with the Python ecosystem.  He feels very strongly that it is more Pythonic to have very flat&#x2F;concrete generated code that is transparent to the reader, and really does not like the idea of hooking import and generating everything at runtime.<p>This is exactly what I am describing about how it is hard to please everybody.  Different people appear to have fiercely different opinions about what is idiomatic.<p>When we wrote the Ruby protobuf implementation this year, we took an approach much more along the lines of what I personally prefer.  The extension is mostly implemented in C, and it&#x27;s very easy to build types at runtime.  It doesn&#x27;t directly import .proto files (which I would have preferred) because there was still some desire from others to have some kind of code generation.  So the approach we took was to use a Ruby-like DSL for describing the protobuf schema.  But really this is nothing but a translation of the .proto file into the Ruby DSL.  ie. take the .proto file:<p><pre><code>  syntax = &quot;proto3&quot;;

  message Test {
    int32 foo = 1;
    double bar = 2;
    Test test = 3;
  }
</code></pre>
The &quot;generated code&quot; for this is simply:<p><pre><code>  require &#x27;google&#x2F;protobuf&#x27;
  
  Google::Protobuf::DescriptorPool.generated_pool.build do
    add_message &quot;Test&quot; do
      optional :foo, :int32, 1
      optional :bar, :double, 2
      optional :test, :message, 3, &quot;Test&quot;
    end
  end

  Test = Google::Protobuf::DescriptorPool.generated_pool.lookup(&quot;Test&quot;).msgclass</code></pre>