Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-avro for openSUSE:Factory checked in at 2022-08-06 22:07:54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-avro (Old) and /work/SRC/openSUSE:Factory/.python-avro.new.1521 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-avro" Sat Aug 6 22:07:54 2022 rev:12 rq:993435 version:1.11.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-avro/python-avro.changes 2021-11-17 01:15:31.630191456 +0100 +++ /work/SRC/openSUSE:Factory/.python-avro.new.1521/python-avro.changes 2022-08-06 22:08:02.526636320 +0200 @@ -1,0 +2,21 @@ +Thu Aug 4 09:32:11 UTC 2022 - Otto Hollmann <otto.hollm...@suse.com> + +- Update to 1.11.1 (from GitHub release notes): + - Avro specification + - Clarify which names are allowed to be qualified with + namespaces + - Inconsistent behaviour on types as invalid names + - Clarify how fullnames are created, with example + - IDL: add syntax to create optional fields + - Improve docs for logical type annotation + - Python + - Scale assignment optimization + - "Scale" property from decimal object + - Byte reading in avro.io does not assert bytes read + - validate the default value of an enum field + - Pass LogicalType to BytesDecimalSchema + - Website + - Website refactor + - Document IDL support in IDEs + +------------------------------------------------------------------- Old: ---- avro-1.11.0.tar.gz New: ---- avro-1.11.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-avro.spec ++++++ --- /var/tmp/diff_new_pack.5Tfjf4/_old 2022-08-06 22:08:04.970643425 +0200 +++ /var/tmp/diff_new_pack.5Tfjf4/_new 2022-08-06 22:08:04.978643448 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-avro # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define skip_python2 1 Name: python-avro -Version: 1.11.0 +Version: 1.11.1 Release: 0 Summary: A serialization and RPC framework for Python License: Apache-2.0 ++++++ avro-1.11.0.tar.gz -> avro-1.11.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/avro-1.11.0/PKG-INFO new/avro-1.11.1/PKG-INFO --- old/avro-1.11.0/PKG-INFO 2021-10-27 17:12:45.792555300 +0200 +++ new/avro-1.11.1/PKG-INFO 2022-07-31 17:26:28.704221500 +0200 @@ -1,18 +1,18 @@ Metadata-Version: 2.1 Name: avro -Version: 1.11.0 +Version: 1.11.1 Summary: Avro is a serialization and RPC framework. Home-page: https://avro.apache.org/ Author: Apache Avro Author-email: d...@avro.apache.org License: Apache License 2.0 Keywords: avro,serialization,rpc -Platform: UNKNOWN Classifier: License :: OSI Approved :: Apache Software License Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 Classifier: Development Status :: 5 - Production/Stable Requires-Python: >=3.6 Description-Content-Type: text/markdown @@ -38,5 +38,3 @@ ### License, Credits and Acknowledgements License, credits and acknowledgements are maintained in the [LICENSE.txt](https://github.com/apache/avro/blob/master/LICENSE.txt) and [NOTICE.txt](https://github.com/apache/avro/blob/master/NOTICE.txt) in the source code repository. Those files are also included with the installed package. - - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/avro-1.11.0/avro/VERSION.txt new/avro-1.11.1/avro/VERSION.txt --- old/avro-1.11.0/avro/VERSION.txt 2021-10-20 16:06:29.000000000 +0200 +++ new/avro-1.11.1/avro/VERSION.txt 2022-07-26 21:29:56.000000000 +0200 @@ -1 +1 @@ -1.11.0 \ No newline at end of file +1.11.1 \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/avro-1.11.0/avro/__main__.py new/avro-1.11.1/avro/__main__.py --- old/avro-1.11.0/avro/__main__.py 2021-10-13 11:58:28.000000000 +0200 +++ new/avro-1.11.1/avro/__main__.py 2022-02-23 17:45:22.000000000 +0100 @@ -171,7 +171,10 @@ def iter_csv(info: IO[AnyStr], schema: avro.schema.RecordSchema) -> Generator[Dict[str, object], None, None]: header = [field.name for field in schema.fields] - for row in csv.reader(getattr(i, "decode", lambda: i)() for i in info): + # If i is bytes, decode into a string. + # If i is a string, no need to decode. + csv_data = (cast(str, getattr(i, "decode", lambda: i)()) for i in info) + for row in csv.reader(csv_data): values = [convert(v, f) for v, f in zip(row, schema.fields)] yield dict(zip(header, values)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/avro-1.11.0/avro/datafile.py new/avro-1.11.1/avro/datafile.py --- old/avro-1.11.0/avro/datafile.py 2021-10-13 11:58:28.000000000 +0200 +++ new/avro-1.11.1/avro/datafile.py 2022-02-23 17:45:22.000000000 +0100 @@ -160,7 +160,7 @@ _datum_writer: avro.io.DatumWriter _encoder: avro.io.BinaryEncoder _header_written: bool - _writer: BinaryIO + _writer: IO[bytes] block_count: int sync_marker: bytes @@ -170,7 +170,7 @@ """If the schema is not present, presume we're appending.""" if hasattr(writer, "mode") and "b" not in writer.mode: warnings.warn(avro.errors.AvroWarning(f"Writing binary data to a writer {writer!r} that's opened for text")) - bytes_writer = getattr(writer, "buffer", writer) + bytes_writer = cast(IO[bytes], getattr(writer, "buffer", writer)) self._writer = bytes_writer self._encoder = avro.io.BinaryEncoder(bytes_writer) self._datum_writer = datum_writer @@ -202,7 +202,7 @@ self.datum_writer.writers_schema = writers_schema @property - def writer(self) -> BinaryIO: + def writer(self) -> IO[bytes]: return self._writer @property @@ -307,7 +307,7 @@ _datum_reader: avro.io.DatumReader _file_length: int _raw_decoder: avro.io.BinaryDecoder - _reader: BinaryIO + _reader: IO[bytes] block_count: int sync_marker: bytes @@ -315,9 +315,9 @@ # TODO(hammer): allow user to specify the encoder def __init__(self, reader: IO[AnyStr], datum_reader: avro.io.DatumReader) -> None: - if "b" not in reader.mode: + if hasattr(reader, "mode") and "b" not in reader.mode: warnings.warn(avro.errors.AvroWarning(f"Reader binary data from a reader {reader!r} that's opened for text")) - bytes_reader = getattr(reader, "buffer", reader) + bytes_reader = cast(IO[bytes], getattr(reader, "buffer", reader)) self._reader = bytes_reader self._raw_decoder = avro.io.BinaryDecoder(bytes_reader) self._datum_decoder = None # Maybe reset at every block. @@ -337,7 +337,7 @@ return self @property - def reader(self) -> BinaryIO: + def reader(self) -> IO[bytes]: return self._reader @property diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/avro-1.11.0/avro/errors.py new/avro-1.11.1/avro/errors.py --- old/avro-1.11.0/avro/errors.py 2021-10-13 11:58:28.000000000 +0200 +++ new/avro-1.11.1/avro/errors.py 2022-02-23 17:45:22.000000000 +0100 @@ -32,6 +32,10 @@ """The base class for exceptions in avro.""" +class InvalidAvroBinaryEncoding(AvroException): + """For invalid numbers of bytes read.""" + + class SchemaParseException(AvroException): """Raised when a schema failed to parse.""" @@ -40,6 +44,10 @@ """User attempted to parse a schema with an invalid name.""" +class InvalidDefault(SchemaParseException): + """User attempted to parse a schema with an invalid default.""" + + class AvroWarning(UserWarning): """Base class for warnings.""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/avro-1.11.0/avro/io.py new/avro-1.11.1/avro/io.py --- old/avro-1.11.0/avro/io.py 2021-10-13 11:58:28.000000000 +0200 +++ new/avro-1.11.1/avro/io.py 2022-06-24 20:02:21.000000000 +0200 @@ -90,7 +90,7 @@ import struct import warnings from typing import ( - BinaryIO, + IO, Deque, Generator, Iterable, @@ -206,23 +206,28 @@ class BinaryDecoder: """Read leaf values.""" - _reader: BinaryIO + _reader: IO[bytes] - def __init__(self, reader: BinaryIO) -> None: + def __init__(self, reader: IO[bytes]) -> None: """ reader is a Python object on which we can call read, seek, and tell. """ self._reader = reader @property - def reader(self) -> BinaryIO: + def reader(self) -> IO[bytes]: return self._reader def read(self, n: int) -> bytes: """ Read n bytes. """ - return self.reader.read(n) + if n < 0: + raise avro.errors.InvalidAvroBinaryEncoding(f"Requested {n} bytes to read, expected positive integer.") + read_bytes = self.reader.read(n) + if len(read_bytes) != n: + raise avro.errors.InvalidAvroBinaryEncoding(f"Read {len(read_bytes)} bytes, expected {n} bytes") + return read_bytes def read_null(self) -> None: """ @@ -410,16 +415,16 @@ class BinaryEncoder: """Write leaf values.""" - _writer: BinaryIO + _writer: IO[bytes] - def __init__(self, writer: BinaryIO) -> None: + def __init__(self, writer: IO[bytes]) -> None: """ writer is a Python object on which we can call write. """ self._writer = writer @property - def writer(self) -> BinaryIO: + def writer(self) -> IO[bytes]: return self._writer def write(self, datum: bytes) -> None: @@ -514,7 +519,7 @@ size_in_bits = size * 8 offset_bits = size_in_bits - bits_req - mask = 2 ** size_in_bits - 1 + mask = 2**size_in_bits - 1 bit = 1 for i in range(bits_req): mask ^= bit @@ -579,7 +584,7 @@ self.write_long(microseconds) def _timedelta_total_microseconds(self, timedelta_: datetime.timedelta) -> int: - return timedelta_.microseconds + (timedelta_.seconds + timedelta_.days * 24 * 3600) * 10 ** 6 + return timedelta_.microseconds + (timedelta_.seconds + timedelta_.days * 24 * 3600) * 10**6 def write_timestamp_millis_long(self, datum: datetime.datetime) -> None: """ @@ -694,8 +699,8 @@ warnings.warn(avro.errors.IgnoredLogicalType(f"Invalid decimal precision {precision}. Must be a positive integer.")) return decoder.read_bytes() scale = writers_schema.get_prop("scale") - if not (isinstance(scale, int) and scale > 0): - warnings.warn(avro.errors.IgnoredLogicalType(f"Invalid decimal scale {scale}. Must be a positive integer.")) + if not (isinstance(scale, int) and scale >= 0): + warnings.warn(avro.errors.IgnoredLogicalType(f"Invalid decimal scale {scale}. Must be a non-negative integer.")) return decoder.read_bytes() return decoder.read_decimal_from_bytes(precision, scale) return decoder.read_bytes() @@ -706,8 +711,8 @@ warnings.warn(avro.errors.IgnoredLogicalType(f"Invalid decimal precision {precision}. Must be a positive integer.")) return self.read_fixed(writers_schema, readers_schema, decoder) scale = writers_schema.get_prop("scale") - if not (isinstance(scale, int) and scale > 0): - warnings.warn(avro.errors.IgnoredLogicalType(f"Invalid decimal scale {scale}. Must be a positive integer.")) + if not (isinstance(scale, int) and scale >= 0): + warnings.warn(avro.errors.IgnoredLogicalType(f"Invalid decimal scale {scale}. Must be a non-negative integer.")) return self.read_fixed(writers_schema, readers_schema, decoder) return decoder.read_decimal_from_fixed(precision, scale, writers_schema.size) return self.read_fixed(writers_schema, readers_schema, decoder) @@ -1062,8 +1067,8 @@ if writers_schema.type == "bytes": if logical_type == "decimal": scale = writers_schema.get_prop("scale") - if not (isinstance(scale, int) and scale > 0): - warnings.warn(avro.errors.IgnoredLogicalType(f"Invalid decimal scale {scale}. Must be a positive integer.")) + if not (isinstance(scale, int) and scale >= 0): + warnings.warn(avro.errors.IgnoredLogicalType(f"Invalid decimal scale {scale}. Must be a non-negative integer.")) elif not isinstance(datum, decimal.Decimal): warnings.warn(avro.errors.IgnoredLogicalType(f"{datum} is not a decimal type")) else: @@ -1075,8 +1080,8 @@ if logical_type == "decimal": scale = writers_schema.get_prop("scale") size = writers_schema.size - if not (isinstance(scale, int) and scale > 0): - warnings.warn(avro.errors.IgnoredLogicalType(f"Invalid decimal scale {scale}. Must be a positive integer.")) + if not (isinstance(scale, int) and scale >= 0): + warnings.warn(avro.errors.IgnoredLogicalType(f"Invalid decimal scale {scale}. Must be a non-negative integer.")) elif not isinstance(datum, decimal.Decimal): warnings.warn(avro.errors.IgnoredLogicalType(f"{datum} is not a decimal type")) else: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/avro-1.11.0/avro/name.py new/avro-1.11.1/avro/name.py --- old/avro-1.11.0/avro/name.py 2021-10-13 11:58:28.000000000 +0200 +++ new/avro-1.11.1/avro/name.py 2022-06-24 20:02:21.000000000 +0200 @@ -20,7 +20,7 @@ """Contains the Name classes.""" from typing import TYPE_CHECKING, Dict, Optional -from avro.constants import VALID_TYPES +from avro.constants import PRIMITIVE_TYPES if TYPE_CHECKING: from avro.schema import NamedSchema @@ -154,7 +154,7 @@ """ to_add = Name(name_attr, space_attr, self.default_namespace) - if to_add.fullname in VALID_TYPES: + if to_add.fullname in PRIMITIVE_TYPES: raise avro.errors.SchemaParseException(f"{to_add.fullname} is a reserved type name.") if to_add.fullname in self.names: raise avro.errors.SchemaParseException(f'The name "{to_add.fullname}" is already in use.') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/avro-1.11.0/avro/schema.py new/avro-1.11.1/avro/schema.py --- old/avro-1.11.0/avro/schema.py 2021-10-13 11:58:28.000000000 +0200 +++ new/avro-1.11.1/avro/schema.py 2022-06-24 20:02:21.000000000 +0200 @@ -303,7 +303,7 @@ raise avro.errors.IgnoredLogicalType(f"Invalid decimal precision {precision}. Max is {max_precision}.") if not isinstance(scale, int) or scale < 0: - raise avro.errors.IgnoredLogicalType(f"Invalid decimal scale {scale}. Must be a positive integer.") + raise avro.errors.IgnoredLogicalType(f"Invalid decimal scale {scale}. Must be a non-negative integer.") if scale > precision: raise avro.errors.IgnoredLogicalType(f"Invalid decimal scale {scale}. Cannot be greater than precision {precision}.") @@ -414,18 +414,15 @@ @arg writer: the schema to match against @return bool """ - return ( - self.type == writer.type - or { - "float": self.type == "double", - "int": self.type in {"double", "float", "long"}, - "long": self.type - in { - "double", - "float", - }, - }.get(writer.type, False) - ) + return self.type == writer.type or { + "float": self.type == "double", + "int": self.type in {"double", "float", "long"}, + "long": self.type + in { + "double", + "float", + }, + }.get(writer.type, False) def to_json(self, names=None): if len(self.props) == 1: @@ -583,6 +580,11 @@ if doc is not None: self.set_prop("doc", doc) + if other_props and "default" in other_props: + default = other_props["default"] + if default not in symbols: + raise avro.errors.InvalidDefault(f"Enum default '{default}' is not a valid member of symbols '{symbols}'") + @property def symbols(self) -> Sequence[str]: symbols = self.get_prop("symbols") @@ -1067,7 +1069,7 @@ def make_bytes_decimal_schema(other_props): """Make a BytesDecimalSchema from just other_props.""" - return BytesDecimalSchema(other_props.get("precision"), other_props.get("scale", 0)) + return BytesDecimalSchema(other_props.get("precision"), other_props.get("scale", 0), other_props) def make_logical_schema(logical_type, type_, other_props): @@ -1130,7 +1132,7 @@ size = json_data.get("size") if logical_type == "decimal": precision = json_data.get("precision") - scale = 0 if json_data.get("scale") is None else json_data.get("scale") + scale = json_data.get("scale", 0) try: return FixedDecimalSchema(size, name, precision, scale, namespace, names, other_props) except avro.errors.IgnoredLogicalType as warning: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/avro-1.11.0/avro/test/gen_interop_data.py new/avro-1.11.1/avro/test/gen_interop_data.py --- old/avro-1.11.0/avro/test/gen_interop_data.py 2021-10-13 11:58:28.000000000 +0200 +++ new/avro-1.11.1/avro/test/gen_interop_data.py 2022-02-23 17:45:22.000000000 +0100 @@ -54,6 +54,7 @@ def gen_data(codec: str, datum_writer: avro.io.DatumWriter, interop_schema: avro.schema.Schema) -> bytes: with io.BytesIO() as file_, avro.datafile.DataFileWriter(file_, datum_writer, interop_schema, codec=codec) as dfw: + dfw.set_meta("user_metadata", b"someByteArray") dfw.append(DATUM) dfw.flush() return file_.getvalue() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/avro-1.11.0/avro/test/test_datafile_interop.py new/avro-1.11.1/avro/test/test_datafile_interop.py --- old/avro-1.11.0/avro/test/test_datafile_interop.py 2021-10-13 11:58:28.000000000 +0200 +++ new/avro-1.11.1/avro/test/test_datafile_interop.py 2022-02-23 17:45:22.000000000 +0100 @@ -37,11 +37,16 @@ for filename in _INTEROP_DATA_DIR.iterdir(): self.assertGreater(os.stat(filename).st_size, 0) base_ext = filename.stem.split("_", 1) - if len(base_ext) < 2 or base_ext[1] not in avro.codecs.KNOWN_CODECS: + if len(base_ext) > 1 and base_ext[1] not in avro.codecs.KNOWN_CODECS: print(f"SKIPPING {filename} due to an unsupported codec\n") continue i = None with self.subTest(filename=filename), avro.datafile.DataFileReader(filename.open("rb"), avro.io.DatumReader()) as dfr: + + user_metadata = dfr.get_meta("user_metadata") + if user_metadata is not None: + self.assertEqual(user_metadata, b"someByteArray") + for i, datum in enumerate(cast(avro.datafile.DataFileReader, dfr), 1): self.assertIsNotNone(datum) self.assertIsNotNone(i) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/avro-1.11.0/avro/test/test_io.py new/avro-1.11.1/avro/test/test_io.py --- old/avro-1.11.0/avro/test/test_io.py 2021-10-13 11:58:28.000000000 +0200 +++ new/avro-1.11.1/avro/test/test_io.py 2022-06-24 20:02:21.000000000 +0200 @@ -72,6 +72,16 @@ decimal.Decimal("-3.1415"), ), ( + { + "type": "fixed", + "logicalType": "decimal", + "name": "Test", + "size": 8, + "precision": 1, + }, + decimal.Decimal("3"), + ), + ( {"type": "bytes", "logicalType": "decimal", "precision": 5, "scale": 4}, decimal.Decimal("3.1415"), ), @@ -79,6 +89,10 @@ {"type": "bytes", "logicalType": "decimal", "precision": 5, "scale": 4}, decimal.Decimal("-3.1415"), ), + ( + {"type": "bytes", "logicalType": "decimal", "precision": 1}, + decimal.Decimal("3"), + ), ({"type": "enum", "name": "Test", "symbols": ["A", "B"]}, "B"), ({"type": "array", "items": "long"}, [1, 3, 2]), ({"type": "map", "values": "long"}, {"a": 1, "b": 3, "c": 2}), @@ -163,6 +177,14 @@ }, {"value": {"car": {"value": "head"}, "cdr": {"value": None}}}, ), + ( + {"type": "record", "name": "record", "fields": [{"name": "value", "type": "int"}, {"name": "next", "type": ["null", "record"]}]}, + {"value": 0, "next": {"value": 1, "next": None}}, + ), + ( + {"type": "record", "name": "ns.long", "fields": [{"name": "value", "type": "int"}, {"name": "next", "type": ["null", "ns.long"]}]}, + {"value": 0, "next": {"value": 1, "next": None}}, + ), ) ) @@ -426,6 +448,58 @@ self.assertEqual(datum_to_read, datum_read) +class TestIncompatibleSchemaReading(unittest.TestCase): + def test_deserialization_fails(self) -> None: + + reader_schema = avro.schema.parse( + json.dumps( + { + "namespace": "example.avro", + "type": "record", + "name": "User", + "fields": [ + {"name": "name", "type": "string"}, + {"name": "age", "type": "int"}, + {"name": "location", "type": "string"}, + ], + } + ) + ) + writer_schema = avro.schema.parse( + json.dumps( + { + "namespace": "example.avro", + "type": "record", + "name": "IncompatibleUser", + "fields": [ + {"name": "name", "type": "int"}, + {"name": "age", "type": "int"}, + {"name": "location", "type": "string"}, + ], + } + ) + ) + + incompatibleUserRecord = {"name": 100, "age": 21, "location": "Woodford"} + writer = avro.io.DatumWriter(writer_schema) + with io.BytesIO() as writer_bio: + enc = avro.io.BinaryEncoder(writer_bio) + writer.write(incompatibleUserRecord, enc) + enc_bytes = writer_bio.getvalue() + reader = avro.io.DatumReader(reader_schema) + with io.BytesIO(enc_bytes) as reader_bio: + self.assertRaises(avro.errors.InvalidAvroBinaryEncoding, reader.read, avro.io.BinaryDecoder(reader_bio)) + + incompatibleUserRecord = {"name": -10, "age": 21, "location": "Woodford"} + with io.BytesIO() as writer_bio: + enc = avro.io.BinaryEncoder(writer_bio) + writer.write(incompatibleUserRecord, enc) + enc_bytes = writer_bio.getvalue() + reader = avro.io.DatumReader(reader_schema) + with io.BytesIO(enc_bytes) as reader_bio: + self.assertRaises(avro.errors.InvalidAvroBinaryEncoding, reader.read, avro.io.BinaryDecoder(reader_bio)) + + class TestMisc(unittest.TestCase): def test_decimal_bytes_small_scale(self) -> None: """Avro should raise an AvroTypeException when attempting to write a decimal with a larger exponent than the schema's scale.""" @@ -585,6 +659,7 @@ SchemaPromotionTestCase(write_type, read_type) for write_type, read_type in itertools.combinations(("int", "long", "float", "double"), 2) ) suite.addTests(DefaultValueTestCase(field_type, default) for field_type, default in DEFAULT_VALUE_EXAMPLES) + suite.addTests(loader.loadTestsFromTestCase(TestIncompatibleSchemaReading)) return suite diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/avro-1.11.0/avro/test/test_schema.py new/avro-1.11.1/avro/test/test_schema.py --- old/avro-1.11.0/avro/test/test_schema.py 2021-10-13 11:58:28.000000000 +0200 +++ new/avro-1.11.1/avro/test/test_schema.py 2022-06-24 20:02:21.000000000 +0200 @@ -85,6 +85,7 @@ ENUM_EXAMPLES = [ ValidTestSchema({"type": "enum", "name": "Test", "symbols": ["A", "B"]}), ValidTestSchema({"type": "enum", "name": "AVRO2174", "symbols": ["nowhitespace"]}), + InvalidTestSchema({"type": "enum", "name": "bad_default", "symbols": ["A"], "default": "B"}, comment="AVRO-3229"), InvalidTestSchema({"type": "enum", "name": "Status", "symbols": "Normal Caution Critical"}), InvalidTestSchema({"type": "enum", "name": [0, 1, 1, 2, 3, 5, 8], "symbols": ["Golden", "Mean"]}), InvalidTestSchema({"type": "enum", "symbols": ["I", "will", "fail", "no", "name"]}), @@ -119,6 +120,19 @@ InvalidTestSchema([{"type": "array", "items": "long"}, {"type": "array", "items": "string"}]), ] +NAME_EXAMPLES = [ + ValidTestSchema({"type": "enum", "name": "record", "symbols": ["A", "B"]}), + ValidTestSchema({"type": "record", "name": "record", "fields": [{"name": "f", "type": "long"}]}), + InvalidTestSchema({"type": "enum", "name": "int", "symbols": ["A", "B"]}), + ValidTestSchema({"type": "enum", "name": "ns.int", "symbols": ["A", "B"]}), + ValidTestSchema({"type": "enum", "namespace": "ns", "name": "int", "symbols": ["A", "B"]}), + ValidTestSchema( + {"type": "record", "name": "LinkedList", "fields": [{"name": "value", "type": "int"}, {"name": "next", "type": ["null", "LinkedList"]}]} + ), + ValidTestSchema({"type": "record", "name": "record", "fields": [{"name": "value", "type": "int"}, {"name": "next", "type": ["null", "record"]}]}), + ValidTestSchema({"type": "record", "name": "ns.int", "fields": [{"name": "value", "type": "int"}, {"name": "next", "type": ["null", "ns.int"]}]}), +] + NAMED_IN_UNION_EXAMPLES = [ ValidTestSchema( { @@ -407,7 +421,7 @@ ), ValidTestSchema( {"type": "bytes", "logicalType": "decimal", "precision": 2, "scale": -2}, - warnings=[avro.errors.IgnoredLogicalType("Invalid decimal scale -2. Must be a positive integer.")], + warnings=[avro.errors.IgnoredLogicalType("Invalid decimal scale -2. Must be a non-negative integer.")], ), ValidTestSchema( {"type": "bytes", "logicalType": "decimal", "precision": -2, "scale": 2}, @@ -511,6 +525,7 @@ EXAMPLES += ARRAY_EXAMPLES EXAMPLES += MAP_EXAMPLES EXAMPLES += UNION_EXAMPLES +EXAMPLES += NAME_EXAMPLES EXAMPLES += NAMED_IN_UNION_EXAMPLES EXAMPLES += RECORD_EXAMPLES EXAMPLES += DOC_EXAMPLES @@ -642,16 +657,16 @@ } ) - bytes_decimal_schema = ValidTestSchema({"type": "bytes", "logicalType": "decimal", "precision": 4}) - fixed_decimal = fixed_decimal_schema.parse() self.assertEqual(4, fixed_decimal.get_prop("precision")) self.assertEqual(2, fixed_decimal.get_prop("scale")) self.assertEqual(2, fixed_decimal.get_prop("size")) + bytes_decimal_schema = ValidTestSchema({"type": "bytes", "logicalType": "decimal", "precision": 4}) bytes_decimal = bytes_decimal_schema.parse() self.assertEqual(4, bytes_decimal.get_prop("precision")) self.assertEqual(0, bytes_decimal.get_prop("scale")) + self.assertEqual("decimal", bytes_decimal.get_prop("logicalType")) def test_fixed_decimal_valid_max_precision(self): # An 8 byte number can represent any 18 digit number. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/avro-1.11.0/avro.egg-info/PKG-INFO new/avro-1.11.1/avro.egg-info/PKG-INFO --- old/avro-1.11.0/avro.egg-info/PKG-INFO 2021-10-27 17:12:45.000000000 +0200 +++ new/avro-1.11.1/avro.egg-info/PKG-INFO 2022-07-31 17:26:28.000000000 +0200 @@ -1,18 +1,18 @@ Metadata-Version: 2.1 Name: avro -Version: 1.11.0 +Version: 1.11.1 Summary: Avro is a serialization and RPC framework. Home-page: https://avro.apache.org/ Author: Apache Avro Author-email: d...@avro.apache.org License: Apache License 2.0 Keywords: avro,serialization,rpc -Platform: UNKNOWN Classifier: License :: OSI Approved :: Apache Software License Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 Classifier: Development Status :: 5 - Production/Stable Requires-Python: >=3.6 Description-Content-Type: text/markdown @@ -38,5 +38,3 @@ ### License, Credits and Acknowledgements License, credits and acknowledgements are maintained in the [LICENSE.txt](https://github.com/apache/avro/blob/master/LICENSE.txt) and [NOTICE.txt](https://github.com/apache/avro/blob/master/NOTICE.txt) in the source code repository. Those files are also included with the installed package. - - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/avro-1.11.0/avro.egg-info/entry_points.txt new/avro-1.11.1/avro.egg-info/entry_points.txt --- old/avro-1.11.0/avro.egg-info/entry_points.txt 2021-10-27 17:12:45.000000000 +0200 +++ new/avro-1.11.1/avro.egg-info/entry_points.txt 2022-07-31 17:26:28.000000000 +0200 @@ -1,3 +1,2 @@ [console_scripts] avro = avro.__main__:main - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/avro-1.11.0/setup.cfg new/avro-1.11.1/setup.cfg --- old/avro-1.11.0/setup.cfg 2021-10-27 17:12:45.793555300 +0200 +++ new/avro-1.11.1/setup.cfg 2022-07-31 17:26:28.704221500 +0200 @@ -19,6 +19,7 @@ Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 Development Status :: 5 - Production/Stable [bdist_wheel]