diff --git a/gunicorn/dirty/tlv.py b/gunicorn/dirty/tlv.py index 5682b0c6..e0b1e2f4 100644 --- a/gunicorn/dirty/tlv.py +++ b/gunicorn/dirty/tlv.py @@ -113,11 +113,9 @@ class TLVEncoder: ) parts = [bytes([TYPE_DICT]), struct.pack(">I", len(value))] for k, v in value.items(): - # Keys must be strings + # Convert keys to strings (like JSON) if not isinstance(k, str): - raise DirtyProtocolError( - f"Dict keys must be strings, got {type(k).__name__}" - ) + k = str(k) parts.append(TLVEncoder.encode(k)) parts.append(TLVEncoder.encode(v)) return b"".join(parts) diff --git a/tests/test_dirty_tlv.py b/tests/test_dirty_tlv.py index 87727203..c36b839a 100644 --- a/tests/test_dirty_tlv.py +++ b/tests/test_dirty_tlv.py @@ -307,12 +307,13 @@ class TestTLVEncoderDict: value, offset = TLVEncoder.decode(encoded, 0) assert value == data - def test_encode_dict_non_string_key(self): - """Test that non-string keys raise error.""" - data = {1: "value"} - with pytest.raises(DirtyProtocolError) as exc_info: - TLVEncoder.encode(data) - assert "keys must be strings" in str(exc_info.value).lower() + def test_encode_dict_non_string_key_converted(self): + """Test that non-string keys are converted to strings (like JSON).""" + data = {1: "value", 2: "other"} + encoded = TLVEncoder.encode(data) + decoded, _ = TLVEncoder.decode(encoded, 0) + # Keys should be converted to strings + assert decoded == {"1": "value", "2": "other"} class TestTLVEncoderComplexStructures: