Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mark defunct and internal methods as deprecated #1101

Merged
merged 13 commits into from
Dec 12, 2023
10 changes: 9 additions & 1 deletion stripe/_api_requestor.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from stripe import oauth_error # noqa: SPY101
from stripe._encode import _api_encode
from stripe._multipart_data_generator import MultipartDataGenerator

richardm-stripe marked this conversation as resolved.
Show resolved Hide resolved
from urllib.parse import urlencode, urlsplit, urlunsplit
from stripe._stripe_response import StripeResponse, StripeStreamResponse

Expand Down Expand Up @@ -78,7 +79,14 @@ def __init__(
self._default_proxy = proxy

@classmethod
@_util.deprecated(
"This method is internal to stripe-python and the public interface will be removed in a future stripe-python version"
)
def format_app_info(cls, info):
return cls._format_app_info(info)

@classmethod
def _format_app_info(cls, info):
str = info["name"]
if info["version"]:
str += "/%s" % (info["version"],)
Expand Down Expand Up @@ -230,7 +238,7 @@ def specific_oauth_error(self, rbody, rcode, resp, rheaders, error_code):
def request_headers(self, api_key, method):
user_agent = "Stripe/v1 PythonBindings/%s" % (_version.VERSION,)
if stripe.app_info:
user_agent += " " + self.format_app_info(stripe.app_info)
user_agent += " " + self._format_app_info(stripe.app_info)

ua = {
"bindings_version": _version.VERSION,
Expand Down
10 changes: 9 additions & 1 deletion stripe/_error.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import stripe # noqa: IMP101
from stripe._error_object import ErrorObject

from stripe import _util
import warnings


class StripeError(Exception):
_message: Optional[str]
Expand Down Expand Up @@ -43,7 +46,9 @@ def __init__(
self.headers = headers or {}
self.code = code
self.request_id = self.headers.get("request-id", None)
self.error = self.construct_error_object()
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
self.error = self.construct_error_object()
pakrym-stripe marked this conversation as resolved.
Show resolved Hide resolved

def __str__(self):
msg = self._message or "<empty message>"
Expand All @@ -68,6 +73,9 @@ def __repr__(self):
self.request_id,
)

@_util.deprecated(
"For internal stripe-python use only. The public interface will be removed in a future version."
)
def construct_error_object(self) -> Optional[ErrorObject]:
if (
self.json_body is None
Expand Down
12 changes: 11 additions & 1 deletion stripe/_request_metrics.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
class RequestMetrics(object):
from stripe import _util


class _RequestMetrics(object):
def __init__(self, request_id, request_duration_ms):
self.request_id = request_id
self.request_duration_ms = request_duration_ms
Expand All @@ -8,3 +11,10 @@ def payload(self):
"request_id": self.request_id,
"request_duration_ms": self.request_duration_ms,
}


@_util.deprecated(
"This class is for internal stripe-python use only. The public interface will be removed in a future version."
)
class RequestMetrics(_RequestMetrics):
pass
48 changes: 40 additions & 8 deletions stripe/_stripe_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
from stripe import _util

from stripe._stripe_response import StripeResponse, StripeStreamResponse
import warnings

_util.deprecated
pakrym-stripe marked this conversation as resolved.
Show resolved Hide resolved
richardm-stripe marked this conversation as resolved.
Show resolved Hide resolved


@overload
Expand Down Expand Up @@ -70,13 +73,19 @@ def _serialize_list(


class StripeObject(Dict[str, Any]):
class ReprJSONEncoder(json.JSONEncoder):
class _ReprJSONEncoder(json.JSONEncoder):
def default(self, o: Any) -> Any:
if isinstance(o, datetime.datetime):
# pyright complains that _encode_datetime is "private", but it's
# private to outsiders, not to stripe_object
return _encode_datetime(o)
return super(StripeObject.ReprJSONEncoder, self).default(o)
return super(StripeObject._ReprJSONEncoder, self).default(o)

@_util.deprecated(
"For internal stripe-python use only. The public interface will be removed in a future version"
)
class ReprJSONEncoder(_ReprJSONEncoder):
pass

_retrieve_params: Dict[str, Any]
_previous: Optional[Dict[str, Any]]
Expand Down Expand Up @@ -307,6 +316,9 @@ def refresh_from(
self._previous = values

@classmethod
@_util.deprecated(
"This will be removed in a future version of stripe-python."
)
def api_base(cls) -> Optional[str]:
return None

Expand Down Expand Up @@ -351,10 +363,14 @@ def _request(
stripe_version = stripe_version or self.stripe_version
api_key = api_key or self.api_key
params = params or self._retrieve_params
api_base = None
with warnings.catch_warnings():
warnings.simplefilter("ignore")
api_base = self.api_base() # pyright: ignore[reportDeprecated]

requestor = stripe.APIRequestor(
key=api_key,
api_base=self.api_base(),
api_base=api_base,
api_version=stripe_version,
account=stripe_account,
)
Expand All @@ -378,9 +394,13 @@ def request_stream(
) -> StripeStreamResponse:
if params is None:
params = self._retrieve_params
api_base = None
with warnings.catch_warnings():
warnings.simplefilter("ignore")
api_base = self.api_base() # pyright: ignore[reportDeprecated]
requestor = stripe.APIRequestor(
key=self.api_key,
api_base=self.api_base(),
api_base=api_base,
api_version=self.stripe_version,
account=self.stripe_account,
)
Expand All @@ -407,23 +427,26 @@ def __repr__(self) -> str:

def __str__(self) -> str:
return json.dumps(
self.to_dict_recursive(),
self._to_dict_recursive(),
sort_keys=True,
indent=2,
cls=self.ReprJSONEncoder,
cls=self._ReprJSONEncoder,
)

@_util.deprecated(
"Deprecated. The public interface will be removed in a future version."
)
def to_dict(self) -> Dict[str, Any]:
return dict(self)

def to_dict_recursive(self) -> Dict[str, Any]:
def _to_dict_recursive(self) -> Dict[str, Any]:
pakrym-stripe marked this conversation as resolved.
Show resolved Hide resolved
def maybe_to_dict_recursive(
value: Optional[Union[StripeObject, Dict[str, Any]]]
) -> Optional[Dict[str, Any]]:
if value is None:
return None
elif isinstance(value, StripeObject):
return value.to_dict_recursive()
return value._to_dict_recursive()
else:
return value

Expand All @@ -434,7 +457,16 @@ def maybe_to_dict_recursive(
for key, value in dict(self).items()
}

@_util.deprecated(
"For internal stripe-python use only. The public interface will be removed in a future version."
)
def to_dict_recursive(self) -> Dict[str, Any]:
return self._to_dict_recursive()

@property
@_util.deprecated(
"For internal stripe-python use only. The public interface will be removed in a future version."
)
def stripe_id(self) -> Optional[str]:
return getattr(self, "id")

Expand Down
14 changes: 10 additions & 4 deletions stripe/_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@

# Used for global variables
import stripe # noqa: IMP101
from stripe._stripe_response import StripeResponse
from stripe._stripe_object import StripeObject

if TYPE_CHECKING:
from stripe._stripe_response import StripeResponse
from stripe._stripe_object import StripeObject

STRIPE_LOG = os.environ.get("STRIPE_LOG")

Expand Down Expand Up @@ -192,12 +194,12 @@ def get_object_classes():
return OBJECT_CLASSES


Resp = Union[StripeResponse, Dict[str, Any], List["Resp"]]
Resp = Union["StripeResponse", Dict[str, Any], List["Resp"]]


@overload
def convert_to_stripe_object(
resp: Union[StripeResponse, Dict[str, Any]],
resp: Union["StripeResponse", Dict[str, Any]],
api_key: Optional[str] = None,
stripe_version: Optional[str] = None,
stripe_account: Optional[str] = None,
Expand Down Expand Up @@ -232,6 +234,10 @@ def convert_to_stripe_object(
# the raw API response information
stripe_response = None

# Imports here at runtime to avoid circular dependencies
from stripe._stripe_response import StripeResponse
pakrym-stripe marked this conversation as resolved.
Show resolved Hide resolved
from stripe._stripe_object import StripeObject

if isinstance(resp, StripeResponse):
stripe_response = resp
resp = cast(Resp, stripe_response.data)
Expand Down
10 changes: 5 additions & 5 deletions tests/test_api_requestor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from stripe._stripe_response import StripeResponse, StripeStreamResponse
from stripe._encode import _api_encode

from urllib.parse import urlsplit
from urllib.parse import urlsplit, parse_qsl
richardm-stripe marked this conversation as resolved.
Show resolved Hide resolved

import urllib3

Expand Down Expand Up @@ -135,7 +135,7 @@ def __init__(self, expected):
def __eq__(self, other):
query = urlsplit(other).query or other

parsed = stripe.util.parse_qsl(query)
parsed = parse_qsl(query)
return self.expected == sorted(parsed)

def __repr__(self):
Expand All @@ -158,7 +158,7 @@ def __eq__(self, other):
)
return False

q_matcher = QueryMatcher(stripe.util.parse_qsl(self.exp_parts.query))
q_matcher = QueryMatcher(parse_qsl(self.exp_parts.query))
return q_matcher == other

def __repr__(self):
Expand Down Expand Up @@ -447,7 +447,7 @@ def test_methods_with_params_and_response(
if method == "post":
check_call(
method,
post_data=QueryMatcher(stripe.util.parse_qsl(encoded)),
post_data=QueryMatcher(parse_qsl(encoded)),
)
else:
abs_url = "%s%s?%s" % (
Expand Down Expand Up @@ -487,7 +487,7 @@ def test_methods_with_params_and_streaming_response(
if method == "post":
check_call(
method,
post_data=QueryMatcher(stripe.util.parse_qsl(encoded)),
post_data=QueryMatcher(parse_qsl(encoded)),
is_streaming=True,
)
else:
Expand Down