Skip to content

Conversation

@rowanseymour
Copy link

Fixes #4693

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Copilot AI review requested due to automatic review settings January 7, 2026 15:46
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a bug in DynamoDB number deserialization where numbers with trailing zeros that exceed 38 total digits (but have ≤38 significant digits) would fail to deserialize. The fix normalizes the decimal representation to remove trailing zeros before applying DynamoDB's 38-digit precision constraint.

Key Changes:

  • Modified _deserialize_n() to normalize decimal values before creating them in DYNAMODB_CONTEXT
  • Added test case for deserializing numbers with trailing zeros

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
boto3/dynamodb/types.py Updated _deserialize_n method to normalize decimal values before creating them with DYNAMODB_CONTEXT, removing trailing zeros that would otherwise cause precision errors
tests/unit/dynamodb/test_types.py Added test case to verify deserialization of large numbers with trailing zeros works correctly

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


def test_deserialize_decimal(self):
assert self.deserializer.deserialize({'N': '1.25'}) == Decimal('1.25')
assert self.deserializer.deserialize({'N': '1234567891234560000000000000000000000000'}) == Decimal('1.23456789123456E+39')
Copy link

Copilot AI Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test uses a different number than the one mentioned in the linked issue (#4693). The issue reports 1234567895171680000000000000000000000000 but this test uses 1234567891234560000000000000000000000000. Consider adding a test case with the exact number from the issue to ensure it's properly fixed.

Copilot uses AI. Check for mistakes.

def test_deserialize_decimal(self):
assert self.deserializer.deserialize({'N': '1.25'}) == Decimal('1.25')
assert self.deserializer.deserialize({'N': '1234567891234560000000000000000000000000'}) == Decimal('1.23456789123456E+39')
Copy link

Copilot AI Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding test cases for additional edge cases with trailing zeros to ensure comprehensive coverage:

  • Numbers with trailing zeros after the decimal point (e.g., '1.2500')
  • Negative numbers with trailing zeros (e.g., '-1234567891234560000000000000000000000000')
  • Numbers already in scientific notation (e.g., '1.23E+39')
  • Very small numbers with trailing zeros (e.g., '0.00001000')

Copilot uses AI. Check for mistakes.
@JustinTArthur
Copy link

There is already a pull request for this without needing the normalization step: #2913 I highly recommend it be considered for reopening.

@rowanseymour
Copy link
Author

@JustinTArthur not sure if the maintainers see comments on closed issues/PRs but yeah I think getting rid of Rounded on deserialization is even better.. is the claim that it's a breaking change because it affects serialization too?

This library should be able to read all values that DynamoDB accepts. Really there shouldn't be any validation of values coming from DynamoDB.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DynamoDB deserialization throws exception for big numbers

2 participants