def _validate(self, name, value): if name[0] == '@' and not is_list_like(value): raise DataError("Invalid variable '%s': Expected list-like value, " "got %s." % (name, type_name(value))) if name[0] == '&' and not is_dict_like(value): raise DataError("Invalid variable '%s': Expected dict-like value, " "got %s." % (name, type_name(value)))
def _import(self, path): with io.open(path, encoding='UTF-8') as stream: variables = self._load_yaml(stream) if not is_dict_like(variables): raise DataError('YAML variable file must be a mapping, got %s.' % type_name(variables)) return variables.items()
def _import_listener(self, listener): if not is_string(listener): return listener, type_name(listener) name, args = split_args_from_name_or_path(listener) importer = Importer("listener") listener = importer.import_class_or_module(os.path.normpath(name), instantiate_with_args=args) return listener, name
def _to_number_with_arithmetics(self, item): if isinstance(item, (int, long, float)): return item number = eval(str(item), {}) if not isinstance(number, (int, long, float)): raise TypeError("Expected number, got %s." % type_name(item)) return number
def __sub__(self, other): if isinstance(other, Date): return Time(self.datetime - other.datetime) if isinstance(other, Time): return Date(self.datetime - other.timedelta) raise TypeError('Can only subtract Date or Time from Date, got %s.' % type_name(other))
def __sub__(self, other): if isinstance(other, Date): return Time(self.seconds - other.seconds) if isinstance(other, Time): return Date(self.seconds - other.seconds) raise TypeError('Can only subtract Date or Time from Date, got %s.' % type_name(other))
def _to_number_with_arithmetics(self, item): if is_number(item): return item number = eval(str(item), {}) if not is_number(number): raise TypeError("Expected number, got %s." % type_name(item)) return number
def _import(self, path): with open(path) as stream: variables = yaml.load(stream) if not is_dict_like(variables): raise DataError('YAML variable file must be a mapping, got %s.' % type_name(variables)) return variables.items()
def visit_suite(self, suite): for visitor in self._visitors: try: suite.visit(visitor) except: message, details = get_error_details() LOGGER.error("Executing pre-run visitor '%s' failed: %s\n%s" % (type_name(visitor), message, details))
def test_java_object(self): for item, exp in [ (String(), "String"), (String, "Class"), (java.lang, "javapackage"), (java, "javapackage"), ]: assert_equals(type_name(item), exp)
def test_base_types(self): for item, exp in [('bytes', 'string'), (u'unicode', 'string'), (b'real bytes', 'string' if bytes is str else 'bytes'), (bytearray(), 'bytearray'), (1, 'integer'), (long(1), 'integer'), (1.0, 'float'), (True, 'boolean'), (None, 'None'), (set(), 'set'), ([], 'list'), ((), 'tuple'), ({}, 'dictionary')]: assert_equal(type_name(item), exp)
def _get_dynamic(self, var_file, args): get_variables = (getattr(var_file, 'get_variables', None) or getattr(var_file, 'getVariables')) variables = get_variables(*args) if is_dict_like(variables): return variables.items() raise DataError("Expected '%s' to return dict-like value, got %s." % (get_variables.__name__, type_name(variables)))
def _get_variable_item(self, name, variable, item): if is_dict_like(variable): return self._get_dict_variable_item(name, variable, item) if is_list_like(variable): return self._get_list_variable_item(name, variable, item) raise VariableError("Variable '%s' is %s, not list or dictionary, " "and thus accessing item '%s' from it is not " "possible." % (name, type_name(variable), item))
def _import_listeners(self, listeners): for listener in listeners: try: yield ListenerProxy(listener) except DataError as err: if not is_string(listener): listener = type_name(listener) LOGGER.error("Taking listener '%s' into use failed: %s" % (listener, err.message))
def _transform_items(self, items): answer = list() for item in items: if not is_list_like(item): raise DataError('FOR IN ZIP items must all be list-like, ' 'got %s.' % type_name(item)) for zipped_item in zip(*[list(item) for item in items]): answer.extend(zipped_item) return answer
def __init__(self, listener): if is_string(listener): name, args = split_args_from_name_or_path(listener) listener = self._import_listener(name, args) else: name = type_name(listener) self.name = name self.version = self._get_version(listener) AbstractLoggerProxy.__init__(self, listener)
def _map_values_to_rounds(self, values, per_round): for item in values: if not is_list_like(item): raise DataError( "FOR IN ZIP items must all be list-like, got %s '%s'." % (type_name(item), item)) if len(values) % per_round != 0: self._raise_wrong_variable_count(per_round, len(values)) return zip(*(list(item) for item in values))
def _handle_error(self, name, value, error=None, strict=True): if not strict: return value value_type = '' if isinstance(value, str) else ' (%s)' % type_name(value) ending = ': %s' % error if (error and error.args) else '.' raise ValueError( "Argument '%s' got value '%s'%s that cannot be converted to %s%s" % (name, unic(value), value_type, self.type_name, ending))
def validate(self, types): if not types: return {} if is_dict_like(types): return self.validate_type_dict(types) if is_list_like(types): return self.convert_type_list_to_dict(types) raise DataError('Type information must be given as a dictionary or ' 'a list, got %s.' % type_name(types))
def _import_listeners(self, listener_data): listeners = [] for listener in listener_data: try: listeners.append(ListenerProxy(listener)) except DataError as err: if not is_string(listener): listener = type_name(listener) LOGGER.error("Taking listener '%s' into use failed: %s" % (listener, unicode(err))) return listeners
def test_custom_objects(self): class NewStyle(object): pass class OldStyle: pass for item, exp in [(NewStyle(), 'NewStyle'), (OldStyle(), 'OldStyle'), (NewStyle, 'class'), (OldStyle, 'class')]: assert_equal(type_name(item), exp)
def _import_listener(self, listener): if not is_string(listener): # Modules have `__name__`, with others better to use `type_name`. name = getattr(listener, '__name__', None) or type_name(listener) return listener, name name, args = split_args_from_name_or_path(listener) importer = Importer('listener') listener = importer.import_class_or_module(os.path.normpath(name), instantiate_with_args=args) return listener, name
def test_custom_objects(self): class CamelCase: pass class lower: pass for item, exp in [(CamelCase(), 'CamelCase'), (lower(), 'lower'), (CamelCase, 'CamelCase')]: assert_equal(type_name(item), exp)
def _close_listener(self, listener): method = (getattr(listener, 'close', None) or getattr(listener, '_close', None)) try: if method: method() except: message, details = get_error_details() name = getattr(listener, '__name__', None) or type_name(listener) self.report_error("Calling method '%s' of listener '%s' failed: %s" % (method.__name__, name, message), details)
def __init__(self, listener): if is_string(listener): name, args = split_args_from_name_or_path(listener) listener = self._import_listener(name, args) else: name = type_name(listener) AbstractLoggerProxy.__init__(self, listener) self.name = name self.version = self._get_version(listener) if self.version == 1: LOGGER.warn("Listener '%s' uses deprecated API version 1. " "Switch to API version 2 instead." % self.name)
def _import_listeners(self, listener_data): listeners = [] for listener in listener_data: try: listeners.append(ListenerProxy(listener)) except DataError as err: if not is_string(listener): listener = type_name(listener) LOGGER.error("Taking listener '%s' into use failed: %s" % (listener, err.message)) return listeners
def visit_suite(self, suite): for visitor in self._visitors: try: suite.visit(visitor) except: message, details = get_error_details() self._log_error("Executing model modifier '%s' failed: %s\n%s" % (type_name(visitor), message, details)) if not (suite.test_count or self._empty_suite_ok): raise DataError("Suite '%s' contains no tests after model " "modifiers." % suite.name)
def validate(self, types): if types is None: return None if not types: return {} if is_dict_like(types): return self.validate_type_dict(types) if is_list_like(types): return self.convert_type_list_to_dict(types) raise DataError('Type information must be given as a dictionary or ' 'a list, got %s.' % type_name(types))
def _close_listener(self, listener): method = (getattr(listener, 'close', None) or getattr(listener, '_close', None)) try: if method: method() except: message, details = get_error_details() name = getattr(listener, '__name__', None) or type_name(listener) LOGGER.error("Calling method '%s' of listener '%s' failed: %s" % (method.__name__, name, message)) LOGGER.info("Details:\n%s" % details)
def _import_listeners(self, library): listeners = [] for listener in library.listeners: try: listeners.append(_LibraryListenerProxy(library, listener)) except DataError as err: LOGGER.error("Taking listener '%s' into use for library '%s' failed: %s\n" "Listeners are disabled for this library." % (type_name(listener), library.name, err.message)) library.has_listener = False return [] return listeners
def import_listeners(cls, listeners, method_names, prefix=None, raise_on_error=False): imported = [] for listener in listeners: try: imported.append(cls(listener, method_names, prefix)) except DataError as err: name = listener if is_string(listener) else type_name(listener) msg = "Taking listener '%s' into use failed: %s" % (name, err) if raise_on_error: raise DataError(msg) LOGGER.error(msg) return imported
def evaluate_expression(expression, variable_store=None, modules=None, namespace=None): try: if not is_string(expression): raise TypeError("Expression must be string, got %s." % type_name(expression)) if not expression: raise ValueError("Expression cannot be empty.") return _evaluate(expression, variable_store, modules, namespace) except: raise DataError("Evaluating expression '%s' failed: %s" % (expression, get_error_message()))
def _to_string(self, value, allow_tuple=False, allow_none=False): if is_unicode(value): return value if is_bytes(value): return value.decode('UTF-8') if allow_tuple and is_list_like(value) and len(value) > 0: return tuple(value) if allow_none and value is None: return value or_tuple = ' or a non-empty tuple' if allow_tuple else '' raise DataError('Return value must be a string%s, got %s.' % (or_tuple, type_name(value)))
def _get_sequence_variable_item(self, name, variable, index): index = self.replace_scalar(index) try: index = self._parse_sequence_variable_index(index) except ValueError: try: return variable[index] except TypeError: raise VariableError( "%s '%s' used with invalid index '%s'. " "To use '[%s]' as a literal value, it needs " "to be escaped like '\\[%s]'." % (type_name( variable, capitalize=True), name, index, index, index)) except: raise VariableError("Accessing '%s[%s]' failed: %s" % (name, index, get_error_message())) try: return variable[index] except IndexError: raise VariableError( "%s '%s' has no item in index %d." % (type_name(variable, capitalize=True), name, index))
def _import_listeners(self, library): listeners = [] for listener in library.listeners: try: listeners.append(_LibraryListenerProxy(library, listener)) except DataError as err: LOGGER.error( "Taking listener '%s' into use for library '%s' failed: %s\n" "Listeners are disabled for this library." % (type_name(listener), library.name, err.message)) library.has_listener = False return [] return listeners
def test_base_types(self): for item, exp in [('x', 'string'), (u'x', 'string'), (b'x', 'bytes'), (bytearray(), 'bytearray'), (1, 'integer'), (1.0, 'float'), (True, 'boolean'), (None, 'None'), (set(), 'set'), ([], 'list'), ((), 'tuple'), ({}, 'dictionary')]: assert_equal(type_name(item), exp)
def test_custom_objects(self): class NewStyle(object): pass class OldStyle: pass for item, exp in [ (NewStyle(), "NewStyle"), (OldStyle(), "OldStyle"), (NewStyle, "type"), (OldStyle, "classobj"), ]: assert_equals(type_name(item), exp)
def _get_variable_item(self, match, value): name = match.name for item in match.items: if is_dict_like(value): value = self._get_dict_variable_item(name, value, item) elif hasattr(value, '__getitem__'): value = self._get_sequence_variable_item(name, value, item) else: raise VariableError( "Variable '%s' is %s, which is not subscriptable, and " "thus accessing item '%s' from it is not possible. To use " "'[%s]' as a literal value, it needs to be escaped like " "'\\[%s]'." % (name, type_name(value), item, item, item)) name = '%s[%s]' % (name, item) return value
def test_base_types(self): for item, exp in [ ("bytes", "string"), (u"unicode", "string"), (1, "integer"), (1L, "integer"), (1.0, "float"), (True, "boolean"), (None, "None"), (set(), "set"), ([], "list"), ((), "tuple"), ({}, "dictionary"), ]: assert_equals(type_name(item), exp)
def test_typing(self): for item, exp in [(List, 'list'), (List[int], 'list'), (Tuple, 'tuple'), (Tuple[int], 'tuple'), (Set, 'set'), (Set[int], 'set'), (Dict, 'dictionary'), (Dict[int, str], 'dictionary'), (Union, 'Union'), (Union[int, str], 'Union'), (Optional, 'Optional'), (Optional[int], 'Union'), (Any, 'Any')]: assert_equal(type_name(item), exp)
def _to_number_with_arithmetics(self, item): if isinstance(item, (int, long, float)): return item item = str(item) # eval() would also convert to int or float, but it sometimes very # mysteriously fails with IronPython (seems to be related to timeouts) # and thus it's better to avoid it. for converter in int, float: try: return converter(item) except ValueError: pass number = eval(item, {}) if not isinstance(number, (int, long, float)): raise TypeError("Expected number, got %s." % type_name(item)) return number
def _literal_eval(self, value, expected): if expected is set: # `ast.literal_eval` has no way to define an empty set. if value == 'set()': return set() try: value = literal_eval(value) except (ValueError, SyntaxError): # Original errors aren't too informative in these cases. raise ValueError('Invalid expression.') except TypeError as err: raise ValueError('Evaluating expression failed: %s' % err) if not isinstance(value, expected): raise ValueError('Value is %s, not %s.' % (type_name(value), expected.__name__)) return value
def _get_matches_in_iterable(iterable, pattern, case_insensitive=False, whitespace_insensitive=False): if not is_string(pattern): raise TypeError("Pattern must be string, got '%s'." % type_name(pattern)) regexp = False if pattern.startswith('regexp='): pattern = pattern[7:] regexp = True elif pattern.startswith('glob='): pattern = pattern[5:] matcher = Matcher(pattern, caseless=is_truthy(case_insensitive), spaceless=is_truthy(whitespace_insensitive), regexp=regexp) return [string for string in iterable if is_string(string) and matcher.match(string)]
def _get_variable_item(self, name, value, match): if match.identifier in '@&': var = '%s[%s]' % (name, match.items[0]) logger.warn("Accessing variable items using '%s' syntax " "is deprecated. Use '$%s' instead." % (var, var[1:])) for item in match.items: if is_dict_like(value): value = self._get_dict_variable_item(name, value, item) elif is_list_like(value): value = self._get_list_variable_item(name, value, item) else: raise VariableError( "Variable '%s' is %s, not list or dictionary, and thus " "accessing item '%s' from it is not possible." % (name, type_name(value), item)) name = '%s[%s]' % (name, item) return value
def __init__(self, type, name, doc, accepts=(), usages=None, members=None, items=None): self.type = type self.name = name self.doc = doc or '' # doc parsed from XML can be None. self.accepts = [ type_name(t) if not isinstance(t, str) else t for t in accepts ] self.usages = usages or [] # Enum members and TypedDict items are used only with appropriate types. self.members = members self.items = items
def _get_variable_item(self, match, value): name = match.name if match.identifier in '@&': var = '%s[%s]' % (name, match.items[0]) logger.warn("Accessing variable items using '%s' syntax " "is deprecated. Use '$%s' instead." % (var, var[1:])) for item in match.items: if is_dict_like(value): value = self._get_dict_variable_item(name, value, item) elif hasattr(value, '__getitem__'): value = self._get_sequence_variable_item(name, value, item) else: raise VariableError( "Variable '%s' is %s, which is not subscriptable, and " "thus accessing item '%s' from it is not possible. To use " "'[%s]' as a literal value, it needs to be escaped like " "'\\[%s]'." % (name, type_name(value), item, item, item)) name = '%s[%s]' % (name, item) return value
def _literal_eval(self, value, expected): # ast.literal_eval has some issues with sets: if expected is set: # On Python 2 it doesn't handle sets at all. if PY2: raise ValueError('Sets are not supported on Python 2.') # There is no way to define an empty set. if value == 'set()': return set() try: value = literal_eval(value) except (ValueError, SyntaxError): # Original errors aren't too informative in these cases. raise ValueError('Invalid expression.') except TypeError as err: raise ValueError('Evaluating expression failed: %s' % err) if not isinstance(value, expected): raise ValueError('Value is %s, not %s.' % (type_name(value), expected.__name__)) return value
def test_java_object(self): for item, exp in [(String(), 'String'), (String, 'Class'), (java.lang, 'javapackage'), (java, 'javapackage')]: assert_equal(type_name(item), exp)
def test_file(self): with open(__file__) as f: assert_equal(type_name(f), 'file')
def __sub__(self, other): if isinstance(other, Time): return Time(self.seconds - other.seconds) raise TypeError('Can only subtract Time from Time, got %s.' % type_name(other))
def _raise_cannot_set_type(self, name, value, expected): raise DataError("Cannot set variable '%s': Expected %s-like value, " "got %s." % (name, expected, type_name(value)))