Typing issue: `CreateParams` for `StripeObject`s should allow for Optional values
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 35/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Stale
- Tech stack
- python
- Domain
- developer-experience
Research direction
Start with the CreateParams definition in stripe/_subscription.py at the linked promotion_code line, then compare its typing with the Optional pattern in stripe/_request_options.py. Run mypy on the reproduction shown in the issue and verify that nullable CreateParams attributes accept None while remaining optional to pass.
Written by the indexing model from the issue text.
Description
Describe the bug
Many CreateParams attributes on StripeObjects are defined to be non-optional. This means that if that keyword argument is passed into the .create( function, it must be a non-null value (that also adheres to the defined typing).
However, the API supports passing null values on many of these attributes and that seems to contextually make sense.
One example is the promotion_code attribute on the Subscription CreateParams class.
The following call succeeds without issue:
import stripe
api_key = "***" # loaded from env
api_version = "2023-10-16" # At the time of writing this ticket, I am using this API version
customer_id = "cus_xxx" # use any customer_id with a payment source in your own env
price_id = "price_xxx". # use an existing active price on a product in your stripe env
promotion_code = None
subscription = stripe.Subscription.create(
customer=customer_id,
items=[{"price": price_id}],
payment_behavior="error_if_incomplete",
promotion_code=promotion_code,
)
however, mypy will find issues with the fact that promotion_code is None and prefers it not to be passed at all.
The workaround at this current moment (other than ignoring the type issue) would be to add a conditional
if promotion_code:
subscription = stripe.Subscription.create(
customer=customer_id,
items=[{"price": price_id}],
payment_behavior="error_if_incomplete",
promotion_code=promotion_code,
)
else:
subscription = stripe.Subscription.create(
customer=customer_id,
items=[{"price": price_id}],
payment_behavior="error_if_incomplete",
)
however, this is quite tedious and becomes unruly if you have more than one attribute you need to check (a permutation of checks will occur)
To Reproduce
- Write the follow or similar code
import stripe
api_key = "***" # loaded from env
api_version = "2023-10-16" # At the time of writing this ticket, I am using this API version
customer_id = "cus_xxx" # use any customer_id with a payment source in your own env
price_id = "price_xxx". # use an existing active price on a product in your stripe env
promotion_code = None
subscription = stripe.Subscription.create(
customer=customer_id,
items=[{"price": price_id}],
payment_behavior="error_if_incomplete",
promotion_code=promotion_code,
)
- Run mypy checker
- You will see the following error:
error: Argument "promotion_code" to "create" of "Subscription" has incompatible type "str | None"; expected "str" [arg-type]
Expected behavior
Using this line as an example, any nullable CreateParams attribute should be noted as Optional
Suggested Solution
promotion_code: NotRequired["str|None"]
^This solution most similarly reflects the way that Optional is implemented on the base RequestOptions class
Code snippets
Sample attribute to modify: https://github.com/stripe/stripe-python/blob/1657f036266412b7ef38d46c77f1b30f5455d83b/stripe/_subscription.py#L594
Existing way Optional is implemented: https://github.com/stripe/stripe-python/blob/1657f036266412b7ef38d46c77f1b30f5455d83b/stripe/_request_options.py#L7
OS
macOS
Language version
Python 3.11.3
Library version
stripe-python v8.9.0
API version
2023-10-16
Additional context
No response
- Dominant language
- Python
- Stars
- 2k
- Forks
- 539
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 26
Contributor 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
-
feature-request future
Difficulty 4/5 3-5 days Newbie friendliness 35/100
stripe/stripe-python#1886 · 1 comment ·
-
feature-request
Difficulty 2/5 1-3 hours Newbie friendliness 54/100
stripe/stripe-python#1841 · 1 comment ·
-
feature-request future
Difficulty 3/5 1-2 days Newbie friendliness 52/100
stripe/stripe-python#1812 · 1 comment ·
-
feature-request future
Difficulty 3/5 1-2 days Newbie friendliness 74/100
stripe/stripe-python#1796 · 3 comments ·
-
feature-request future
Difficulty 4/5 3-5 days Newbie friendliness 38/100
stripe/stripe-python#1465 · 4 comments · 2 reactions ·
All issues in stripe/stripe-python
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
bancolombia/sentinel#23 ·
-
test md OpenCI
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
-
integration:quickjs org:external priority:backlog topic:code-interpreter topic:middleware type:feature
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
langchain-ai/deepagents#6450 ·
-
bug client
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100