This is an automated email from the ASF dual-hosted git repository. rskraba pushed a commit to branch branch-1.11 in repository https://gitbox.apache.org/repos/asf/avro.git
commit b5bd312324d5a47890b3e8a802995f1d0c4346bb Author: Igor Izvekov <[email protected]> AuthorDate: Fri Jun 17 19:31:05 2022 +0300 AVRO-3521: "Scale" property from decimal object (#1689) * AVRO-3521 * Fixed style for "AVRO-3521" * Changed from 'a positive integer' to 'a non-negative integer' (by RyanSkraba's improvement). * Update error message in test Co-authored-by: Ryan Skraba <[email protected]> --- lang/py/avro/io.py | 16 ++++++++-------- lang/py/avro/schema.py | 2 +- lang/py/avro/test/test_io.py | 14 ++++++++++++++ lang/py/avro/test/test_schema.py | 2 +- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/lang/py/avro/io.py b/lang/py/avro/io.py index be81d9b6d..998dcd863 100644 --- a/lang/py/avro/io.py +++ b/lang/py/avro/io.py @@ -699,8 +699,8 @@ class DatumReader: 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() @@ -711,8 +711,8 @@ class DatumReader: 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) @@ -1067,8 +1067,8 @@ class DatumWriter: 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: @@ -1080,8 +1080,8 @@ class DatumWriter: 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 --git a/lang/py/avro/schema.py b/lang/py/avro/schema.py index 064c9d134..4885e333f 100644 --- a/lang/py/avro/schema.py +++ b/lang/py/avro/schema.py @@ -303,7 +303,7 @@ class DecimalLogicalSchema(LogicalSchema): 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}.") diff --git a/lang/py/avro/test/test_io.py b/lang/py/avro/test/test_io.py index 6ca3a61b8..29dd82130 100644 --- a/lang/py/avro/test/test_io.py +++ b/lang/py/avro/test/test_io.py @@ -71,6 +71,16 @@ SCHEMAS_TO_VALIDATE = tuple( }, 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 @@ SCHEMAS_TO_VALIDATE = tuple( {"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}), diff --git a/lang/py/avro/test/test_schema.py b/lang/py/avro/test/test_schema.py index ed101632e..5a4949301 100644 --- a/lang/py/avro/test/test_schema.py +++ b/lang/py/avro/test/test_schema.py @@ -421,7 +421,7 @@ IGNORED_LOGICAL_TYPE = [ ), 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},
