Skip to content

Commit

Permalink
Adding black and applying results
Browse files Browse the repository at this point in the history
  • Loading branch information
douglasmiller committed Aug 5, 2022
1 parent 80de0f8 commit c2a339a
Show file tree
Hide file tree
Showing 14 changed files with 2,497 additions and 2,215 deletions.
1,867 changes: 972 additions & 895 deletions recurly/__init__.py

Large diffs are not rendered by default.

82 changes: 52 additions & 30 deletions recurly/errors.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from defusedxml import ElementTree
import six


class ResponseError(Exception):

"""An error received from the Recurly API in response to an HTTP
Expand All @@ -13,39 +14,37 @@ def __init__(self, response_xml):
def response_doc(self):
"""The XML document received from the service."""
try:
return self.__dict__['response_doc']
return self.__dict__["response_doc"]
except KeyError:
self.__dict__['response_doc'] = ElementTree.fromstring(
self.response_xml
)
return self.__dict__['response_doc']
self.__dict__["response_doc"] = ElementTree.fromstring(self.response_xml)
return self.__dict__["response_doc"]

@property
def symbol(self):
"""The machine-readable identifier for the error."""
el = self.response_doc.find('symbol')
el = self.response_doc.find("symbol")
if el is not None:
return el.text

@property
def message(self):
"""The human-readable description of the error."""
el = self.response_doc.find('description')
el = self.response_doc.find("description")
if el is not None:
return el.text

@property
def details(self):
"""A further human-readable elaboration on the error."""
el = self.response_doc.find('details')
el = self.response_doc.find("details")
if el is not None:
return el.text

@property
def error(self):
"""A fall-back error message in the event no more specific
error is given."""
el = self.response_doc.find('error')
el = self.response_doc.find("error")
if el is not None:
return el.text

Expand All @@ -58,13 +57,14 @@ def __unicode__(self):
return self.error
details = self.details
if details is not None:
return six.u('%s: %s %s') % (symbol, self.message, details)
return six.u('%s: %s') % (symbol, self.message)
return six.u("%s: %s %s") % (symbol, self.message, details)
return six.u("%s: %s") % (symbol, self.message)


class ClientError(ResponseError):
"""An error resulting from a problem in the client's request (that
is, an error with an HTTP ``4xx`` status code)."""

pass


Expand All @@ -76,11 +76,13 @@ class BadRequestError(ClientError):
Resubmitting the request will likely result in the same error.
"""

pass


class ConfigurationError(Exception):
"""An error related to a bad configuration"""

pass


Expand All @@ -99,6 +101,7 @@ def __unicode__(self):
class PaymentRequiredError(ClientError):
"""An error indicating your Recurly account is in production mode
but is not in good standing (HTTP ``402 Payment Required``)."""

pass


Expand All @@ -110,18 +113,21 @@ class ForbiddenError(ClientError):
your login credentials are for the appropriate account.
"""

pass


class NotFoundError(ClientError):
"""An error for when the resource was not found with the given
identifier (HTTP ``404 Not Found``)."""

pass


class NotAcceptableError(ClientError):
"""An error for when the client's request could not be accepted by
the remote service (HTTP ``406 Not Acceptable``)."""

pass


Expand All @@ -134,12 +140,14 @@ class PreconditionFailedError(ClientError):
corresponds to the HTTP ``412 Precondition Failed`` status code.
"""

pass


class UnsupportedMediaTypeError(ClientError):
"""An error resulting from the submission as an unsupported media
type (HTTP ``415 Unsupported Media Type``)."""

pass


Expand All @@ -153,42 +161,42 @@ def __init__(self, response_doc):
@property
def error_code(self):
"""The machine-readable identifier for the error."""
el = self.response_doc.find('error_code')
el = self.response_doc.find("error_code")
if el is not None:
return el.text

@property
def error_category(self):
"""The machine-readable identifier for the error category."""
el = self.response_doc.find('error_category')
el = self.response_doc.find("error_category")
if el is not None:
return el.text

@property
def customer_message(self):
"""Recommended message for the customer"""
el = self.response_doc.find('customer_message')
el = self.response_doc.find("customer_message")
if el is not None:
return el.text

@property
def merchant_message(self):
"""Recommended message for the merchant"""
el = self.response_doc.find('merchant_message')
el = self.response_doc.find("merchant_message")
if el is not None:
return el.text

@property
def gateway_error_code(self):
"""Error code from the gateway"""
el = self.response_doc.find('gateway_error_code')
el = self.response_doc.find("gateway_error_code")
if el is not None:
return el.text

@property
def three_d_secure_action_token_id(self):
"""3DS Action Token ID for further authentication"""
el = self.response_doc.find('three_d_secure_action_token_id')
el = self.response_doc.find("three_d_secure_action_token_id")
if el is not None:
return el.text

Expand All @@ -201,16 +209,16 @@ class ValidationError(ClientError):
@property
def transaction_error(self):
"""The transaction error object."""
error = self.response_doc.find('transaction_error')
error = self.response_doc.find("transaction_error")
if error is not None:
return TransactionError(error)

@property
def transaction_error_code(self):
"""The machine-readable error code for a transaction error."""
error = self.response_doc.find('transaction_error')
error = self.response_doc.find("transaction_error")
if error is not None:
code = error.find('error_code')
code = error.find("error_code")
if code is not None:
return code.text

Expand All @@ -228,7 +236,7 @@ def __str__(self):
return self.__unicode__()

def __unicode__(self):
return six.u('%s: %s %s') % (self.symbol, self.field, self.message)
return six.u("%s: %s %s") % (self.symbol, self.field, self.message)

