Revision: 9921cff8ef7b
Author: Pekka Klärck
Date: Thu May 19 13:13:43 2011
Log: Refactored import logic and at the same time fixed problem with
importing two libraries with same name using physical path
Update issue 822
Status: Done
The problem is now fixed (or at least the test I created earlier passes).
The code changes were quite a bit larger than absolutely needed, but I
wanted
to cleanup the import logic at the same time. After the refactoring libs
specified with a path are imported using the same code that is used for
importing variable files which already had a fix for importing module with
a same name as an earlier imported different module.
http://code.google.com/p/robotframework/source/detail?r=9921cff8ef7b
Modified:
/atest/robot/test_libraries/library_import_failing.txt
/atest/robot/test_libraries/library_imports_by_path.txt
/src/robot/utils/importing.py
=======================================
--- /atest/robot/test_libraries/library_import_failing.txt Thu May 19
12:38:24 2011
+++ /atest/robot/test_libraries/library_import_failing.txt Thu May 19
13:13:43 2011
@@ -7,7 +7,8 @@
*** Test Cases ***
Library Import Fails Because Not a Library
- Check Failure From Output 0 Importing test
library 'MyInvalidLibFile' failed: ImportError: I'm not really a library!
raise ImportError("I'm not really a library!")
+ ${path} = Normalize Path
${CURDIR}/../../testdata/test_libraries/MyInvalidLibFile.py
+ Check Failure From Output 0 Importing test library '${path}' failed:
ImportError: I'm not really a library! raise ImportError("I'm not really a
library!")
Library Import Fails Because Initialization Fails
Check Failure From Output 2 Creating an instance of the test
library 'InitializationFailLibrary' with no arguments failed:
Initialization failed! InitializationFailLibrary.py", line 4, in __init__
=======================================
--- /atest/robot/test_libraries/library_imports_by_path.txt Thu May 19
04:27:08 2011
+++ /atest/robot/test_libraries/library_imports_by_path.txt Thu May 19
13:13:43 2011
@@ -39,7 +39,8 @@
Check Test Case Importing By Path Having Spaces
Importing Invalid Python File Fails
- Check Stderr Contains Importing test library 'MyInvalidLibFile'
failed: ImportError: I'm not really a library!
+ ${path} = Normalize Path
${CURDIR}/../../testdata/test_libraries/MyInvalidLibFile.py
+ Check Stderr Contains Importing test library '${path}' failed:
ImportError: I'm not really a library!
Inporting Dir Library Without Trailing "/" Fails
Check Stderr Contains Importing test library 'MyLibDir' failed:
ImportError: No module named MyLibDir
=======================================
--- /src/robot/utils/importing.py Thu May 19 05:39:25 2011
+++ /src/robot/utils/importing.py Thu May 19 13:13:43 2011
@@ -36,7 +36,8 @@
sys.path.insert(0, moddir)
try:
module = __import__(modname)
- if normpath(os.path.dirname(module.__file__)) != normpath(moddir):
+ if hasattr(module, '__file__') and \
+ normpath(os.path.dirname(module.__file__)) !=
normpath(moddir):
del sys.modules[modname]
module = __import__(modname)
return module
@@ -69,58 +70,50 @@
the module is also 'MyLibrary' then it is possible to use only
name 'MyLibrary'.
"""
- if os.path.exists(name):
- moddir, name = _split_path_to_module(name)
- sys.path.insert(0, moddir)
- pop_sys_path = True
+ if '.' not in name or os.path.exists(name):
+ code, module = _non_dotted_import(name, type_)
else:
- pop_sys_path = False
- try:
- code, module = _import(name, type_)
- finally:
- if pop_sys_path:
- sys.path.pop(0)
+ code, module = _dotted_import(name, type_)
source = _get_module_source(module)
return code, source
-
-def _import(name, type_):
- modname, classname, fromlist = _get_import_params(name)
+def _non_dotted_import(name, type_):
+ try:
+ if os.path.exists(name):
+ module = _import_module_by_path(name)
+ else:
+ module = __import__(name)
+ except:
+ _raise_import_failed(type_, name)
+ try:
+ code = getattr(module, module.__name__)
+ if not inspect.isclass(code):
+ raise AttributeError
+ except AttributeError:
+ code = module
+ return code, module
+
+def _dotted_import(name, type_):
+ parentname, libname = name.rsplit('.', 1)
try:
try:
- # It seems that we get class when importing java class from
file system
- # or from a default package of a jar file. Otherwise we get a
module.
- imported = __import__(modname, {}, {}, fromlist)
+ module = __import__(parentname, fromlist=[str(libname)])
except ImportError:
- # Hack to support standalone Jython:
+ # Hack to support standalone Jython:
# http://code.google.com/p/robotframework/issues/detail?id=515
if not sys.platform.startswith('java'):
- raise
+ raise
__import__(name)
- imported = __import__(modname, {}, {}, fromlist)
+ module = __import__(parentname, fromlist=[str(libname)])
except:
_raise_import_failed(type_, name)
try:
- code = getattr(imported, classname)
+ code = getattr(module, libname)
except AttributeError:
- if fromlist:
- _raise_no_lib_in_module(type_, modname, fromlist[0])
- code = imported
+ _raise_no_lib_in_module(type_, parentname, libname)
if not (inspect.ismodule(code) or inspect.isclass(code)):
- if fromlist:
- _raise_invalid_type(type_, code)
- else:
- code = imported
- return code, imported
-
-def _get_import_params(name):
- if '.' not in name:
- return name, name, []
- parts = name.split('.')
- modname = '.'.join(parts[:-1])
- classname = parts[-1]
- fromlist = [str(classname)] # Unicode not generally accepted
- return modname, classname, fromlist
+ _raise_invalid_type(type_, code)
+ return code, module
def _get_module_source(module):
source = getattr(module, '__file__', None)