def test_identity(self): value = "0221" self.assertEqual(undefined_to_string(string_to_undefined(value)), value) value = "48 50 50 49" self.assertEqual(string_to_undefined(undefined_to_string(value)), value)
def test_undefined_to_string(self): self.assertEqual(undefined_to_string("48 50 50 49"), "0221") self.assertEqual(undefined_to_string("48 50 50 49 "), "0221") self.assertRaises(ValueError, undefined_to_string, "") self.assertRaises(ValueError, undefined_to_string, "foo") self.assertRaises(ValueError, undefined_to_string, "48 50 50 49")
def _convert_to_python(self, value): """ Convert one raw value to its corresponding python type. :param value: the raw value to be converted :type value: string :return: the value converted to its corresponding python type :raise ExifValueError: if the conversion fails """ if self.type == 'Ascii': # The value may contain a Datetime for format in self._datetime_formats: try: t = time.strptime(value, format) except ValueError: continue else: return datetime.datetime(*t[:6]) # Or a Date (e.g. Exif.GPSInfo.GPSDateStamp) for format in self._date_formats: try: t = time.strptime(value, format) except ValueError: continue else: return datetime.date(*t[:3]) # Default to string. # There is currently no charset conversion. # TODO: guess the encoding and decode accordingly into unicode # where relevant. return value elif self.type in ('Byte', 'SByte'): return value elif self.type == 'Comment': if value.startswith('charset='): charset, val = value.split(' ', 1) charset = charset.split('=')[1].strip('"') encoding = self._match_encoding(charset) return val.decode(encoding, 'replace') else: # No encoding defined. try: return value.decode('utf-8') except UnicodeError: return value elif self.type in ('Short', 'SShort'): try: return int(value) except ValueError: raise ExifValueError(value, self.type) elif self.type in ('Long', 'SLong'): try: return long(value) except ValueError: raise ExifValueError(value, self.type) elif self.type in ('Rational', 'SRational'): try: r = make_fraction(value) except (ValueError, ZeroDivisionError): raise ExifValueError(value, self.type) else: if self.type == 'Rational' and r.numerator < 0: raise ExifValueError(value, self.type) return r elif self.type == 'Undefined': # There is currently no charset conversion. # TODO: guess the encoding and decode accordingly into unicode # where relevant. return undefined_to_string(value) raise ExifValueError(value, self.type)
def _convert_to_python(self, value): """ Convert one raw value to its corresponding python type. :param value: the raw value to be converted :type value: string :return: the value converted to its corresponding python type :raise ExifValueError: if the conversion fails """ if self.type == 'Ascii': # The value may contain a Datetime for format in self._datetime_formats: try: t = time.strptime(value, format) except ValueError: continue else: return datetime.datetime(*t[:6]) # Or a Date (e.g. Exif.GPSInfo.GPSDateStamp) for format in self._date_formats: try: t = time.strptime(value, format) except ValueError: continue else: return datetime.date(*t[:3]) # Default to string. # There is currently no charset conversion. # TODO: guess the encoding and decode accordingly into unicode # where relevant. return value elif self.type in ('Byte', 'SByte'): if isinstance(value, bytes): return value.decode('utf-8') return value elif self.type == 'Comment': if isinstance(value, str): if value.startswith('charset='): charset, val = value.split(' ', 1) return val return value if value.startswith(b'charset='): charset = charset.split('=')[1].strip('"') encoding = self._match_encoding(charset) return val.decode(encoding, 'replace') else: # No encoding defined. try: return value.decode('utf-8') except UnicodeError: pass return value elif self.type in ('Short', 'SShort'): try: return int(value) except ValueError: raise ExifValueError(value, self.type) elif self.type in ('Long', 'SLong'): try: return int(value) except ValueError: raise ExifValueError(value, self.type) elif self.type in ('Rational', 'SRational'): try: r = make_fraction(value) except (ValueError, ZeroDivisionError): raise ExifValueError(value, self.type) else: if self.type == 'Rational' and r.numerator < 0: raise ExifValueError(value, self.type) return r elif self.type == 'Undefined': # There is currently no charset conversion. # TODO: guess the encoding and decode accordingly into unicode # where relevant. return undefined_to_string(value) raise ExifValueError(value, self.type)
def test_undefined_to_string_invalid(uval): with pytest.raises(ValueError): undefined_to_string(uval)
def test_undefined_to_string_oneway(uval, sval): assert undefined_to_string(uval) == sval
def test_undefined_to_string_invertible(uval, sval): sxval = undefined_to_string(uval) uxval = string_to_undefined(sval) assert sval == sxval assert uval == uxval