66import sys
77import traceback
88from os import path
9+ from contextlib import contextmanager
910
1011from getgauge import logger
1112from getgauge .registry import registry
1617env_dir = os .path .join (project_root , 'env' , 'default' )
1718requirements_file = os .path .join (project_root , 'requirements.txt' )
1819sys .path .append (project_root )
20+ temporary_sys_path = []
1921PLUGIN_JSON = 'python.json'
2022VERSION = 'version'
2123PYTHON_PROPERTIES = 'python.properties'
@@ -30,6 +32,12 @@ def load_impls(step_impl_dirs=impl_dirs):
3032 logger .error ('Make sure `STEP_IMPL_DIR` env var is set to a valid directory path.' )
3133 return
3234 base_dir = project_root if impl_dir .startswith (project_root ) else os .path .dirname (impl_dir )
35+ # Handle multi-level relative imports
36+ for _ in range (impl_dir .count ('..' )):
37+ base_dir = os .path .dirname (base_dir ).replace ("/" , os .path .sep ).replace ("\\ " , os .path .sep )
38+ # Add temporary sys path for relative imports that is not already added
39+ if '..' in impl_dir and base_dir not in temporary_sys_path :
40+ temporary_sys_path .append (base_dir )
3341 _import_impl (base_dir , impl_dir )
3442
3543
@@ -57,12 +65,25 @@ def _import_impl(base_dir, step_impl_dir):
5765 elif path .isdir (file_path ):
5866 _import_impl (base_dir , file_path )
5967
68+ @contextmanager
69+ def use_temporary_sys_path ():
70+ original_sys_path = sys .path [:]
71+ sys .path .extend (temporary_sys_path )
72+ try :
73+ yield
74+ finally :
75+ sys .path = original_sys_path
6076
6177def _import_file (base_dir , file_path ):
6278 rel_path = os .path .normpath (file_path .replace (base_dir + os .path .sep , '' ))
6379 try :
6480 module_name = os .path .splitext (rel_path .replace (os .path .sep , '.' ))[0 ]
65- m = importlib .import_module (module_name )
81+ # Use temporary sys path for relative imports
82+ if '..' in file_path :
83+ with use_temporary_sys_path ():
84+ m = importlib .import_module (module_name )
85+ else :
86+ m = importlib .import_module (module_name )
6687 # Get all classes in the imported module
6788 classes = inspect .getmembers (m , lambda member : inspect .isclass (member ) and member .__module__ == module_name )
6889 if len (classes ) > 0 :
0 commit comments