Exemple #1
0
 def make_output_factory_args_kwargs(self, mapping_items):
     # type: (NamespaceMappingOrIterable) -> Tuple[Iterable, Mapping[Name, Value]]
     try:
         if isinstance(mapping_items, (str, bytes, bytearray)):
             raise DataConversionError('got a `str`/`bytes`/`bytearray`')
         self.verify_isinstance(mapping_items, (Mapping, Iterable))
         mapping = dict(**dict(mapping_items))
     except (TypeError, DataConversionError):
         raise DataConversionError(
             'expected a name-to-value mapping or an equivalent '
             'collection of name-value pairs')
     kwargs = dict(self.output_factory_default_kwargs)
     kwargs.update(mapping)
     return (), kwargs
Exemple #2
0
def _adjust_server_secret(value):
    # type: (...) -> str
    if not isinstance(value, (unicode, bytes)):                                  #3: `unicode` -> `str`
        raise DataConversionError('not a `str` or `bytes` - its type is `{}`'
                                  .format(ascii_str(type(value).__name__)))      #3: `__name__` -> `__qualname__`
    try:
        value = as_unicode(value)
    except UnicodeDecodeError:
        # We don't want to reveal the value in the traceback etc.
        raise DataConversionError('contains non-UTF-8 binary data')              #3: add: `from None`
    if not value.strip():
        raise DataConversionError('an empty or whitespace-only value')
    value = value.encode('utf-8')                                                #3--
    assert isinstance(value, str)
    yield value
Exemple #3
0
 def _verify_length(self, value):
     value_length = len(value)
     if self.max_length is not None and value_length > self.max_length:
         raise DataConversionError(
             'too long string (its length: {} characters; '
             'maximum valid length: {} characters)'.format(
                 value_length, self.max_length))
 def generate_output_items(self):
     # type: () -> Iterator[NameValuePair]
     for (output_name, converted_value_cell
          ) in self._output_name_to_converted_value_cell.items():
         possible_input_names = self.iter_input_names_for_output_name(
             output_name)
         with DataConversionError.sublocation(possible_input_names):
             yield output_name, converted_value_cell.output
Exemple #5
0
def _adjust_token_max_age(value):
    # type: (...) -> int
    orig_value = value
    value = int(value)
    if value == orig_value and not isinstance(orig_value, bool):
        yield value
    else:
        raise DataConversionError('{!r} is not an integer number'.format(orig_value))
Exemple #6
0
 def _convert_flag_string(self, value):
     word = value.lower()
     if not self._true_flag_strings and not self._false_flag_strings:
         raise DataConversionError(
             '{!a} is an illegal value (for this item, strings '
             'cannot be converted to Boolean values)'.format(word))
     if word in self._true_flag_strings:
         word = True
     elif word in self._false_flag_strings:
         word = False
     else:
         raise DataConversionError(
             '{!a} is an illegal value (for this item these are the only '
             'strings that can be converted to Boolean values: {})'.format(
                 word, ', '.join(
                     sorted(map(ascii, self._true_flag_strings)) +
                     sorted(map(ascii, self._false_flag_strings)))))
     return word
 def verify_required_input_items_collected(self, required_input_names):
     # type: (AbstractSet) -> None
     uncollected = required_input_names - self._collected_input_names
     if uncollected:
         raise DataConversionError(
             'the following required items are missing or have '
             'been skipped as effectively NULL-like (i.e., not '
             'carrying any meaningful data): {}'.format(', '.join(
                 sorted(
                     repr(ascii_str(input_name))
                     for input_name in uncollected))))
Exemple #8
0
    def verify_is_regular_iterable_collection(cls, value):
        # type: (Value) -> None
        """
        A helper that can to be used in subclasses: verify that for the
        given `value` --

        * `isinstance(value, typing.Iterable)` is true, **but**
        * `isinstance(value, typing.Mapping)` is *not* true, and
        * `isinstance(value, str)` is *not* true, and
        * `isinstance(value, (bytes, bytearray, memoryview))` is *not* true.

        If the result of the above verification is negative, a
        `DataConversionError` with an appropriate message is raised.
        """
        cls.verify_isinstance(value, Iterable, 'expected a collection')
        if isinstance(value, Mapping):
            raise DataConversionError(
                'expected a collection but *not* a mapping')
        if isinstance(value, str):
            raise DataConversionError('expected a collection, *not* a string')
        if isinstance(value, (bytes, bytearray, memoryview)):
            raise DataConversionError(
                'expected a collection, *not* a binary data object')
