18 from collections
import OrderedDict
19 from itertools
import chain
26 printable_name, seq2str2)
28 from .importer
import ImportCache, Importer
29 from .runkwregister
import RUN_KW_REGISTER
30 from .usererrorhandler
import UserErrorHandler
31 from .userkeyword
import UserLibrary
40 _default_libraries = (
'BuiltIn',
'Reserved',
'Easter')
44 _library_import_by_path_endings = (
'.py',
'.java',
'.class',
'/', os.sep)
46 def __init__(self, variables, suite, resource):
47 LOGGER.info(
"Initializing namespace for test suite '%s'" % suite.longname)
59 return self.
_kw_store_kw_store.libraries.values()
70 for item
in import_settings:
73 raise DataError(
'%s setting requires a name' % item.type)
75 except DataError
as err:
76 item.report_invalid_syntax(err.message)
82 action(import_setting)
90 if overwrite
or path
not in self.
_kw_store_kw_store.resources:
91 resource = IMPORTER.import_resource(path)
92 self.
variablesvariables.set_from_variable_table(resource.variables, overwrite)
94 self.
_kw_store_kw_store.resources[path] = user_library
96 LOGGER.imported(
"Resource", user_library.name,
97 importer=import_setting.source,
100 LOGGER.info(
"Resource file '%s' already imported by suite '%s'"
104 name = os.path.splitext(os.path.basename(path))[0]
105 if name.lower() ==
'__init__':
106 raise DataError(
"Initialization file '%s' cannot be imported as "
107 "a resource file." % path)
117 self.
variablesvariables.set_from_file(path, args, overwrite)
118 LOGGER.imported(
"Variables", os.path.basename(path),
120 importer=import_setting.source,
123 msg =
"Variable file '%s'" % path
125 msg +=
" with arguments %s" %
seq2str2(args)
126 LOGGER.info(
"%s already imported by suite '%s'"
135 lib = IMPORTER.import_library(name, import_setting.args,
136 import_setting.alias, self.
variablesvariables)
137 if lib.name
in self.
_kw_store_kw_store.libraries:
138 LOGGER.info(
"Test library '%s' already imported by suite '%s'"
142 LOGGER.imported(
"Library", lib.name,
143 args=list(import_setting.args),
144 originalname=lib.orig_name,
145 importer=import_setting.source,
147 self.
_kw_store_kw_store.libraries[lib.name] = lib
153 name = import_setting.name
155 name = self.
variablesvariables.replace_string(name)
156 except DataError
as err:
158 return self.
_get_name_get_name(name, import_setting)
161 raise DataError(
"Replacing variables from setting '%s' failed: %s"
162 % (import_setting.type, err.message))
165 if import_setting.type ==
'Library' and not self.
_is_library_by_path_is_library_by_path(name):
167 return find_file(name, import_setting.directory,
168 file_type=import_setting.type)
175 return self.
variablesvariables.replace_list(import_setting.args)
176 except DataError
as err:
180 old_order = self.
_kw_store_kw_store.search_order
181 self.
_kw_store_kw_store.search_order = new_order
203 IMPORTER.close_global_library_listeners()
213 return self.
_kw_store_kw_store.get_library(libname).get_instance()
216 return dict((name, lib.get_instance())
217 for name, lib
in self.
_kw_store_kw_store.libraries.items())
220 library = self.
_kw_store_kw_store.get_library(libname_or_instance)
227 except DataError
as error:
235 UserLibrary.TEST_CASE_FILE_TYPE)
241 if name_or_instance
is None:
242 raise DataError(
"Library can not be None.")
250 matches = [lib
for lib
in self.
librarieslibraries.values()
if eq(lib.name, name)]
251 if len(matches) == 1:
257 raise DataError(
"Multiple libraries matching '%s' found." % name)
258 raise DataError(
"No library '%s' found." % name)
261 for lib
in self.
librarieslibraries.values():
262 if lib.get_instance(create=
False)
is instance:
273 msg =
"No keyword with name '%s' found." % name
277 recommendations = finder.recommend_similar_keywords(name)
278 msg = finder.format_recommendations(msg, recommendations)
283 raise DataError(
'Keyword name cannot be empty.')
285 raise DataError(
'Keyword name must be a string.')
287 if not runner
and '.' in name:
297 for prefix
in [
'given ',
'when ',
'then ',
'and ',
'but ']:
298 if lower.startswith(prefix):
299 runner = self.
_get_runner_get_runner(name[len(prefix):])
301 runner = copy.copy(runner)
314 return self.
user_keywordsuser_keywords.handlers.create_runner(name)
317 found = [lib.handlers.create_runner(name)
318 for lib
in self.
resourcesresources.values()
319 if name
in lib.handlers]
329 found = [lib.handlers.create_runner(name)
for lib
in self.
librarieslibraries.values()
330 if name
in lib.handlers]
343 for runner
in runners:
344 if eq(libname, runner.libname):
349 stdlibs_without_remote = STDLIBS - {
'Remote'}
350 if runner1.library.orig_name
in stdlibs_without_remote:
351 standard, custom = runner1, runner2
352 elif runner2.library.orig_name
in stdlibs_without_remote:
353 standard, custom = runner2, runner1
355 return [runner1, runner2]
356 if not RUN_KW_REGISTER.is_run_keyword(custom.library.orig_name, custom.name):
361 custom_with_name = standard_with_name =
''
362 if custom.library.name != custom.library.orig_name:
363 custom_with_name =
" imported as '%s'" % custom.library.name
364 if standard.library.name != standard.library.orig_name:
365 standard_with_name =
" imported as '%s'" % standard.library.name
366 warning =
Message(
"Keyword '%s' found both from a custom test library "
367 "'%s'%s and a standard library '%s'%s. The custom "
368 "keyword is used. To select explicitly, and to get "
369 "rid of this warning, use either '%s' or '%s'."
371 custom.library.orig_name, custom_with_name,
372 standard.library.orig_name, standard_with_name,
373 custom.longname, standard.longname), level=
'WARN')
374 if custom.pre_run_messages:
375 custom.pre_run_messages.append(warning)
377 custom.pre_run_messages = [warning]
382 found.extend(self.
_find_keywords_find_keywords(owner_name, kw_name))
385 return found[0]
if found
else None
388 tokens = full_name.split(
'.')
389 for i
in range(1, len(tokens)):
390 yield '.'.join(tokens[:i]),
'.'.join(tokens[i:])
393 return [owner.handlers.create_runner(name)
394 for owner
in chain(self.
librarieslibraries.values(), self.
resourcesresources.values())
395 if eq(owner.name, owner_name)
and name
in owner.handlers]
398 error =
"Multiple keywords with name '%s' found" % name
400 error +=
". Give the full name of the keyword you want to use"
401 names = sorted(runner.longname
for runner
in found)
407 def __init__(self, user_keywords, libraries, resources):
415 normalizer =
lambda name: candidates.get(name, name).
lower().replace(
417 finder = RecommendationFinder(normalizer)
418 return finder.find_recommendations(name, candidates)
422 return RecommendationFinder.format_recommendations(
423 msg, recommendations)
428 full_name =
'%s.%s' % (owner, name)
if owner
else name
429 names[full_name] = full_name
if use_full_name
else name
438 for library
in chain(self.
librarieslibraries.values(), self.
resourcesresources.values()):
439 if library.name !=
'Reserved':
441 ((library.name
or '',
443 for handler
in library.handlers))
445 return sorted(handlers)
Used when variable does not exist.
Used when a test or keyword timeout occurs.
Keeps track on and optionally caches imported items.
def recommend_similar_keywords(self, name)
Return keyword names similar to name.
def _get_all_handler_names(self)
Return a list of (library_name, handler_name) tuples.
def _get_candidates(self, use_full_name)
def format_recommendations(msg, recommendations)
def __init__(self, user_keywords, libraries, resources)
def _get_bdd_style_runner(self, name)
def __init__(self, resource)
def _get_lib_by_name(self, name)
def get_runner(self, name)
def _get_runner_based_on_search_order(self, runners)
def _get_runner_from_libraries(self, name)
def get_library(self, name_or_instance)
def _get_lib_by_instance(self, instance)
def _raise_no_keyword_found(self, name)
def _get_runner_from_resource_files(self, name)
def _get_runner(self, name)
def _get_explicit_runner(self, name)
def _no_library_found(self, name, multiple=False)
def _get_runner_from_test_case_file(self, name)
def _yield_owner_and_kw_names(self, full_name)
def _get_implicit_runner(self, name)
def _raise_multiple_keywords_found(self, name, found, implicit=True)
def _custom_and_standard_keyword_conflict_warning(self, custom, standard)
def _find_keywords(self, owner_name, name)
def _filter_stdlib_runner(self, runner1, runner2)
def get_library_instances(self)
def end_user_keyword(self)
def _validate_not_importing_init_file(self, path)
def get_runner(self, name)
def import_variables(self, name, args, overwrite=False)
def _handle_imports(self, import_settings)
def end_suite(self, suite)
def _import_variables(self, import_setting, overwrite=False)
def start_user_keyword(self)
def get_library_instance(self, libname)
def import_library(self, name, args=None, alias=None, notify=True)
def __init__(self, variables, suite, resource)
def _resolve_name(self, import_setting)
def _import_library(self, import_setting, notify=True)
def _import_resource(self, import_setting, overwrite=False)
def _get_name(self, name, import_setting)
tuple _library_import_by_path_endings
def _import(self, import_setting)
def _is_library_by_path(self, path)
def _resolve_args(self, import_setting)
def _raise_replacing_vars_failed(self, import_setting, err)
def _import_default_libraries(self)
def set_search_order(self, new_order)
def reload_library(self, libname_or_instance)
def import_resource(self, name, overwrite=True)
Created if creating handlers fail – running raises DataError.
def eq(str1, str2, ignore=(), caseless=True, spaceless=True)
def printable_name(string, code_style=False)
Generates and returns printable name from the given string.
def seq2str2(sequence)
Returns sequence in format [ item 1 | item 2 | ...
def find_file(path, basedir='.', file_type=None)