0

It is not possible to import python modules generated by protobuf. Here's the code.

  • error message

here is the error message after run python main.py.

# python main.py 
Traceback (most recent call last):
  File "/usr/lib64/python2.7/multiprocessing/queues.py", line 266, in _feed
    send(obj)
PicklingError: Can't pickle <class 'demo_pb2.msg'>: import of module demo_pb2 failed
^CTraceback (most recent call last):
  File "main.py", line 31, in <module>
    main()
  File "main.py", line 24, in main
    for msg in iter(q.get, None):
  File "/usr/lib64/python2.7/multiprocessing/queues.py", line 117, in get
    res = self._recv()
KeyboardInterrupt
  • code tree
.
├── __init__.py
├── main.py
└── pb
    ├── demo_pb2_grpc.py
    ├── demo_pb2.py
    ├── demo.proto
    ├── __init__.py
    └── run_codegen.py
  • main.py
from multiprocessing import Queue
import os
from threading import Thread
import time
from pb import demo_pb2

q = Queue()


def generate_file_path(path):
    for root, dirs, files in os.walk(path):
        for dir_ in dirs:
            q.put(demo_pb2.msg(path=os.path.join(root, dir_)))
            time.sleep(0.1)
        for file_ in files:
            q.put(demo_pb2.msg(path=os.path.join(root, file_)))
            time.sleep(0.1)
    q.put(None)


def main():
    t = Thread(target=generate_file_path, args=('/root/pip',))
    t.start()
    for msg in iter(q.get, None):
        print(msg)
    q.close()
    t.join()


if __name__ == '__main__':
    main()
  • pb/demo.proto
syntax = "proto3";

package demo;

message msg {
    string path = 1;
}
  • pb/run_codegen.py
from grpc_tools import protoc

protoc.main((
    '-I./',
    '--python_out=./',
    '--grpc_python_out=./',
    'demo.proto',
))
iskylite
  • 1
  • 1
  • Hello @iskylite, and welcome to StackOverflow! Please share the definition of the `demo_pb2.msg` class with us. Also, if you make your code into a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) it will be appreciated. – David Jul 31 '22 at 04:36
  • Hello @David, thanks for your reply. But i don't found the file `demo_pb2.msg`, where is the file? And above is the minimal reproducible code. actually only need `main.py` and `pb/demo.proto` two files. – iskylite Aug 01 '22 at 01:22
  • Please share the contents of the file `pb/demo_pb2.py`. Inside there *should* be a `class msg:` definition (unless `msg` is imported from somewhere). – David Aug 01 '22 at 23:56

1 Answers1

0

Protobuf messages are not picklable. multiprocessing.Queue requires that enqueued objects be picleable. Maybe try serializing to JSON on one end and then deserializing on the other.

Richard Belleville
  • 1,445
  • 5
  • 7