`_api_encode` encodes bool/datetime list elements raw (e.g. `flags[0]=True` instead of `true`)
Maintainers usually reply within 6 days
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
Research direction
Read stripe/_encode.py and trace how _api_encode handles direct list elements compared with top-level values. Add regression tests for boolean and datetime list elements, then run the relevant encoding tests; done means both serialize to the expected lowercase booleans and Unix timestamps. The issue author says a fix is prepared, but no pull request is linked and the issue has no comments.
Written by the indexing model from the issue text.
Description
Describe the bug
stripe._encode._api_encode converts bool and datetime values to the forms the API expects at the top level and inside nested dicts (bool → "true"/"false", datetime → unix timestamp), but yields them raw when they are direct elements of a list.
The request body/query string is built with urlencode(list(_api_encode(params))) (in _api_requestor.py), so a list parameter containing a boolean is serialized as "True"/"False" (Python str(bool)) and a list containing a datetime is serialized as its str() repr instead of a unix timestamp. Multipart form encoding is affected too, since MultipartDataGenerator.add_params also goes through _api_encode.
To Reproduce
import datetime
from urllib.parse import urlencode
from stripe._encode import _api_encode
dt = datetime.datetime(2024, 1, 2, 3, 4, 5, tzinfo=datetime.timezone.utc)
print(urlencode(list(_api_encode({"active": True})))) # correct
print(urlencode(list(_api_encode({"flags": [True, False]})))) # wrong
print(urlencode(list(_api_encode({"created": dt})))) # correct
print(urlencode(list(_api_encode({"created": [dt]})))) # wrong
Output:
active=true
flags%5B0%5D=True&flags%5B1%5D=False
created=1704164645
created%5B0%5D=2024-01-02+03%3A04%3A05%2B00%3A00
The top-level bool/datetime are encoded correctly (active=true, created=1704164645); the same values inside a list are not.
Expected behavior
A bool or datetime inside a list should be encoded the same way as at the top level:
flags[0]=true&flags[1]=falsecreated[0]=1704164645
Code snippets
OS
Any (reproduced on Linux)
Language version
Python 3.12 (version-independent)
Library version
main (89e8528)
API version
N/A — client-side request encoding, independent of API version
Additional context
Root cause
In _api_encode (stripe/_encode.py), the list branch handles dict/_data elements and nested list/tuple elements, but every other element — including bool and datetime.datetime — falls through to else: yield (encoded_key, sv) raw. The top-level code has explicit datetime and bool branches; the list branch does not.
(Nested dict values are unaffected because they recurse back through _api_encode; nested lists are unaffected because they go through _encode_nested_dict + recursion. Only direct scalar elements of a list are affected.)
Proposed fix
Mirror the top-level handling in the list branch:
elif isinstance(sv, datetime.datetime):
yield (encoded_key, _encode_datetime(sv))
elif isinstance(sv, bool):
yield (encoded_key, str(sv).lower())
else:
yield (encoded_key, sv)
I've prepared this fix with regression tests on a branch: https://github.com/alphasafal/stripe-python/tree/fix/encode-list-bool-datetime — happy to open a PR if a maintainer would like one (the repo currently limits PR creation to collaborators).
- Dominant language
- Python
- Stars
- 2.1k
- Forks
- 547
- Avg merge
- 5d 6h
- Merged PRs (30d)
- 9
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from stripe/stripe-python
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
stripe/stripe-python#1962 ·
Maintainers usually reply within 6 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
stripe/stripe-python#1948 · 2 comments ·
Maintainers usually reply within 6 days
-
Boolean list elements are encoded as True/False instead of true/falseMay be free again @inchang-ing claimed this 13 days ago, and no pull request is open. Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
stripe/stripe-python#1947 · 3 comments ·
Maintainers usually reply within 6 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
stripe/stripe-python#1936 · 2 comments ·
Maintainers usually reply within 6 days
-
Difficulty 3/5 1-2 days Newbie friendliness 55/100
stripe/stripe-python#1954 · 1 comment · 2 reactions ·
Maintainers usually reply within 6 days
All issues in stripe/stripe-python
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
microsoft/markitdown#2820 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
yt-project/yt#5624 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
NousResearch/hermes-agent#148376 ·
Maintainers usually reply within 1 day