Exemple #9
0
    def verify_in(value, container, error_message=None):
        # type: (Value, Container, Optional[String]) -> None
        """
        A helper that can to be used in subclasses: verify
        that `value in container` is true. If not, raise
        `DataConversionError(error_message)` or -- if
        `error_message` is unspecified or specified as
        `None` -- a `DataConversionError` with an automatically
        generated `"... is not in ..."` message.

        """
        if value not in container:
            if error_message is None:
                error_message = '{!a} is not in {!a}'.format(value, container)
            raise DataConversionError(error_message)
Exemple #10
0
 def validate_input_names(self, data):
     # type: (Iterator) -> (Sequence[NameValuePair])
     """
     Note: this method works in an eager (not lazy) manner (in
     particular, is not a generator and does not return an iterator,
     but a sequence) -- because we want to emphasize that we do
     *not* want to defer the validation, but to have it performed
     immediately.
     """
     validated = []
     for input_name, input_value in data:
         if not isinstance(input_name, str):
             raise DataConversionError(
                 'unexpected non-string key ({!a}) in '
                 'the mapping'.format(input_name))
         validated.append((input_name, input_value))
     return validated
Exemple #11
0
 def verify_isinstance(value, type_spec, error_message=None):
     # type: (Value, TypeSpec, Optional[String]) -> None
     """
     A helper that can to be used in subclasses: verify that
     `isinstance(value, type_spec)` is true. If not, raise
     `DataConversionError(error_message)` or -- if `error_message`
     is unspecified or specified as `None` -- a `DataConversionError`
     with an automatically generated `"unexpected type of..."`-like
     message.
     """
     if not isinstance(value, type_spec):
         if error_message is None:
             if isinstance(type_spec, tuple):
                 error_message = 'unexpected type of {!a}'.format(value)
             else:
                 safe_class_name = ascii_str(type_spec.__qualname__)
                 error_message = 'unexpected type of {!a} (should be a {})'.format(
                     value, safe_class_name)
         raise DataConversionError(error_message)
Exemple #12
0
 def __call__(self, data):
     # type: (Value) -> Iterator
     with self.state_bookkeeper_context() as bookkeeper:
         input_name_value_pairs = self.generate_input_name_value_pairs(data)
         input_name_value_pairs = self.validate_input_names(
             input_name_value_pairs)
         input_name_value_pairs = bookkeeper.preprocess_input_items(
             input_name_value_pairs)
         for input_name, input_value in input_name_value_pairs:
             with DataConversionError.sublocation(input_name):
                 item_conv = self._input_name_to_converter.get(
                     input_name, self._free_item_converter)
                 for output_name, converted_value_cell in item_conv(
                     (input_name, input_value)):
                     bookkeeper.collect_converted_item(
                         input_name, output_name, converted_value_cell)
         bookkeeper.verify_required_input_items_collected(
             self._required_input_names)
         output_name_value_pairs = bookkeeper.generate_output_items()
         for assembled_data in self._assembling_converter(
                 output_name_value_pairs):
             yield assembled_data
 def __add__(self, other):
     # type: (Cell) -> Cell
     if isinstance(other, StemCell):
         return self
     raise DataConversionError('data duplication detected')
Exemple #14
0
 def illegal_item_error_factory(_data):
     return DataConversionError('illegal item name')
Exemple #15
0
 def generate_output_elements(self, input_elements):
     # type: (Iterator[Value]) -> Iterator[Value]
     for index, value in enumerate(input_elements):
         with DataConversionError.sublocation(index):
             for converted_value in self._element_converter(value):
                 yield converted_value
Exemple #16
0
 def default_error_factory(_data):
     # type: (Value) -> BaseException
     return DataConversionError('unspecified error')