-
Notifications
You must be signed in to change notification settings - Fork 22
Added support for Tuple data type encoding #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -88,6 +88,17 @@ def test_encode_primitive_array(): | |
| result = encode(data) | ||
| assert result == 'items: [hello,"world, test",foo]' | ||
|
|
||
| def test_encode_tuple_array(): | ||
| """Test encoding of primitive arrays.""" | ||
| # Number tuple | ||
| assert encode({'numbers': (1, 2, 3)}) == 'numbers: [1,2,3]' | ||
|
|
||
| # String tuple | ||
| assert encode({'names': ('Alice', 'Bob')}) == 'names: [Alice,Bob]' | ||
|
|
||
| # Mixed primitive tuple | ||
| assert encode({'mixed': (1, 'text', True, None)}) == 'mixed: [1,text,true,null]' | ||
|
Comment on lines
+91
to
+100
|
||
|
|
||
|
|
||
| def test_encode_array_delimiter(): | ||
| """Test different array delimiters.""" | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -117,9 +117,11 @@ def _encode_value(value: Any, level: int, opts: EncoderOptions) -> str: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return _encode_array(value, level, opts) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif isinstance(value, dict): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return _encode_object(value, level, opts) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif isinstance(value, tuple): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return _encode_tuple(value) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return _encode_tuple(value) | |
| return _encode_tuple(value, level, opts) |
Copilot
AI
Feb 6, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR changes the behavior from encoding unknown types as 'null' to raising NotImplementedError, but there are no tests to verify this new behavior. Add a test that verifies NotImplementedError is raised for unsupported types (e.g., custom classes, sets, frozensets, etc.) to ensure the error handling works as expected.
Copilot
AI
Feb 6, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The _encode_tuple function doesn't accept or use the opts parameter, so it always uses comma as the delimiter. This creates an inconsistency with list encoding which respects the delimiter option. For example, if a user encodes data with delimiter='tab', lists will use tabs but tuples will still use commas. The function should accept level and opts parameters like _encode_array does, and either call _encode_array or reimplement the logic to respect the delimiter option.
| def _encode_tuple(value: tuple) -> str: | |
| """Encode a tuple.""" | |
| if not value: | |
| return '[]' | |
| tuple_data = ','.join(_encode_primitive_value(v) for v in value) | |
| def _encode_tuple(value: tuple, level: int = 0, opts: Optional[EncoderOptions] = None) -> str: | |
| """Encode a tuple.""" | |
| if not value: | |
| return '[]' | |
| # Use the configured delimiter when options are provided; fall back to comma for backward compatibility | |
| delimiter = opts.delimiter if opts is not None else COMMA | |
| tuple_data = delimiter.join(_encode_primitive_value(v) for v in value) |
Copilot
AI
Feb 6, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The _encode_tuple function only handles primitive values using _encode_primitive_value, which falls back to 'null' for non-primitive types (line 304 in encoder.py). This means tuples containing nested structures (like dicts, lists, or other tuples) will be incorrectly encoded. For example, a tuple like ({'a': 1}, [2, 3]) would be encoded as [null,null] instead of properly encoding the nested structures. Consider converting the tuple to a list and using _encode_array instead, or implement proper handling for nested structures.
| """Encode a tuple.""" | |
| if not value: | |
| return '[]' | |
| tuple_data = ','.join(_encode_primitive_value(v) for v in value) | |
| """Encode a tuple. | |
| Tuples are encoded similarly to arrays. Primitive elements are encoded | |
| via `_encode_primitive_value`, while nested containers (lists, dicts, | |
| and tuples) are encoded using the corresponding encoder functions. | |
| """ | |
| if not value: | |
| return '[]' | |
| # Use default encoder options for nested structures. The previous | |
| # implementation ignored options entirely, so this is backward | |
| # compatible while allowing proper nested encoding. | |
| opts = EncoderOptions() | |
| encoded_items: List[str] = [] | |
| for v in value: | |
| if is_primitive(v): | |
| encoded_items.append(_encode_primitive_value(v)) | |
| elif isinstance(v, list): | |
| # Encode lists using the standard array encoder. | |
| encoded_items.append(_encode_array(v, level=0, opts=opts)) | |
| elif isinstance(v, dict): | |
| # Encode dictionaries as objects at the top level. | |
| encoded_items.append(_encode_object(v, level=0, opts=opts)) | |
| elif isinstance(v, tuple): | |
| # Recursively encode nested tuples. | |
| encoded_items.append(_encode_tuple(v)) | |
| else: | |
| # Fallback to primitive encoding behavior for unsupported types. | |
| encoded_items.append(_encode_primitive_value(v)) | |
| tuple_data = ','.join(encoded_items) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docstring says "Test encoding of primitive arrays" but this test is actually testing tuple encoding. Update the docstring to accurately describe what the test is doing, for example: "Test encoding of tuples".