ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Strange <package>.msg import behavior: "ModuleNotFoundError: No module named '<package>.msg'" Is this a ROS bug?

asked 2022-08-09 22:22:32 -0600

zkytony gravatar image

updated 2022-08-09 22:30:01 -0600

I am using ROS Noetic on Ubuntu 20.04. My Python version is 3.8.10. Here is what I observed.

Suppose we create a package called 'mytest', whose content is as follows

|-- CMakeLists.txt
|-- msg
|   `-- MyMessage.msg
|-- package.xml
|-- scripts
|   `--
`-- src
    |-- mytest
    |   |--
    |   `--
    `-- mytest2

Notice there are two Python packages 'mytest' and 'mytest2', and they both contain a script called '', with identical content:

from mytest.msg import MyMessage  # We import mytest/MyMessage

def hello():

Suppose initially has the following content:

#!/usr/bin/env python
from mytest.hey import hello


Refer to the content of CMakeLists.txt at the bottom. Build this package with catkin_make -DCATKIN_WHITELIST_PACKAGES='mytest'.

Now, if I do rosrun mytest, I get the expected output, which is HELLO. However, if I change from mytest.hey import hello to from mytest2.hey import hello, then I get an error:

$ rosrun mytest
Traceback (most recent call last):
  File "...../ros_ws/src/mytest/scripts/", line 2, in <module>
    from mytest2.hey import hello
  File "...../ros_ws/src/mytest/src/mytest2/", line 1, in <module>
    from mytest.msg import MyMessage
ModuleNotFoundError: No module named 'mytest.msg'

How is this possible? "mytest" is built, and "mytest.msg" exists. But I can only access it within "mytest" and not from another pacfkage. I observed this weird behavior that confused me for several hours. Could someone explain what is going on?

Further Observation 1

I printed sys.path and the __file__ attribute of mytest and mytest.msg before the import statement in for both mytest and mytest2. I notice that the output of sys.path is identical. Notably, I get:

# print(sys.path)

However, the __file__ attribute differs.

In mytest/,

import mytest
# output: ..../ros_ws/devel/lib/python3/dist-packages/mytest/

Whereas, in mytest2/,

import mytest
# output: ..../ros_ws/src/mytest/src/mytest/

Further Observation 2

mytest.msg can be imported in a Python shell

$ python
Python 3.8.10 (default, Mar 15 2022, 12:22:08) 
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import mytest.msg
>>> mytest.msg.__file__

The content of CMakeLists.txt is

cmake_minimum_required(VERSION 3.0.2)

find_package(catkin REQUIRED COMPONENTS




edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted

answered 2022-08-10 11:22:16 -0600

Mike Scheutzow gravatar image

updated 2022-08-10 11:24:11 -0600

Not a bug.

What you are missing is your custom messages create a python module mytest in ros_ws/devel/lib/... It has a .py file for each custom message.

So when your mytest2 looks for python module mytest, the first one it finds is ros_ws/src/mytest/src/mytest. This python module has no submodule msg, so an error is thrown.

It's bad practice to name your ros-package the same as a nested python module, and this is the reason why.

edit flag offensive delete link more


Thanks Mike. I had thought about that actually. But how come import mytest.msg works within in mytest? The sys.path shows that ros_ws/src/mytest/src/mytest is the first place to look for mytest, and there is no msgsubmodule there. That doesn't make sense to me. Also, regarding the mention of bad practice, I seem to often see ROS packages whose name is also used as an inner python package name. For example, the rospy package has a 'src/rospy' folder.

zkytony gravatar image zkytony  ( 2022-08-10 11:33:41 -0600 )edit

Question Tools



Asked: 2022-08-09 22:22:32 -0600

Seen: 551 times

Last updated: Aug 10 '22