Skip to content

Bug: custom serializer isn't being used by nested dict #4658

Closed
@LironEr

Description

@LironEr

Expected Behaviour

The custom serializer should be passed to all sub-functions

Current Behaviour

The custom serializer is not being called, it's passed only on the first jsonable_encoder run.
https://github.com/aws-powertools/powertools-lambda-python/blob/develop/aws_lambda_powertools/event_handler/openapi/encoders.py#L112

Code snippet

from aws_lambda_powertools.event_handler.openapi.encoders import jsonable_encoder
from bson import Decimal128


def custom_serializer(obj):
    if isinstance(obj, Decimal128):
        return int(obj.to_decimal())

    return obj


# work
print(jsonable_encoder(Decimal128('123'), custom_serializer=custom_serializer))

# doesn't work
print(jsonable_encoder({'dec': Decimal128('123')}, custom_serializer=custom_serializer))

Possible Solution

pass custom_serializer to all functions, as this is a recursive function as mentioned in #3892 (comment)

Steps to Reproduce

run the code snippet (:

Powertools for AWS Lambda (Python) version

2.40.1

AWS Lambda function runtime

3.11

Packaging format used

PyPi

Debugging logs

Traceback (most recent call last):
  File "xxxxxxxxxxxxxx/.venv/lib/python3.11/site-packages/aws_lambda_powertools/event_handler/openapi/encoders.py", line 279, in _dump_other
    data = dict(obj)
           ^^^^^^^^^
TypeError: 'Decimal128' object is not iterable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "xxxxxxxxxxxxxx/.venv/lib/python3.11/site-packages/aws_lambda_powertools/event_handler/openapi/encoders.py", line 283, in _dump_other
    data = vars(obj)
           ^^^^^^^^^
TypeError: vars() argument must have __dict__ attributeTraceback (most recent call last):
  File "xxxxxxxxxxxxxx/.venv/lib/python3.11/site-packages/aws_lambda_powertools/event_handler/openapi/encoders.py", line 279, in _dump_other
    data = dict(obj)
           ^^^^^^^^^
TypeError: 'Decimal128' object is not iterable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "xxxxxxxxxxxxxx/.venv/lib/python3.11/site-packages/aws_lambda_powertools/event_handler/openapi/encoders.py", line 283, in _dump_other
    data = vars(obj)
           ^^^^^^^^^
TypeError: vars() argument must have __dict__ attribute

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "xxxxxxxxxxxxxx/.venv/lib/python3.11/site-packages/aws_lambda_powertools/event_handler/openapi/encoders.py", line 147, in jsonable_encoder
    return _dump_other(
           ^^^^^^^^^^^^
  File "xxxxxxxxxxxxxx/.venv/lib/python3.11/site-packages/aws_lambda_powertools/event_handler/openapi/encoders.py", line 286, in _dump_other
    raise ValueError(errors) from e
ValueError: [TypeError("'Decimal128' object is not iterable"), TypeError('vars() argument must have __dict__ attribute')]

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "xxxxxxxxxxxxxx/c.py", line 19, in <module>
    print(jsonable_encoder({'dec': Decimal128('123')}, custom_serializer=custom_serializer))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "xxxxxxxxxxxxxx/.venv/lib/python3.11/site-packages/aws_lambda_powertools/event_handler/openapi/encoders.py", line 113, in jsonable_encoder
    return _dump_dict(
           ^^^^^^^^^^^
  File "xxxxxxxxxxxxxx/.venv/lib/python3.11/site-packages/aws_lambda_powertools/event_handler/openapi/encoders.py", line 226, in _dump_dict
    encoded_value = jsonable_encoder(
                    ^^^^^^^^^^^^^^^^^
  File "xxxxxxxxxxxxxx/.venv/lib/python3.11/site-packages/aws_lambda_powertools/event_handler/openapi/encoders.py", line 157, in jsonable_encoder
    raise SerializationError(
aws_lambda_powertools.event_handler.openapi.exceptions.SerializationError: ('Unable to serialize the object 123 as it is not a supported type. Error details: [TypeError("\'Decimal128\' object is not iterable"), TypeError(\'vars() argument must have __dict__ attribute\')]', 'See: https://docs.powertools.aws.dev/lambda/python/latest/core/event_handler/api_gateway/#serializing-objects')

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "xxxxxxxxxxxxxx/.venv/lib/python3.11/site-packages/aws_lambda_powertools/event_handler/openapi/encoders.py", line 147, in jsonable_encoder
    return _dump_other(
           ^^^^^^^^^^^^
  File "xxxxxxxxxxxxxx/.venv/lib/python3.11/site-packages/aws_lambda_powertools/event_handler/openapi/encoders.py", line 286, in _dump_other
    raise ValueError(errors) from e
ValueError: [TypeError("'Decimal128' object is not iterable"), TypeError('vars() argument must have __dict__ attribute')]

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "xxxxxxxxxxxxxx/c.py", line 19, in <module>
    print(jsonable_encoder({'dec': Decimal128('123')}, custom_serializer=custom_serializer))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "xxxxxxxxxxxxxx/.venv/lib/python3.11/site-packages/aws_lambda_powertools/event_handler/openapi/encoders.py", line 113, in jsonable_encoder
    return _dump_dict(
           ^^^^^^^^^^^
  File "xxxxxxxxxxxxxx/.venv/lib/python3.11/site-packages/aws_lambda_powertools/event_handler/openapi/encoders.py", line 226, in _dump_dict
    encoded_value = jsonable_encoder(
                    ^^^^^^^^^^^^^^^^^
  File "xxxxxxxxxxxxxx/.venv/lib/python3.11/site-packages/aws_lambda_powertools/event_handler/openapi/encoders.py", line 157, in jsonable_encoder
    raise SerializationError(
aws_lambda_powertools.event_handler.openapi.exceptions.SerializationError: ('Unable to serialize the object 123 as it is not a supported type. Error details: [TypeError("\'Decimal128\' object is not iterable"), TypeError(\'vars() argument must have __dict__ attribute\')]', 'See: https://docs.powertools.aws.dev/lambda/python/latest/core/event_handler/api_gateway/#serializing-objects')

Metadata

Metadata

Assignees

Type

No type

Projects

Status

Shipped

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions