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},

Reply via email to