From b00db7fcb98b4b0f293c448ae7e550336e1ea565 Mon Sep 17 00:00:00 2001 From: Jacob Perron Date: Thu, 14 May 2020 14:24:04 -0700 Subject: [PATCH 1/2] Explicitly add DLL directories for Windows before importing New in Python 3.8, we should call os.add_dll_directory for directories containing the DLLs we intend to import as well as their recursive dependencies. Signed-off-by: Jacob Perron --- .../rosidl_generator_py/import_type_support_impl.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/rosidl_generator_py/rosidl_generator_py/import_type_support_impl.py b/rosidl_generator_py/rosidl_generator_py/import_type_support_impl.py index 86062700..b4a2025a 100644 --- a/rosidl_generator_py/rosidl_generator_py/import_type_support_impl.py +++ b/rosidl_generator_py/rosidl_generator_py/import_type_support_impl.py @@ -13,6 +13,7 @@ # limitations under the License. import importlib +import os class UnsupportedTypeSupport(Exception): @@ -36,7 +37,19 @@ def import_type_support(pkg_name): :returns: the typesupport Python module for the specified package """ module_name = '.{}_s__rosidl_typesupport_c'.format(pkg_name) + # New in Python 3.8: on Windows we should call 'add_dll_directory()' for directories + # containing DLLs we depend on. + # https://docs.python.org/3/whatsnew/3.8.html#bpo-36085-whatsnew + dll_dir_handles = [] + if os.name == 'nt' and hasattr(os, 'add_dll_directory'): + path_env = os.environ['PATH'].split(';') + for prefix_path in path_env: + if os.path.exists(prefix_path): + dll_dir_handles.append(os.add_dll_directory(prefix_path)) try: return importlib.import_module(module_name, package=pkg_name) except ImportError: raise UnsupportedTypeSupport(pkg_name) + finally: + for handle in dll_dir_handles: + handle.close() From 6adb2959c1956e60aeb4ed10b059a6f81f292354 Mon Sep 17 00:00:00 2001 From: Jacob Perron Date: Fri, 15 May 2020 17:06:15 -0700 Subject: [PATCH 2/2] Move logic to common package rpyutils Signed-off-by: Jacob Perron --- rosidl_generator_py/package.xml | 1 + .../import_type_support_impl.py | 21 +++++++------------ 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/rosidl_generator_py/package.xml b/rosidl_generator_py/package.xml index 62bdb6c7..59f9535b 100644 --- a/rosidl_generator_py/package.xml +++ b/rosidl_generator_py/package.xml @@ -26,6 +26,7 @@ rosidl_generator_c rosidl_parser rosidl_runtime_c + rpyutils ament_cmake_pytest ament_index_python diff --git a/rosidl_generator_py/rosidl_generator_py/import_type_support_impl.py b/rosidl_generator_py/rosidl_generator_py/import_type_support_impl.py index b4a2025a..c16b0fb2 100644 --- a/rosidl_generator_py/rosidl_generator_py/import_type_support_impl.py +++ b/rosidl_generator_py/rosidl_generator_py/import_type_support_impl.py @@ -13,7 +13,8 @@ # limitations under the License. import importlib -import os + +from rpyutils import add_dll_directories_from_env class UnsupportedTypeSupport(Exception): @@ -37,19 +38,11 @@ def import_type_support(pkg_name): :returns: the typesupport Python module for the specified package """ module_name = '.{}_s__rosidl_typesupport_c'.format(pkg_name) - # New in Python 3.8: on Windows we should call 'add_dll_directory()' for directories - # containing DLLs we depend on. - # https://docs.python.org/3/whatsnew/3.8.html#bpo-36085-whatsnew - dll_dir_handles = [] - if os.name == 'nt' and hasattr(os, 'add_dll_directory'): - path_env = os.environ['PATH'].split(';') - for prefix_path in path_env: - if os.path.exists(prefix_path): - dll_dir_handles.append(os.add_dll_directory(prefix_path)) try: - return importlib.import_module(module_name, package=pkg_name) + # Since Python 3.8, on Windows we should ensure DLL directories are explicitly added + # to the search path. + # See https://docs.python.org/3/whatsnew/3.8.html#bpo-36085-whatsnew + with add_dll_directories_from_env('PATH'): + return importlib.import_module(module_name, package=pkg_name) except ImportError: raise UnsupportedTypeSupport(pkg_name) - finally: - for handle in dll_dir_handles: - handle.close()