5 new revisions:
Revision: 7fe5f5ec67a2
Author: Pekka Klärck
Date: Mon Jan 2 14:13:08 2012
Log: importing by path: require paths to be absolute. no need to
require di...
http://code.google.com/p/robotframework/source/detail?r=7fe5f5ec67a2
Revision: 7bbc0dcb3f41
Author: Pekka Klärck
Date: Mon Jan 2 14:42:34 2012
Log: import by path: first verifying path exists generally gives
better err...
http://code.google.com/p/robotframework/source/detail?r=7bbc0dcb3f41
Revision: 95ac39daaa95
Author: Pekka Klärck
Date: Mon Jan 2 14:56:46 2012
Log: convert paths to variable files and listeners into absolute
format alr...
http://code.google.com/p/robotframework/source/detail?r=95ac39daaa95
Revision: 1cf831700b07
Author: Pekka Klärck
Date: Mon Jan 2 15:00:08 2012
Log: test cleanup
http://code.google.com/p/robotframework/source/detail?r=1cf831700b07
Revision: 92fe00c4eaf0
Author: Pekka Klärck
Date: Mon Jan 2 15:01:11 2012
Log: namespace: cleanup. partly made possible by enhancements to
importer
http://code.google.com/p/robotframework/source/detail?r=92fe00c4eaf0
==============================================================================
Revision: 7fe5f5ec67a2
Author: Pekka Klärck
Date: Mon Jan 2 14:13:08 2012
Log: importing by path: require paths to be absolute. no need to
require dirs to contain / at the end afterwards.
http://code.google.com/p/robotframework/source/detail?r=7fe5f5ec67a2
Modified:
/src/robot/utils/importer.py
/utest/utils/test_importer_util.py
=======================================
--- /src/robot/utils/importer.py Mon Jan 2 07:04:30 2012
+++ /src/robot/utils/importer.py Mon Jan 2 14:13:08 2012
@@ -144,10 +144,10 @@
class ByPathImporter(_Importer):
- _import_path_endings = ('.py', '.java', '.class', '/', os.sep)
+ _valid_import_extensions = ('.py', '.java', '.class', '')
def handles(self, path):
- return os.path.exists(path) and
path.endswith(self._import_path_endings)
+ return os.path.isabs(path)
def import_(self, path):
self._verify_import_path(path)
@@ -155,22 +155,24 @@
imported = self._get_class_from_module(module) or module
return self._verify_type(imported), path
+ def _verify_import_path(self, path):
+ if not os.path.isabs(path):
+ raise DataError('Import path must be absolute.')
+ if not os.path.exists(path):
+ raise DataError('File or directory does not exist.')
+ if not os.path.splitext(path)[1] in self._valid_import_extensions:
+ raise DataError('Not a valid file or directory to import.')
+
def _import_by_path(self, path):
module_dir, module_name = self._split_path_to_module(path)
- sys.path.insert(0, module_dir)
if module_name in sys.modules:
del sys.modules[module_name]
+ sys.path.insert(0, module_dir)
try:
return self._import(module_name)
finally:
sys.path.pop(0)
- def _verify_import_path(self, path):
- if not os.path.exists(path):
- raise DataError('File or directory does not exist.')
- if not path.endswith(self._import_path_endings):
- raise DataError('Not a valid file or directory to import.')
-
def _split_path_to_module(self, path):
module_dir, module_file = os.path.split(abspath(path))
module_name = os.path.splitext(module_file)[0]
=======================================
--- /utest/utils/test_importer_util.py Mon Jan 2 07:04:30 2012
+++ /utest/utils/test_importer_util.py Mon Jan 2 14:13:08 2012
@@ -136,21 +136,31 @@
class TestInvalidImportPath(unittest.TestCase):
+ def test_non_absolute(self):
+ assert_raises_with_msg(DataError,
+ "Importing 'non.existing.py' failed: Import path must be
absolute.",
+ Importer().import_class_or_module_by_path, 'non.existing.py')
+ assert_raises_with_msg(DataError,
+ "Importing file 'nonex.py' failed: Import path must be
absolute.",
+ Importer('file').import_class_or_module_by_path, 'nonex.py')
+
def test_non_existing(self):
+ path = abspath('non-existing.py')
assert_raises_with_msg(DataError,
- "Importing 'non-existing.py' failed: File or directory does
not exist.",
- Importer().import_class_or_module_by_path, 'non-existing.py')
+ "Importing '%s' failed: File or directory does not exist." %
path,
+ Importer().import_class_or_module_by_path, path)
assert_raises_with_msg(DataError,
- "Importing test file 'non-existing.py' failed: File or
directory does not exist.",
- Importer('test
file').import_class_or_module_by_path, 'non-existing.py')
+ "Importing test file '%s' failed: File or directory does not
exist." % path,
+ Importer('test file').import_class_or_module_by_path, path)
def test_invalid_format(self):
+ path = join(CURDIR, '..', '..', 'README.txt')
assert_raises_with_msg(DataError,
- "Importing '%s' failed: Not a valid file or directory to
import." % CURDIR,
- Importer().import_class_or_module_by_path, CURDIR)
+ "Importing '%s' failed: Not a valid file or directory to
import." % path,
+ Importer().import_class_or_module_by_path, path)
assert_raises_with_msg(DataError,
- "Importing xxx '%s' failed: Not a valid file or directory to
import." % CURDIR,
- Importer('xxx').import_class_or_module_by_path, CURDIR)
+ "Importing xxx '%s' failed: Not a valid file or directory to
import." % path,
+ Importer('xxx').import_class_or_module_by_path, path)
class TestImportClassOrModule(unittest.TestCase):
==============================================================================
Revision: 7bbc0dcb3f41
Author: Pekka Klärck
Date: Mon Jan 2 14:42:34 2012
Log: import by path: first verifying path exists generally gives
better error messages than first checking it is absolute
http://code.google.com/p/robotframework/source/detail?r=7bbc0dcb3f41
Modified:
/src/robot/utils/importer.py
/utest/utils/test_importer_util.py
=======================================
--- /src/robot/utils/importer.py Mon Jan 2 14:13:08 2012
+++ /src/robot/utils/importer.py Mon Jan 2 14:42:34 2012
@@ -156,10 +156,10 @@
return self._verify_type(imported), path
def _verify_import_path(self, path):
- if not os.path.isabs(path):
- raise DataError('Import path must be absolute.')
if not os.path.exists(path):
raise DataError('File or directory does not exist.')
+ if not os.path.isabs(path):
+ raise DataError('Import path must be absolute.')
if not os.path.splitext(path)[1] in self._valid_import_extensions:
raise DataError('Not a valid file or directory to import.')
=======================================
--- /utest/utils/test_importer_util.py Mon Jan 2 14:13:08 2012
+++ /utest/utils/test_importer_util.py Mon Jan 2 14:42:34 2012
@@ -136,23 +136,25 @@
class TestInvalidImportPath(unittest.TestCase):
- def test_non_absolute(self):
- assert_raises_with_msg(DataError,
- "Importing 'non.existing.py' failed: Import path must be
absolute.",
- Importer().import_class_or_module_by_path, 'non.existing.py')
- assert_raises_with_msg(DataError,
- "Importing file 'nonex.py' failed: Import path must be
absolute.",
- Importer('file').import_class_or_module_by_path, 'nonex.py')
-
def test_non_existing(self):
- path = abspath('non-existing.py')
+ path = 'non-existing.py'
assert_raises_with_msg(DataError,
"Importing '%s' failed: File or directory does not exist." %
path,
Importer().import_class_or_module_by_path, path)
+ path = abspath(path)
assert_raises_with_msg(DataError,
"Importing test file '%s' failed: File or directory does not
exist." % path,
Importer('test file').import_class_or_module_by_path, path)
+ def test_non_absolute(self):
+ path = os.listdir('.')[0]
+ assert_raises_with_msg(DataError,
+ "Importing '%s' failed: Import path must be absolute." % path,
+ Importer().import_class_or_module_by_path, path)
+ assert_raises_with_msg(DataError,
+ "Importing file '%s' failed: Import path must be absolute." %
path,
+ Importer('file').import_class_or_module_by_path, path)
+
def test_invalid_format(self):
path = join(CURDIR, '..', '..', 'README.txt')
assert_raises_with_msg(DataError,
==============================================================================
Revision: 95ac39daaa95
Author: Pekka Klärck
Date: Mon Jan 2 14:56:46 2012
Log: convert paths to variable files and listeners into absolute
format already in settings - this is required because nowadays imports by
path must use absolute paths
http://code.google.com/p/robotframework/source/detail?r=95ac39daaa95
Modified:
/src/robot/conf/settings.py
/utest/conf/test_settings.py
=======================================
--- /src/robot/conf/settings.py Tue Dec 13 15:10:56 2011
+++ /src/robot/conf/settings.py Mon Jan 2 14:56:46 2012
@@ -95,7 +95,7 @@
if name in ['SuiteStatLevel', 'MonitorWidth']:
return self._convert_to_positive_integer_or_default(name,
value)
if name in ['Listeners', 'VariableFiles']:
- return [self._split_args_from_name(item) for item in value]
+ return [self._split_args_from_name_or_path(item) for item in
value]
if name == 'ReportBackground':
return self._process_report_background(value)
if name == 'TagStatCombine':
@@ -215,14 +215,17 @@
def _get_default_value(self, name):
return self._cli_opts[name][1]
- def _split_args_from_name(self, name):
+ def _split_args_from_name_or_path(self, name):
if ':' not in name or os.path.exists(name):
- return name, []
- args = name.split(':')
- name = args.pop(0)
- # Handle absolute Windows paths with arguments
- if len(name) == 1 and args[0].startswith(('/', '\\')):
- name = name + ':' + args.pop(0)
+ args = []
+ else:
+ args = name.split(':')
+ name = args.pop(0)
+ # Handle absolute Windows paths with arguments
+ if len(name) == 1 and args[0].startswith(('/', '\\')):
+ name = name + ':' + args.pop(0)
+ if os.path.exists(name):
+ name = os.path.abspath(name)
return name, args
def __contains__(self, setting):
=======================================
--- /utest/conf/test_settings.py Wed Oct 5 05:34:12 2011
+++ /utest/conf/test_settings.py Mon Jan 2 14:56:46 2012
@@ -1,5 +1,6 @@
import unittest
import os
+from os.path import abspath
from robot.conf.settings import _BaseSettings, RobotSettings, RebotSettings
from robot.utils.asserts import assert_equals, assert_false
@@ -11,10 +12,10 @@
pass
-class TestSplitArgsFromName(unittest.TestCase):
+class TestSplitArgsFromNameOrPath(unittest.TestCase):
def setUp(self):
- self.method = SettingWrapper()._split_args_from_name
+ self.method = SettingWrapper()._split_args_from_name_or_path
def test_with_no_args(self):
assert_equals(self.method('name'), ('name', []))
@@ -40,14 +41,23 @@
('D:\\APPS\\listener', ['v1', 'b2', 'z3']))
assert_equals(self.method('C:/varz.py:arg'), ('C:/varz.py',
['arg']))
+ def test_existing_paths_are_made_absolute(self):
+ path = 'robot-framework-unit-test-file-12q3405909qasf'
+ open(path, 'w').close()
+ try:
+ assert_equals(self.method(path), (abspath(path), []))
+ assert_equals(self.method(path+':arg'), (abspath(path),
['arg']))
+ finally:
+ os.remove(path)
+
def test_existing_path_with_colons(self):
# Colons aren't allowed in Windows paths (other than in "c:")
if os.sep == '\\':
return
path = 'robot:framework:test:1:2:42'
+ os.mkdir(path)
try:
- os.mkdir(path)
- assert_equals(self.method(path), (path, []))
+ assert_equals(self.method(path), (abspath(path), []))
finally:
os.rmdir(path)
==============================================================================
Revision: 1cf831700b07
Author: Pekka Klärck
Date: Mon Jan 2 15:00:08 2012
Log: test cleanup
http://code.google.com/p/robotframework/source/detail?r=1cf831700b07
Modified:
/atest/robot/variables/commandline_variable_files.txt
=======================================
--- /atest/robot/variables/commandline_variable_files.txt Thu Dec 22
02:31:46 2011
+++ /atest/robot/variables/commandline_variable_files.txt Mon Jan 2
15:00:08 2012
@@ -15,22 +15,34 @@
Check Test Case Arguments To Variable Files
Non-Existing Variable File
- Check Stderr Contains [ ERROR ] Importing variable
file 'non_existing.py' failed: File or directory does not exist.
+ Check Stderr Contains [ ERROR ] Importing variable file '${VF3}'
failed: File or directory does not exist.
+ Check Stderr Contains [ ERROR ] Importing variable file '${VF4}'
failed: File or directory does not exist.
Too Few Arguments To Variable File
- Check Stderr Contains [ ERROR ] Processing variable
file '${VARFILE2}' failed: TypeError: get_variables()
+ Check Stderr Contains [ ERROR ] Processing variable file '${VF2}'
failed: TypeError: get_variables()
Too Many Arguments To Variable File
- Check Stderr Contains [ ERROR ] Processing variable
file '${VARFILE2}' with arguments [ too | many | args ] failed: TypeError:
get_variables()
+ Check Stderr Contains [ ERROR ] Processing variable file '${VF2}'
with arguments [ too | many | args ] failed: TypeError: get_variables()
Invalid Variable File
- Check Stderr Contains [ ERROR ] Processing variable
file '${VARFILE2}' with arguments [ FAIL ] failed: ZeroDivisionError:
+ Check Stderr Contains [ ERROR ] Processing variable file '${VF2}'
with arguments [ FAIL ] failed: ZeroDivisionError:
*** Keywords ***
Run Test Data
- ${varfile} = Normalize Path ${VARFILEDIR}/cli_vars.py
- ${varfile2} = Normalize Path ${VARFILEDIR}/cli_vars_2.py
- ${varfile3} = Normalize Path ${VARFILEDIR}/cli_vars_invalid.py
- Run Tests --variablefile ${varfile} -V ${varfile2}:arg -V
${varfile2}:arg2:given --variablefile non_existing.py --variablefile
${varfile2} -V ${varfile2}:too:many:args -V ${varfile2}:FAIL
variables/commandline_variable_files.txt
- Set Suite Variable $VARFILE2
-
+ ${vf1} = Normalize Path ${VARFILEDIR}/cli_vars.py
+ ${vf2} = Normalize Path ${VARFILEDIR}/cli_vars_2.py
+ ${vf3} = Normalize Path ${VARFILEDIR}/non_existing.py
+ ${vf4} = Set Variable non_absolute_non_existing.py
+ ${varfiles} = Catenate
+ ... --variablefile ${vf1}
+ ... -V ${vf2}:arg
+ ... -V ${vf2}:arg2:given
+ ... --variablefile ${vf2}
+ ... -V ${vf2}:FAIL
+ ... -V ${vf2}:too:many:args
+ ... --variablefile ${vf3}
+ ... --variablefile ${vf4}
+ Run Tests ${varfiles} variables/commandline_variable_files.txt
+ Set Suite Variable $VF2
+ Set Suite Variable $VF3
+ Set Suite Variable $VF4
==============================================================================
Revision: 92fe00c4eaf0
Author: Pekka Klärck
Date: Mon Jan 2 15:01:11 2012
Log: namespace: cleanup. partly made possible by enhancements to
importer
http://code.google.com/p/robotframework/source/detail?r=92fe00c4eaf0
Modified:
/src/robot/running/namespace.py
/utest/running/test_namespace.py
=======================================
--- /src/robot/running/namespace.py Thu Dec 22 02:31:46 2011
+++ /src/robot/running/namespace.py Mon Jan 2 15:01:11 2012
@@ -17,7 +17,7 @@
import copy
from robot import utils
-from robot.errors import FrameworkError, DataError
+from robot.errors import DataError
from robot.variables import GLOBAL_VARIABLES, is_scalar_var
from robot.common import UserErrorHandler
from robot.output import LOGGER
@@ -30,16 +30,17 @@
from .context import EXECUTION_CONTEXTS
-STDLIB_NAMES =
['BuiltIn', 'Collections', 'Dialogs', 'Easter', 'OperatingSystem',
- 'Remote', 'Reserved', 'Screenshot', 'String', 'Telnet']
+STDLIB_NAMES = set(('BuiltIn', 'Collections', 'Dialogs', 'Easter',
+ 'OperatingSystem', 'Remote', 'Reserved',
+ 'Screenshot', 'String', 'Telnet'))
IMPORTER = Importer()
class Namespace:
- """A database for keywords and variables.
-
- A new instance of this class is created for each test suite.
- """
+ _default_libraries = ('BuiltIn', 'Reserved', 'Easter')
+ _deprecated_libraries = {'BuiltIn': 'DeprecatedBuiltIn',
+ 'OperatingSystem': 'DeprecatedOperatingSystem'}
+ _library_import_by_path_endings = ('.py', '.java', '.class', '/',
os.sep)
def __init__(self, suite, parent_vars):
if suite is not None:
@@ -65,7 +66,7 @@
return variables
def _import_default_libraries(self):
- for name in 'BuiltIn', 'Reserved', 'Easter':
+ for name in self._default_libraries:
self.import_library(name)
def _handle_imports(self, import_settings):
@@ -74,17 +75,14 @@
if not item.name:
raise DataError('%s setting requires a name' %
item.type)
self._import(item)
- except:
- item.report_invalid_syntax(utils.get_error_message())
+ except DataError, err:
+ item.report_invalid_syntax(unicode(err))
def _import(self, import_setting):
- try:
- action = {'Library': self._import_library,
- 'Resource': self._import_resource,
- 'Variables':
self._import_variables}[import_setting.type]
- action(import_setting, self.variables.current)
- except KeyError:
- raise FrameworkError("Invalid import setting: %s" %
import_setting)
+ action = {'Library': self._import_library,
+ 'Resource': self._import_resource,
+ 'Variables': self._import_variables}[import_setting.type]
+ action(import_setting, self.variables.current)
def import_resource(self, name, overwrite=True):
self._import_resource(Resource(None, name), overwrite=overwrite)
@@ -122,7 +120,7 @@
self._import_library(Library(None, name, args=args, alias=alias),
variables)
def _import_library(self, import_setting, variables):
- name = self._get_library_name(import_setting, variables)
+ name = self._resolve_name(import_setting, variables)
lib = IMPORTER.import_library(name, import_setting.args,
import_setting.alias, variables)
if lib.name in self._testlibs:
@@ -135,66 +133,58 @@
lib.start_test()
self._import_deprecated_standard_libs(lib.name)
- def _get_library_name(self, import_setting, variables):
- name = self._resolve_name(import_setting, variables)
- if os.path.exists(name):
- return name
- return name.replace(' ', '')
-
def _resolve_name(self, import_setting, variables):
- """Resolves variables from the import_setting name
-
- Returns absolute path to file if it exists or resolved
import_setting name.
- """
+ name = import_setting.name
if variables:
try:
- name = variables.replace_string(import_setting.name)
+ name = variables.replace_string(name)
except DataError, err:
- self._report_replacing_vars_failed(import_setting, err)
- else:
- name = import_setting.name
- basedir = import_setting.directory or ''
- return self._get_path(import_setting.type, name, basedir)
-
- def _report_replacing_vars_failed(self, import_setting, err):
+ self._raise_replacing_vars_failed(import_setting, err)
+ return self._get_path(name, import_setting.directory,
import_setting.type)
+
+ def _raise_replacing_vars_failed(self, import_setting, err):
raise DataError("Replacing variables from setting '%s' failed: %s"
% (import_setting.type, unicode(err)))
- def _resolve_args(self, import_setting, variables):
- if not variables:
- return import_setting.args
+ def _get_path(self, name, basedir, type):
+ if type == 'Library' and not self._is_library_by_path(name):
+ return name.replace(' ', '')
try:
- return variables.replace_list(import_setting.args)
- except DataError, err:
- self._report_replacing_vars_failed(import_setting, err)
-
- def _get_path(self, setting_name, path, basedir):
- if setting_name == 'Library' and not
self._is_library_by_path(path):
- return path
- path = self._resolve_path(setting_name, path.replace('/', os.sep),
basedir)
- ending = os.sep if path.endswith(os.sep) else ''
- return utils.abspath(path) + ending
+ return self._resolve_path(name.replace('/', os.sep), basedir)
+ except DataError:
+ self._raise_imported_does_not_exist(type, name)
def _is_library_by_path(self, path):
- return path.lower().endswith(('.py', '.java', '.class', '/',
os.sep))
-
- def _resolve_path(self, setting_name, path, basedir):
+ return path.lower().endswith(self._library_import_by_path_endings)
+
+ def _resolve_path(self, path, basedir):
for base in [basedir] + sys.path:
- if not os.path.isdir(base):
+ if not (base and os.path.isdir(base)):
continue
ret = os.path.join(base, path)
if os.path.isfile(ret):
return ret
if os.path.isdir(ret) and
os.path.isfile(os.path.join(ret, '__init__.py')):
return ret
- name = {'Library': 'Test library',
+ raise DataError
+
+ def _raise_imported_does_not_exist(self, type, path):
+ type = {'Library': 'Test library',
'Variables': 'Variable file',
- 'Resource': 'Resource file'}[setting_name]
- raise DataError("%s '%s' does not exist." % (name, path))
+ 'Resource': 'Resource file'}[type]
+ raise DataError("%s '%s' does not exist." % (type, path))
+
+ def _resolve_args(self, import_setting, variables):
+ if not variables:
+ return import_setting.args
+ try:
+ return variables.replace_list(import_setting.args)
+ except DataError, err:
+ self._raise_replacing_vars_failed(import_setting, err)
def _import_deprecated_standard_libs(self, name):
- if name in ['BuiltIn', 'OperatingSystem']:
- self.import_library('Deprecated' + name)
+ if name in self._deprecated_libraries:
+ self.import_library(self._deprecated_libraries[name])
def start_test(self, test):
self.variables.start_test(test)
@@ -240,9 +230,8 @@
handler = self._get_handler(name)
if handler is None:
raise DataError("No keyword with name '%s' found." % name)
- except:
- error = utils.get_error_message()
- handler = UserErrorHandler(name, error)
+ except DataError, err:
+ handler = UserErrorHandler(name, unicode(err))
self._replace_variables_from_user_handlers(handler)
return handler
=======================================
--- /utest/running/test_namespace.py Thu Oct 13 15:21:11 2011
+++ /utest/running/test_namespace.py Mon Jan 2 15:01:11 2012
@@ -11,9 +11,9 @@
def test_standard_library_names(self):
module_path = os.path.dirname(libraries.__file__)
- exp_libs = [name for _, name, _ in
pkgutil.iter_modules([module_path])
- if name[0].isupper() and not
name.startswith('Deprecated')]
- assert_equals(exp_libs, namespace.STDLIB_NAMES)
+ exp_libs = (name for _, name, _ in
pkgutil.iter_modules([module_path])
+ if name[0].isupper() and not
name.startswith('Deprecated'))
+ assert_equals(set(exp_libs), namespace.STDLIB_NAMES)
class TestVariableScopes(unittest.TestCase):