@property
def errors(self):
Expand All @@ -240,14 +248,14 @@ def errors(self):
"""
try:
return self.__dict__['errors']
return self.__dict__["errors"]
except KeyError:
pass

suberrors = dict()
for err in self.response_doc.findall('error'):
field = err.attrib['field']
symbol = err.attrib['symbol']
for err in self.response_doc.findall("error"):
field = err.attrib["field"]
symbol = err.attrib["symbol"]
message = err.text
sub_err = self.Suberror(field, symbol, message)

Expand All @@ -260,28 +268,33 @@ def errors(self):
else:
suberrors[field] = sub_err

self.__dict__['errors'] = suberrors
self.__dict__["errors"] = suberrors
return suberrors

def __unicode__(self):
all_error_strings = []
for error_key in sorted(self.errors.keys()):
error = self.errors[error_key]
if isinstance(error, (tuple, list)):
all_error_strings += [six.text_type(e) for e in error] # multiple errors on field
all_error_strings += [
six.text_type(e) for e in error
] # multiple errors on field
else:
all_error_strings.append(six.text_type(error))
return six.u('; ').join(all_error_strings)
return six.u("; ").join(all_error_strings)


class ServerError(ResponseError):
"""An error resulting from a problem creating the server's response
to the request (that is, an error with an HTTP ``5xx`` status code)."""

pass


class InternalServerError(ServerError):
"""An unexpected general server error (HTTP ``500 Internal Server
Error``)."""

pass


Expand All @@ -293,6 +306,7 @@ class BadGatewayError(ServerError):
Try the request again.
"""

pass


Expand All @@ -303,6 +317,7 @@ class ServiceUnavailableError(ServerError):
response. Try the request again.
"""

pass


Expand All @@ -313,6 +328,7 @@ class GatewayTimeoutError(ServerError):
response. Try the request again.
"""

pass


Expand All @@ -335,14 +351,17 @@ class UnexpectedClientError(UnexpectedStatusError):
not be used for classes mapped in the `error_classes` dict.
"""

pass


class UnexpectedServerError(UnexpectedStatusError):
"""An error resulting from an unexpected status code in
the range 500-599 of HTTP status codes. This class should
not be used for classes mapped in the `error_classes` dict.
"""

pass


Expand All @@ -369,13 +388,16 @@ def error_class_for_http_status(status):
try:
return error_classes[status]
except KeyError:

def new_status_error(xml_response):
if (status > 400 and status < 500):
if status > 400 and status < 500:
return UnexpectedClientError(status, xml_response)
if (status > 500 and status < 600):
if status > 500 and status < 600:
return UnexpectedServerError(status, xml_response)
return UnexpectedStatusError(status, xml_response)

return new_status_error


other_errors = [ConfigurationError]
__all__ = [x.__name__ for x in list(error_classes.values()) + other_errors]
34 changes: 18 additions & 16 deletions recurly/link_header.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,43 +34,44 @@

TOKEN = r'(?:[^\(\)<>@,;:\\"/\[\]\?={} \t]+?)'
QUOTED_STRING = r'(?:"(?:\\"|[^"])*")'
PARAMETER = r'(?:%(TOKEN)s(?:=(?:%(TOKEN)s|%(QUOTED_STRING)s))?)' % locals()
LINK = r'<[^>]*>\s*(?:;\s*%(PARAMETER)s?\s*)*' % locals()
COMMA = r'(?:\s*(?:,\s*)+)'
LINK_SPLIT = r'%s(?=%s|\s*$)' % (LINK, COMMA)
PARAMETER = r"(?:%(TOKEN)s(?:=(?:%(TOKEN)s|%(QUOTED_STRING)s))?)" % locals()
LINK = r"<[^>]*>\s*(?:;\s*%(PARAMETER)s?\s*)*" % locals()
COMMA = r"(?:\s*(?:,\s*)+)"
LINK_SPLIT = r"%s(?=%s|\s*$)" % (LINK, COMMA)


def _unquotestring(instr):
if instr[0] == instr[-1] == '"':
instr = instr[1:-1]
instr = re.sub(r'\\(.)', r'\1', instr)
instr = re.sub(r"\\(.)", r"\1", instr)
return instr


def _splitstring(instr, item, split):
if not instr:
return []
return [h.strip() for h in re.findall(r'%s(?=%s|\s*$)' % (item, split), instr)]
return [h.strip() for h in re.findall(r"%s(?=%s|\s*$)" % (item, split), instr)]


link_splitter = re.compile(LINK_SPLIT)


def parse_link_value(instr):
"""
Given a link-value (i.e., after separating the header-value on commas),
Given a link-value (i.e., after separating the header-value on commas),
return a dictionary whose keys are link URLs and values are dictionaries
of the parameters for their associated links.
Note that internationalised parameters (e.g., title*) are
Note that internationalised parameters (e.g., title*) are
NOT percent-decoded.
Also, only the last instance of a given parameter will be included.
For example,
For example,
>>> parse_link_value('</foo>; rel="self"; title*=utf-8\'de\'letztes%20Kapitel')
{'/foo': {'title*': "utf-8'de'letztes%20Kapitel", 'rel': 'self'}}
"""
out = {}
if not instr:
Expand All @@ -89,7 +90,8 @@ def parse_link_value(instr):
return out


if __name__ == '__main__':
if __name__ == "__main__":
import sys

if len(sys.argv) > 1:
print(parse_link_value(sys.argv[1]))
print(parse_link_value(sys.argv[1]))
Loading

0 comments on commit c2a339a

Please sign in to comment.