def __init__(self, *, vli_format: VarIntEncoding, max_bytes: Optional[int] = None, **kwargs: Any): encoding_info = varints.INTEGER_ENCODING_MAP.get(vli_format) if encoding_info is None: raise errors.ConfigurationError( "Invalid or unsupported integer encoding scheme: %r" % vli_format, field=self, ) format_endianness = typing.cast(str, encoding_info["endian"]) format_signedness = typing.cast(bool, encoding_info["signed"]) self.vli_format = vli_format self.max_bytes = max_bytes self._encode_integer_fn = typing.cast(Callable[[int], bytes], encoding_info["encode"]) self._decode_integer_fn = typing.cast(Callable[[BinaryIO], int], encoding_info["decode"]) super().__init__(endian=format_endianness, signed=format_signedness, **kwargs)
def __init__( self, *, encoding: str = "iso-8859-1", pad_byte: Optional[bytes] = None, **kwargs: Any ): if pad_byte is not None: if not isinstance(pad_byte, (bytes, bytearray)): raise errors.ConfigurationError( "`pad_byte` must be a bytes-like object.", field=self ) if len(pad_byte) != 1: raise errors.ConfigurationError( "`pad_byte` must be exactly one byte long.", field=self ) self.encoding = encoding self.pad_byte = pad_byte super().__init__(**kwargs)
def __init__(self, *choices: _Union["Field[Any]", Type["Struct"]], load_decider, dump_decider, **kwargs: Any): super().__init__(**kwargs) if any(isinstance(c, type) and issubclass(c, Field) for c in choices): raise errors.ConfigurationError( "You must pass an instance of a Field, not a class.", field=self) self.choices = choices self.load_decider = load_decider self.dump_decider = dump_decider
def __init__(self, *, format_string: str, endian: Optional[str] = None, **kwargs: Any): if format_string == "e" and sys.version_info[:2] < ( 3, 6): # pragma: no cover raise errors.ConfigurationError( "binary16 format not supported on this version of Python.", field=self) super().__init__(size=struct.calcsize(format_string), **kwargs) self.endian = endian or sys.byteorder if self.endian == "big": self.format_string = ">" + format_string elif self.endian == "little": self.format_string = "<" + format_string else: raise errors.ConfigurationError( "`endian` must be 'big' or 'little', got %r." % endian, field=self)
def get_final_element_count(self, field_values: StrDict) -> Optional[int]: """Calculate the number of elements in the array based on other fields' values. :param dict field_values: A dict mapping field names to their deserialized values. It doesn't need to have every value in the struct; if :attr:`count` references a field, it only requires that field to be present here. :return: The expected number of elements in this array, or ``None`` if the array doesn't have a fixed size. :rtype: int .. versionadded:: 0.6.1 .. versionchanged:: 0.8.0 Throws a `ConfigurationError` if this field's :attr:`count` is a `Field` but doesn't have an assigned name. """ if self.count is None: return None if isinstance(self.count, int): return self.count if isinstance(self.count, Field): name = self.count.name if name is None: # This will only happen if someone creates a field outside of a Struct # and passes it to this field as the count object. raise errors.ConfigurationError( "`count` field for %r has no assigned name." % self, field=self.count, ) elif isinstance(self.count, str): name = self.count else: raise TypeError("Unexpected type for `count`: %r" % type(self.count).__name__) # The number of fields in this array is a field that should already have been # loaded. if name not in field_values: raise errors.FieldReferenceError( "Array size depends on field %r but it wasn't found." % name, field=name, ) return typing.cast(int, field_values[name])
def __init__(self, *, size: int, resolution: str = "s", tz_aware: bool = False, endian: Optional[str] = None, signed: bool = True, **kwargs: Any): if resolution not in self._RESOLUTION_UNITS: raise errors.ConfigurationError( "Invalid resolution. Expected one of %s but got %r" % (", ".join(repr(k) for k in self._RESOLUTION_UNITS), resolution), field=self, ) super().__init__(size=size, **kwargs) self.endian = endian or sys.byteorder self.signed = signed self.resolution = resolution self.tz_aware = tz_aware self._units = self._RESOLUTION_UNITS[resolution]
def test_configuration_error__no_args_crashes(): with pytest.raises(ValueError, match=r"^At least one of `field`, .+$"): errors.ConfigurationError()
def test_configurationerror__default_messages(field, struct, obj, message): err = errors.ConfigurationError(field=field, struct=struct, obj=obj) assert str(err) == message