How to import .proto file in different package correctly?

431 views
Skip to first unread message

Alexander Luya

unread,
Jan 17, 2018, 2:52:17 AM1/17/18
to Protocol Buffers
I have two packages like this

    com.abc.
             protobuf.
                        share.proto
             depart.
                        detect.proto 

and the conent of  share.proto like this:

    syntax = "proto3";
    package com.adc.protobuf;
    message Test{}
       
and the content of detect.proto like this:

    syntax = "proto3";
    package com.adc.depart;
    import "com/abc/protobuf/share.proto"

and compile share.proto in it's dir like this:

    protoc -I=. --python_out=. share.proto

then compile detect.proto in it's dir like this:

    protoc -I=/pathToSrcDir/ -I=. --python_out=. detect.proto 
and
    
    pathToSrcDir has been added to PYTHONPATH

all compilations work fine,but when run a python script which 

    from com.abc.depart import detect_pb2

got this error   

    TypeError: Couldn't build proto file into descriptor pool!
    Invalid proto descriptor for file "detect.proto":
      detect.proto: Import "com/abc/protobuf/share.proto" has not been loaded.
      com.abc.depert.XClass.ymethod: "com.abc.protobuf.Test" seems to be defined in "share.proto", which is not imported by "detect.proto".  To use it here, please add the necessary import.

How to solve this import problem?

Charlie Tian

unread,
Sep 15, 2023, 12:32:17 AM9/15/23
to Protocol Buffers
"I've encountered the same issue. Have you found a solution?

Daz Wilkin

unread,
Sep 18, 2023, 9:51:31 PM9/18/23
to Protocol Buffers
The repro is somewhat unclear.

The package structure is uses `abc` but the protobuf sources use `adc`; I assume both should be the same.

In `share.proto`, `message Test` contains no fields and fields contain values, so the `Test` message contains no values and isn't useful.

The `detect.proto` contains no messages and so isn't useful either. 

If instead the following structure is used:

```
.
├── com
│   └── abc
│       ├── depart
│       │   └── detect.proto
│       └── protobuf
│           └── share.proto
└── main.py
```
And:
`detect.proto`:
```
syntax = "proto3";

package com.abc.depart;

import "com/abc/protobuf/share.proto";

message X{
    com.abc.protobuf.Test test = 1;
}
```
And:
`share.proto`:
```
syntax = "proto3";

package com.abc.protobuf;

message Test{
    string value = 1;
}
```

Because, there's a single protopath (`${PWD}` or `.`), we can use one `protoc` command to compile to Python sources:

```bash
protoc \
--proto_path=${PWD} \
--python_out=${PWD} \
--pyi_out=${PWD} \
${PWD}/com/abc/depart/detect.proto \
${PWD}/com/abc/protobuf/share.proto
```
and e.g. `main.py`:
```python3
from com.abc.depart import detect_pb2

x = detect_pb2.X()
x.test.value = "foo"

print(x)
```
Yields:

```console
test {
  value: "foo"
}
```
Reply all
Reply to author
Forward
0 new messages