Skip to content

fix(core): handle non-iterable objects with __iter__ = None in metadata_to_dict - #493

Open
reginaldalfret wants to merge 1 commit into
aws:masterfrom
reginaldalfret:fix-453-metadata-non-iterable
Open

reginaldalfret wants to merge 1 commit into
aws:masterfrom
reginaldalfret:fix-453-metadata-non-iterable

Conversation

@reginaldalfret

Copy link
Copy Markdown

Fixes #453

Issue Description

In Python, classes such as MySQLConnection (from mysql-connector-python) explicitly declare __iter__ = None to mark instances as non-iterable according to Python's data model. When such an object was passed to aws_xray_sdk.core.utils.conversion.metadata_to_dict, the check hasattr(obj, "__iter__") evaluated to True. Attempting to iterate over obj then raised TypeError: 'MySQLConnection' object is not iterable.

This caused metadata_to_dict to fail with a warning log and return an empty dictionary {} instead of extracting and serializing the object's attributes via hasattr(obj, "__dict__").

Solution

  1. Use isinstance(obj, Iterable) from collections.abc instead of hasattr(obj, "__iter__"). In Python's ABC system, isinstance(obj, Iterable) returns False when __iter__ = None.
  2. Add a try...except TypeError: guard around iteration to gracefully fall through to __dict__ serialization in the event of custom non-iterable or broken iterable types.
  3. Added unit tests covering objects with __iter__ = None, broken iterators raising TypeError, and primitive/collection types.

Testing

  • Ran core test suite (pytest --ignore tests/ext): 152 passed.
  • Added regression tests in tests/test_utils.py:
    • test_metadata_to_dict_non_iterable_object (passed)
    • test_metadata_to_dict_broken_iterable (passed)
    • test_metadata_to_dict_collection_types (passed)
  • test_metadata_to_dict_self_reference in tests/util.py (passed).
  • git diff --check and py_compile clean.

…ta_to_dict

Fixes aws#453

In Python, classes such as MySQLConnection (from mysql-connector-python) explicitly set __iter__ = None to mark instances as non-iterable. hasattr(obj, '__iter__') evaluates to True for such objects, but attempting iteration raises TypeError: '<Class>' object is not iterable.

When metadata_to_dict encountered these objects, the TypeError caused it to log a warning and return an empty dictionary instead of serializing the object's attributes via __dict__.

Fix this by:
1. Checking isinstance(obj, Iterable) rather than hasattr(obj, '__iter__'), which correctly identifies classes with __iter__ = None as non-iterable.
2. Catching TypeError during iteration as a fallback so that any non-iterable object safely proceeds to __dict__ serialization.
3. Adding regression tests for non-iterable and broken iterable objects.
@reginaldalfret
reginaldalfret requested a review from a team as a code owner September 25, 2026 05:14
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.

mysql-connector 9.2.0 - TypeError: 'MySQLConnection' object is not iterable

1 participant