Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add hint if rclpy fails to be imported #116

Merged
merged 7 commits into from
Sep 12, 2017

Conversation

mikaelarguedas
Copy link
Member

@mikaelarguedas mikaelarguedas commented Sep 12, 2017

closes #115
connects to #115

Thew content of the referenced wiki page can be updated at a later date

Without this change

Failed to load entry point 'pub': DLL load failed: The specified module could not be found.
Traceback (most recent call last):
  File "C:\dev\ros2\lib\demo_nodes_py\talker-script.py", line 11, in <module>
    load_entry_point('demo-nodes-py==0.0.0', 'console_scripts', 'talker')()
  File "C:\Python36\lib\site-packages\pkg_resources\__init__.py", line 570, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "C:\Python36\lib\site-packages\pkg_resources\__init__.py", line 2687, in load_entry_point
    return ep.load()
  File "C:\Python36\lib\site-packages\pkg_resources\__init__.py", line 2341, in load
    return self.resolve()
  File "C:\Python36\lib\site-packages\pkg_resources\__init__.py", line 2347, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "C:\dev\ros2\Lib\site-packages\demo_nodes_py\topics\talker.py", line 17, in <module>
    import rclpy
  File "C:\dev\ros2\Lib\site-packages\rclpy\__init__.py", line 17, in <module>
    from rclpy.executors import SingleThreadedExecutor as _SingleThreadedExecutor
  File "C:\dev\ros2\Lib\site-packages\rclpy\executors.py", line 21, in <module>
    from rclpy.impl.implementation_singleton import rclpy_implementation as _rclpy
  File "C:\dev\ros2\Lib\site-packages\rclpy\impl\implementation_singleton.py", line 32, in <module>
    rclpy_implementation = importlib.import_module('._rclpy', package='rclpy')
  File "C:\Python36\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
ImportError: DLL load failed: The specified module could not be found.

With this change

Failed to load entry point 'pub': DLL load failed: The specified module could not be found.
The module '._rclpy' failed to be imported while being present on the system. Please refer to 'https://github.com/ros2/ros2/wiki/Rclpy-Import-error-hint' for possible solutions

Traceback (most recent call last):
  File "C:\dev\ros2\lib\demo_nodes_py\talker-script.py", line 11, in <module>
    load_entry_point('demo-nodes-py==0.0.0', 'console_scripts', 'talker')()
  File "C:\Python36\lib\site-packages\pkg_resources\__init__.py", line 570, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "C:\Python36\lib\site-packages\pkg_resources\__init__.py", line 2687, in load_entry_point
    return ep.load()
  File "C:\Python36\lib\site-packages\pkg_resources\__init__.py", line 2341, in load
    return self.resolve()
  File "C:\Python36\lib\site-packages\pkg_resources\__init__.py", line 2347, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "C:\dev\ros2\Lib\site-packages\demo_nodes_py\topics\talker.py", line 17, in <module>
    import rclpy
  File "C:\dev\ros2\Lib\site-packages\rclpy\__init__.py", line 17, in <module>
    from rclpy.executors import SingleThreadedExecutor as _SingleThreadedExecutor
  File "C:\dev\ros2\Lib\site-packages\rclpy\executors.py", line 21, in <module>
    from rclpy.impl.implementation_singleton import rclpy_implementation as _rclpy
  File "C:\dev\ros2\Lib\site-packages\rclpy\impl\implementation_singleton.py", line 35, in <module>
    rclpy_implementation = importlib.import_module(module_name, package='rclpy')
  File "C:\Python36\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
ImportError: DLL load failed: The specified module could not be found.

Alternatively we could not reraise the exception and exit. That will give a cleaner error message but has the downside of restricting user ability to catch it and fallback. So I settled on the current behavior
Without reraising

Failed to load entry point 'pub': DLL load failed: The specified module could not be found.
The module '._rclpy' failed to be imported while being present on the system. Please refer to 'https://github.com/ros2/ros2/wiki/Rclpy-Import-error-hint' for possible solutions

@mikaelarguedas mikaelarguedas added in progress Actively being worked on (Kanban column) in review Waiting for review (Kanban column) and removed in progress Actively being worked on (Kanban column) labels Sep 12, 2017
import os
if os.path.isfile(e.path):
import sys
print(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use warnings module instead of printing? I think it would allow an advanced user to suppress the output, though I can't think of a use case for that.

try:
rclpy_implementation = importlib.import_module(module_name, package='rclpy')
except ImportError as e:
import os
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import should at module level. No need to do it in this local scope. Same for sys below.

print(
"The module '%s' failed to be imported while being present on the system."
" Please refer to '%s' for possible solutions\n" %
(module_name, 'https://github.com/ros2/ros2/wiki/Rclpy-Import-error-hint'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather print e.path here since module_name is already part of the exception string. The message could start with "The C extension '%s' failed ..." then.

@mikaelarguedas
Copy link
Member Author

new message:

Failed to load entry point 'pub': The C extension 'C:\dev\ros2\Lib\site-packages\rclpy\_rclpy.pyd' failed to be imported while being present on the system. Please refer to 'https://github.com/ros2/ros2/wiki/Rclpy-Import-error-hint' for possible solutions

Traceback (most recent call last):
  File "C:\dev\ros2\Lib\site-packages\rclpy\impl\implementation_singleton.py", line 33, in <module>
    rclpy_implementation = importlib.import_module('._rclpy', package='rclpy')
  File "C:\Python36\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 978, in _gcd_import
  File "<frozen importlib._bootstrap>", line 961, in _find_and_load
  File "<frozen importlib._bootstrap>", line 950, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 648, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 560, in module_from_spec
  File "<frozen importlib._bootstrap_external>", line 922, in create_module
  File "<frozen importlib._bootstrap>", line 205, in _call_with_frames_removed
ImportError: DLL load failed: The specified module could not be found.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\dev\ros2\lib\demo_nodes_py\talker-script.py", line 11, in <module>
    load_entry_point('demo-nodes-py==0.0.0', 'console_scripts', 'talker')()
  File "C:\Python36\lib\site-packages\pkg_resources\__init__.py", line 570, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "C:\Python36\lib\site-packages\pkg_resources\__init__.py", line 2687, in load_entry_point
    return ep.load()
  File "C:\Python36\lib\site-packages\pkg_resources\__init__.py", line 2341, in load
    return self.resolve()
  File "C:\Python36\lib\site-packages\pkg_resources\__init__.py", line 2347, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "C:\dev\ros2\Lib\site-packages\demo_nodes_py\topics\talker.py", line 17, in <module>
    import rclpy
  File "C:\dev\ros2\Lib\site-packages\rclpy\__init__.py", line 17, in <module>
    from rclpy.executors import SingleThreadedExecutor as _SingleThreadedExecutor
  File "C:\dev\ros2\Lib\site-packages\rclpy\executors.py", line 21, in <module>
    from rclpy.impl.implementation_singleton import rclpy_implementation as _rclpy
  File "C:\dev\ros2\Lib\site-packages\rclpy\impl\implementation_singleton.py", line 39, in <module>
    (e.path, 'https://github.com/ros2/ros2/wiki/Rclpy-Import-error-hint'))
ImportWarning: The C extension 'C:\dev\ros2\Lib\site-packages\rclpy\_rclpy.pyd' failed to be imported while being present on the system. Please refer to 'https://github.com/ros2/ros2/wiki/Rclpy-Import-error-hint' for possible solutions

rclpy_implementation = importlib.import_module('._rclpy', package='rclpy')
except ImportError as e:
if os.path.isfile(e.path):
raise ImportWarning(
Copy link
Member

@dirk-thomas dirk-thomas Sep 12, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be an ImportWarning. I thought @sloretz was referring to call warnings.warn(...).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I figured I just liked the idea of the message being the last thing the user see rather than having to scroll up the stack trace to see our message burried in the middle.
But I agree it's less semantically correct

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also extend the msg of the raised exception e to add additional information if you prefer a single message.

if os.path.isfile(e.path):
warnings.warn(
"The C extension '%s' failed to be imported while being present on the system."
" Please refer to '%s' for possible solutions\n" %
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the trailing \n necessary?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was not necessary but made the custom message not visible at all originally that's why I added it. Not that it's part of the exception message it's not necessary anymore

if os.path.isfile(e.path):
e.msg += \
"\nThe C extension '%s' failed to be imported while being present on the system." \
" Please refer to '%s' for possible solutions\n" % \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why should this have a trailing newline?

Copy link
Member

@dirk-thomas dirk-thomas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Can you post the resulting stacktrace?

@mikaelarguedas
Copy link
Member Author

Resulting stack trace:

Failed to load entry point 'pub': DLL load failed: The specified module could not be found.
The C extension 'C:\dev\ros2\Lib\site-packages\rclpy\_rclpy.pyd' failed to be imported while being present on the system. Please refer to 'https://github.com/ros2/ros2/wiki/Rclpy-Import-error-hint' for possible solutions

Traceback (most recent call last):
  File "C:\dev\ros2\lib\demo_nodes_py\talker-script.py", line 11, in <module>
    load_entry_point('demo-nodes-py==0.0.0', 'console_scripts', 'talker')()
  File "C:\Python36\lib\site-packages\pkg_resources\__init__.py", line 570, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "C:\Python36\lib\site-packages\pkg_resources\__init__.py", line 2687, in load_entry_point
    return ep.load()
  File "C:\Python36\lib\site-packages\pkg_resources\__init__.py", line 2341, in load
    return self.resolve()
  File "C:\Python36\lib\site-packages\pkg_resources\__init__.py", line 2347, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "C:\dev\ros2\Lib\site-packages\demo_nodes_py\topics\talker.py", line 17, in <module>
    import rclpy
  File "C:\dev\ros2\Lib\site-packages\rclpy\__init__.py", line 17, in <module>
    from rclpy.executors import SingleThreadedExecutor as _SingleThreadedExecutor
  File "C:\dev\ros2\Lib\site-packages\rclpy\executors.py", line 21, in <module>
    from rclpy.impl.implementation_singleton import rclpy_implementation as _rclpy
  File "C:\dev\ros2\Lib\site-packages\rclpy\impl\implementation_singleton.py", line 33, in <module>
    rclpy_implementation = importlib.import_module('._rclpy', package='rclpy')
  File "C:\Python36\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
ImportError: DLL load failed: The specified module could not be found.
The C extension 'C:\dev\ros2\Lib\site-packages\rclpy\_rclpy.pyd' failed to be imported while being present on the system. Please refer to 'https://github.com/ros2/ros2/wiki/Rclpy-Import-error-hint' for possible solutions

@mikaelarguedas mikaelarguedas merged commit 829a4ff into master Sep 12, 2017
@mikaelarguedas mikaelarguedas deleted the add_hint_for_fail_import branch September 12, 2017 22:46
@mikaelarguedas mikaelarguedas removed the in review Waiting for review (Kanban column) label Sep 12, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

r2b3 Failure to import _rclpy on windows
3 participants