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

How to import modules using ros noetic with python3?

asked 2021-06-11 12:07:01 -0600

muronglindong gravatar image

updated 2021-06-12 11:39:31 -0600

Hello, I'm new in ROS. When using ROS noetic with python, I can't import any modules in the same directory. For example, I created a package "test" and wrote two test files under ".../test/src/" as followed:

test1.py:

#!/usr/bin/env python
import sys

print(sys.path)

from test2 import *

a=test()

print(math.pi*2)

test2()

test2.py:

#!/usr/bin/env python
import math

class test:
    def __init__(self):
        print(math.pi)

def test2():
    print('test')

After executing 'rosrun test test1.py', the result shows:

['/home/mu/mu/devel/lib/test', '/home/mu/mu/devel/lib/python3/dist-packages', '/opt/ros/noetic/lib/python3/dist-packages', '/usr/lib/python38.zip', '/usr/lib/python3.8', '/usr/lib/python3.8/lib-dynload', '/home/mu/.local/lib/python3.8/site-packages', '/usr/local/lib/python3.8/dist-packages', '/usr/lib/python3/dist-packages']
Traceback (most recent call last):
  File "/home/mu/mu/devel/lib/test/test1.py", line 15, in <module>
    exec(compile(fh.read(), python_script, 'exec'), context)
  File "/home/mu/mu/src/test/src/test1.py", line 6, in <module>
    from test2 import *
ModuleNotFoundError: No module named 'test2'

But the same files executed in ROS melodic show:

test2 is imported
['/home/mu/mu/src/test/src', '/home/mu/mu/devel/lib/python2.7/dist-packages', '/opt/ros/melodic/lib/python2.7/dist-packages', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/home/mu/.local/lib/python2.7/site-packages', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/wx-3.0-gtk3']
3.14159265359
6.28318530718
test

I noticed sys.path[0] was different. So how to change sys.path[0], or how to import modules correctly in ROS noetic?

edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted
3

answered 2021-06-12 04:25:12 -0600

gvdhoorn gravatar image

updated 2021-06-12 04:37:01 -0600

So how to change sys.path[0], [..]

My answer to this would be: don't. Changing such properties manually should be done only when necessary (ie: no other standard mechanisms exist or work).

or how to import modules correctly in ROS noetic?

This isn't really related to Melodic or Noetic, but is probably caused by the Python version you're using -- which is related to whether you're using Melodic or Noetic.

Melodic is still Python 2.

Noetic is Python 3 (as you already mention).

Python 2 supports something called implicit relative imports, which makes statements like this

from test2 import *

first look for something called test2 in the directory in which test1.py is located. These are implicit relative imports as the import statement does not explicitly tell Python to look for test2 in the same directory as test1.py.

Python 3 doesn't support that any more.

In Python 3 you must tell Python explicitly to try and import from a local directory, instead of only searching on the sys.path.

If you'd change your import statement to read:

from . test2 import *

it will most likely start working.

And just to make it extra clear: this is a general Python 'problem', not something specific to ROS.

For a source which goes into a bit more detail, see Absolute vs Relative Imports in Python on Real Python.

edit flag offensive delete link more

Comments

1

Thank you for answering my question. I learned relative imports but not quite understand. Anyway, test1.py can be runned directly using "python -m src.test1.py" after modified to relative imports, though there still exists some error. But running "rosrun test test1.py" still can't work with the error "ImportError: attempted relative import with no known parent package".

In fact, running test1.py with absolute imports using "python test1.py" can get the same result as in ROS melodic. It seems that ROS noetic created a new file ".../devel/lib/test/test1.py" and executed this one, while ROS melodic won't create this file. Running the test1.py created by ROS noetic directly got the same error as discribed in the question.

Is relative import used here because the main executed file is the one created instead of the one I wrote?

muronglindong gravatar image muronglindong  ( 2021-06-12 11:36:15 -0600 )edit

Hi @muronglindong Have you solved this issue? Because i am facing the same issue when transitioning melodic package to noetic, and not yet found a solution.

HappySamuel gravatar image HappySamuel  ( 2022-03-02 02:01:18 -0600 )edit
0

answered 2022-09-06 08:48:21 -0600

Current python workpath is where you run rosrun, not the …/test/src. Hence, this problem is coursed by the path of python file you want import is not in sys.path, you can simply fix it by add sys.path.append("pyth to test2.py") to test1.py.

Also, when adding test1.py to CMakeLists.txt, ROS noetic will create a .py file in devel/lib with same name and add the file path to sys.path, then rosrun test test1 is available. So if you adding test2.py to CMakeLists.txt, you may get error like module test2 has no attribute test.

edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2021-06-11 12:07:01 -0600

Seen: 2,816 times

Last updated: Jun 12 '21