Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions stripe/_encode.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,15 @@ def _api_encode(
elif hasattr(value, "id"):
yield (key, getattr(value, "id"))
elif isinstance(value, list) or isinstance(value, tuple):
if not value:
# An empty list signals "clear this array field". Stripe's
# form-encoded API interprets `key=` (empty string) as a
# request to remove all previously set values, matching the
# documented workaround of passing "" instead of [].
# Without this, an empty list is silently dropped and the
# field is left unchanged.
# See https://github.com/stripe/stripe-python/issues/802
yield (key, "")
for i, sv in enumerate(value):
# Always use indexed format for arrays
encoded_key = "%s[%d]" % (key, i)
Expand Down
24 changes: 24 additions & 0 deletions tests/test_encode.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,27 @@ def test_encode_mixed_nested_list_value(self):
("items[1][0]", 3),
("items[1][1]", 4),
]

def test_encode_empty_list_yields_empty_string(self):
"""An empty list must encode to (key, '') so the Stripe API clears the field.

Regression test for https://github.com/stripe/stripe-python/issues/802

Before this fix, _api_encode({"blocked_categories": []}) yielded
nothing — the field was silently omitted from the request and the Stripe
API left the previously-set values untouched. The documented workaround
was to pass "" instead of [], which encodes to ("blocked_categories", "").
The fix makes an empty list behave identically to that workaround.
"""
result = list(_api_encode({"blocked_categories": []}))
assert result == [("blocked_categories", "")], (
"Empty list should encode to (key, '') to clear the field; "
f"got {result!r} instead"
)

def test_encode_empty_tuple_yields_empty_string(self):
"""An empty tuple must encode to (key, '') just like an empty list."""
result = list(_api_encode({"tags": ()}))
assert result == [("tags", "")], (
f"Empty tuple should encode to (key, ''); got {result!r}"
)