Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

importing protobuf generated modules within packages

This is my directory structure.

.
|-- A
|   |-- B
|   |    `-- b.proto
|   `-- C
|        `-- c.proto
`-- py_gen

I compile the test.proto like this

protoc --python_out=py_gen/ --proto_path ${ROOT}/A ${ROOT}/A/B/b.proto \
       ${ROOT}/A/C/c.proto

and this is the results that I get.

.
`-- py_gen
          |-- B
          |    `-- b_pb2.py
          `-- C
               `-- c_pb2.py

It all works fine, and I can import each module and use the module, if I include ${ROOT}/A/B/py_gen/B and ${ROOT}/A/B/py_gen/C in my PYTHONPATH.

The problem comes when, say, module c imports b. This would translate in the generated code for c importing

 import B.b_pb2

This is what is expected, because "In Python, packages are normally determined by directory structure" (from the protobuf tutorial). However, I cannot import module c because it does not find B.b_pb2.py. At the moment, to have it working, I have to add empty __init__.py files within the generated directories B and C. So why there is no __init__.py in the generated directory structure? Am I forgetting something? I am very new to python, so I might be overlooking something obvious here. But reading the python tutorial

The __init__.py files are required to make Python treat the directories as containing packages.

like image 737
stefano Avatar asked Jun 23 '11 13:06

stefano


1 Answers

Just:

import B.b_pb2

Without the .py ending. Also, for this to work, the B directory must have an __init__.py file in it, which can be empty. This tells Python this is a package directory. AFAIK protobuf won't put the __init__.py in there for your - but neither should it, since its goal is to just generate a single module for you.

like image 146
Eli Bendersky Avatar answered Sep 26 '22 06:09

Eli Bendersky