Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

StripeError exceptions are not pickleable

オープン
#1,941 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 2 日以内に返信

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
55/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
活発
技術スタック
python

調査の方向性

Start by locating StripeError and its subclasses, especially InvalidRequestError, and read how their constructors and exception arguments are handled. Reproduce the pickle round trip in the issue with Python 3.12, then inspect or add tests for serializing and deserializing the error. Done means the round trip succeeds for InvalidRequestError and its required fields are preserved.

索引モデルが issue の本文から書いたものです。

説明

bug
Describe the bug

StripeError exceptions can't be serialized and deserialized using pickle.
We use Celery and the errors returned by Stripe API calls can't be serialized and can't be caught outside of the async task.

To Reproduce
from stripe import StripeClient, InvalidRequestError
import pickle

try:
    StripeClient("myapikey").v1.prices.list({"expand": ["notexpandable"]})
except InvalidRequestError as e:
    pickle.loads(pickle.dumps(e))  # TypeError: InvalidRequestError.__init__() missing 1 required positional argument: 'param'
Expected behavior

InvalidRequestError can pickled:

pickle.loads(pickle.dumps(e))

raises no error

Code snippets

OS

Linux

Language version

Python 3.12

Library version

stripe-python v15.6.1

API version

2026-02-25.clover

Additional context

I suggest to not call the super().__init__() of the StripeError class. When the exception is pickled, it is deconstructed and reconstructed using the exc.args attribute, only the arguments passed to the parent class will be included in exc.args. For example:

class StripeError(Exception):
    def __init__(message, http_body, http_status):
        super().__init__(message)
        ....


StripeError("message", {"response": "body"}, 400).args  # ("message",)   all other arguments are not included

Solution:

class StripeError(Exception):
    def __init__(message, http_body, http_status):
        # do not call __init__ of Exception
        ....

StripeError("message", {"response": "body"}, 400).args  # ("message",  {"response": "body"}, 400)

But still if we pass keyword arguments:

class StripeError(Exception):
    def __init__(message, http_body, http_status):
        # do not call __init__ of Exception
        ....

# keyword arguments are not include in exception args
StripeError("message", http_body={"response": "body"}, status=400).args  # ("message",)

We could think of passing all parameters to the parent class, but:

class StripeError(Exception):
    def __init__(message, http_body, http_status):
        # pass all parameters to parent class
        super().__init__(message, http_body, http_status)

# instances of StripeError are fixed
StripeError("message", http_body={"response": "body"}, status=400).args  # ("message",  {"response": "body"}, 400)

# but what if we subclass again?
class InvalidRequesError(StripeError):
    def __init__(message, http_body, http_status, param):
        # pass all parameters to parent class
        super().__init__(message, http_body, http_status)
        self.param = param

# now we have an issue again
InvalidRequesError("message", {"response": "body"}, 400, "param").args  # ("message",  {"response": "body"}, 400)   param is missing

One possible solution, never call Exception.init() and accept *args which will be forwarded to the parent class:

class StripeError(Exception):
    # accept *args
    def __init__(message, http_body, http_status, *args):
        # do not call Exception.__init__()
        ...

# instances of StripeError are fixed
StripeError("message", {"response": "body"}, 400).args  # ("message",  {"response": "body"}, 400)

class InvalidRequesError(StripeError):
    def __init__(message, http_body, http_status, param):
        # pass all parameters to parent class
        super().__init__(message, http_body, http_status, param)
        self.param = param

# now also subclasses are fixed
InvalidRequesError("message", {"response": "body"}, 400, "param").args  # ("message",  {"response": "body"}, 400, "param")

If we want to subclass InvalidRequestError it will also have to accept *args and forward everything as positional argument to its parent class.

主要言語
Python
スター
2.1k
フォーク
538
平均マージ
2日 16時間
マージ済み PR(30日)
28

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

stripe/stripe-python のほかの issue

stripe/stripe-python の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。