diff --git a/src/betamax/adapter.py b/src/betamax/adapter.py index 8e8a0d2..64195e1 100644 --- a/src/betamax/adapter.py +++ b/src/betamax/adapter.py @@ -22,7 +22,7 @@ class BetamaxAdapter(BaseAdapter): """ - def __init__(self, **kwargs): + def __init__(self, **kwargs): # noqa: D107 super(BetamaxAdapter, self).__init__() self.cassette = None self.cassette_name = None diff --git a/src/betamax/cassette/__init__.py b/src/betamax/cassette/__init__.py index 7a7e366..0f99041 100644 --- a/src/betamax/cassette/__init__.py +++ b/src/betamax/cassette/__init__.py @@ -1,3 +1,4 @@ +# noqa: D104 from .cassette import Cassette, dispatch_hooks from .interaction import Interaction diff --git a/src/betamax/cassette/cassette.py b/src/betamax/cassette/cassette.py index 2707af8..c5d588d 100644 --- a/src/betamax/cassette/cassette.py +++ b/src/betamax/cassette/cassette.py @@ -1,3 +1,4 @@ +# noqa: D100 # -*- coding: utf-8 -*- import collections from datetime import datetime @@ -12,7 +13,7 @@ serialize_response, timestamp) -class Cassette(object): +class Cassette(object): # noqa: D101 default_cassette_options = { 'record_mode': 'once', @@ -25,7 +26,7 @@ class Cassette(object): hooks = collections.defaultdict(list) - def __init__(self, cassette_name, serialization_format, **kwargs): + def __init__(self, cassette_name, serialization_format, **kwargs): # noqa: D107, E501 #: Short name of the cassette self.cassette_name = cassette_name @@ -68,7 +69,7 @@ def __init__(self, cassette_name, serialization_format, **kwargs): self.serializer.allow_serialization = self.is_recording() @staticmethod - def can_be_loaded(cassette_library_dir, cassette_name, serialize_with, + def can_be_loaded(cassette_library_dir, cassette_name, serialize_with, # noqa: D102, E501 record_mode): # If we want to record a cassette we don't care if the file exists # yet @@ -92,7 +93,7 @@ def can_be_loaded(cassette_library_dir, cassette_name, serialize_with, # have the cassette the user expects us to load and raise. return os.path.exists(cassette_path) or recording - def clear(self): + def clear(self): # noqa: D102 # Clear out the interactions self.interactions = [] # Serialize to the cassette file @@ -106,7 +107,7 @@ def earliest_recorded_date(self): return i.recorded_at return datetime.now() - def eject(self): + def eject(self): # noqa: D102 self._save_cassette() def find_match(self, request): @@ -166,7 +167,7 @@ def is_recording(self): } return values.get(self.record_mode, True) - def load_interactions(self): + def load_interactions(self): # noqa: D102 if self.serialized is None: self.serialized = self.serializer.deserialize() @@ -177,11 +178,11 @@ def load_interactions(self): dispatch_hooks('before_playback', i, self) i.replace_all(self.placeholders, False) - def sanitize_interactions(self): + def sanitize_interactions(self): # noqa: D102 for i in self.interactions: i.replace_all(self.placeholders, True) - def save_interaction(self, response, request): + def save_interaction(self, response, request): # noqa: D102 serialized_data = self.serialize_interaction(response, request) interaction = Interaction(serialized_data, response) dispatch_hooks('before_record', interaction, self) @@ -189,7 +190,7 @@ def save_interaction(self, response, request): self.interactions.append(interaction) return interaction - def serialize_interaction(self, response, request): + def serialize_interaction(self, response, request): # noqa: D102 return { 'request': serialize_prepared_request( request, @@ -219,17 +220,17 @@ class Placeholder(collections.namedtuple('Placeholder', """Encapsulate some logic about Placeholders.""" @classmethod - def from_dict(cls, dictionary): + def from_dict(cls, dictionary): # noqa: D102 return cls(**dictionary) - def unpack(self, serializing): + def unpack(self, serializing): # noqa: D102 if serializing: return self.replace, self.placeholder else: return self.placeholder, self.replace -def merge_placeholder_lists(defaults, overrides): +def merge_placeholder_lists(defaults, overrides): # noqa: D103 overrides = [Placeholder.from_dict(override) for override in overrides] overrides_dict = dict((p.placeholder, p) for p in overrides) placeholders = [overrides_dict.pop(p.placeholder, p) diff --git a/src/betamax/cassette/interaction.py b/src/betamax/cassette/interaction.py index 799a8d5..edc0649 100644 --- a/src/betamax/cassette/interaction.py +++ b/src/betamax/cassette/interaction.py @@ -1,3 +1,4 @@ +# noqa: D100 from requests.cookies import extract_cookies_to_jar from datetime import datetime @@ -5,7 +6,6 @@ class Interaction(object): - """The Interaction object represents the entirety of a single interaction. The interaction includes the date it was recorded, its JSON @@ -21,7 +21,7 @@ class Interaction(object): """ - def __init__(self, interaction, response=None): + def __init__(self, interaction, response=None): # noqa: D107 self.data = interaction self.orig_response = response self.recorded_response = self.deserialize() @@ -42,7 +42,7 @@ def as_response(self): return self.recorded_response @property - def recorded_at(self): + def recorded_at(self): # noqa: D102 return datetime.strptime(self.data['recorded_at'], '%Y-%m-%dT%H:%M:%S') def deserialize(self): @@ -68,7 +68,7 @@ def replace_all(self, replacements, serializing): for placeholder in replacements: self.replace(*placeholder.unpack(serializing)) - def replace_in_headers(self, text_to_replace, placeholder): + def replace_in_headers(self, text_to_replace, placeholder): # noqa: D102 if text_to_replace == '': return for obj in ('request', 'response'): @@ -80,7 +80,7 @@ def replace_in_headers(self, text_to_replace, placeholder): else: headers[k] = v.replace(text_to_replace, placeholder) - def replace_in_body(self, text_to_replace, placeholder): + def replace_in_body(self, text_to_replace, placeholder): # noqa: D102 if text_to_replace == '': return for obj in ('request', 'response'): @@ -96,7 +96,7 @@ def replace_in_body(self, text_to_replace, placeholder): else: self.data[obj]['body']['string'] = body - def replace_in_uri(self, text_to_replace, placeholder): + def replace_in_uri(self, text_to_replace, placeholder): # noqa: D102 if text_to_replace == '': return for (obj, key) in (('request', 'uri'), ('response', 'url')): diff --git a/src/betamax/configure.py b/src/betamax/configure.py index b065eff..ad89508 100644 --- a/src/betamax/configure.py +++ b/src/betamax/configure.py @@ -1,3 +1,4 @@ +# noqa: D100 from collections import defaultdict from .cassette import Cassette @@ -23,13 +24,13 @@ class Configuration(object): CASSETTE_LIBRARY_DIR = 'vcr/cassettes' recording_hooks = defaultdict(list) - def __enter__(self): + def __enter__(self): # noqa: D105 return self - def __exit__(self, *args): + def __exit__(self, *args): # noqa: D105 pass - def __setattr__(self, prop, value): + def __setattr__(self, prop, value): # noqa: D105 if prop == 'preserve_exact_body_bytes': self.default_cassette_options[prop] = True else: diff --git a/src/betamax/decorator.py b/src/betamax/decorator.py index 2e42b2f..52c0187 100644 --- a/src/betamax/decorator.py +++ b/src/betamax/decorator.py @@ -1,3 +1,4 @@ +# noqa: D100 import functools import unittest diff --git a/src/betamax/exceptions.py b/src/betamax/exceptions.py index 9886ad5..18dacbc 100644 --- a/src/betamax/exceptions.py +++ b/src/betamax/exceptions.py @@ -1,45 +1,47 @@ -class BetamaxError(Exception): - def __init__(self, message): +# noqa: D100 + +class BetamaxError(Exception): # noqa: D101 + def __init__(self, message): # noqa: D107 super(BetamaxError, self).__init__(message) -class MissingDirectoryError(BetamaxError): +class MissingDirectoryError(BetamaxError): # noqa: D101 pass -class ValidationError(BetamaxError): +class ValidationError(BetamaxError): # noqa: D101 pass -class InvalidOption(ValidationError): +class InvalidOption(ValidationError): # noqa: D101 pass -class BodyBytesValidationError(ValidationError): +class BodyBytesValidationError(ValidationError): # noqa: D101 pass -class MatchersValidationError(ValidationError): +class MatchersValidationError(ValidationError): # noqa: D101 pass -class RecordValidationError(ValidationError): +class RecordValidationError(ValidationError): # noqa: D101 pass -class RecordIntervalValidationError(ValidationError): +class RecordIntervalValidationError(ValidationError): # noqa: D101 pass -class PlaceholdersValidationError(ValidationError): +class PlaceholdersValidationError(ValidationError): # noqa: D101 pass -class PlaybackRepeatsValidationError(ValidationError): +class PlaybackRepeatsValidationError(ValidationError): # noqa: D101 pass -class SerializerValidationError(ValidationError): +class SerializerValidationError(ValidationError): # noqa: D101 pass diff --git a/src/betamax/fixtures/__init__.py b/src/betamax/fixtures/__init__.py index e69de29..6e03199 100644 --- a/src/betamax/fixtures/__init__.py +++ b/src/betamax/fixtures/__init__.py @@ -0,0 +1 @@ +# noqa: D104 diff --git a/src/betamax/fixtures/pytest.py b/src/betamax/fixtures/pytest.py index 13824fa..7d5c1c8 100644 --- a/src/betamax/fixtures/pytest.py +++ b/src/betamax/fixtures/pytest.py @@ -17,9 +17,11 @@ def _sanitize(name): + """Replace problematic characters. + + Replaces characters which might be problematic when contained in + strings which will be used as file names with '-'s. """ - Replace certain characters (which might be problematic when contained in - strings which will be used as file names) by '-'s. """ return re.sub(r'[\s/<>:\\"|?*]', '-', name) @@ -102,7 +104,6 @@ def betamax_session(betamax_recorder): :returns: An instantiated requests Session wrapped by Betamax. """ - return betamax_recorder.session @@ -144,5 +145,4 @@ def betamax_parametrized_session(betamax_parametrized_recorder): :returns: An instantiated requests Session wrapped by Betamax. """ - return betamax_parametrized_recorder.session diff --git a/src/betamax/fixtures/unittest.py b/src/betamax/fixtures/unittest.py index ae505cc..c27700e 100644 --- a/src/betamax/fixtures/unittest.py +++ b/src/betamax/fixtures/unittest.py @@ -1,4 +1,4 @@ -"""Minimal :class:`unittest.TestCase` subclass adding Betamax integration. +r"""Minimal :class:`unittest.TestCase` subclass adding Betamax integration. .. autoclass:: betamax.fixtures.unittest.BetamaxTestCase :members: @@ -62,7 +62,6 @@ class TestMyApi(unittest.BetamaxTestCase): class BetamaxTestCase(unittest.TestCase): - """Betamax integration for unittest. .. versionadded:: 0.5.0 @@ -75,7 +74,7 @@ class BetamaxTestCase(unittest.TestCase): CASSETTE_LIBRARY_DIR = None def generate_cassette_name(self): - """Generates a cassette name for the current test. + """Generate a cassette name for the current test. The default format is "%(classname)s.%(testMethodName)s" diff --git a/src/betamax/headers.py b/src/betamax/headers.py index c1df11b..6389246 100644 --- a/src/betamax/headers.py +++ b/src/betamax/headers.py @@ -16,7 +16,8 @@ class HTTPHeaderDict(MutableMapping): - """ + """A ``dict`` like container for storing HTTP Headers. + :param headers: An iterable of field-value pairs. Must not contain multiple field names when compared case-insensitively. @@ -24,8 +25,6 @@ class HTTPHeaderDict(MutableMapping): :param kwargs: Additional field-value pairs to pass in to ``dict.update``. - A ``dict`` like container for storing HTTP Headers. - Field names are stored and compared case-insensitively in compliance with RFC 7230. Iteration provides the first case-sensitive key seen for each case-insensitive pair. @@ -49,7 +48,7 @@ class HTTPHeaderDict(MutableMapping): '7' """ - def __init__(self, headers=None, **kwargs): + def __init__(self, headers=None, **kwargs): # noqa: D107 super(HTTPHeaderDict, self).__init__() self._container = {} if headers is not None: @@ -60,21 +59,21 @@ def __init__(self, headers=None, **kwargs): if kwargs: self.extend(kwargs) - def __setitem__(self, key, val): + def __setitem__(self, key, val): # noqa: D105 self._container[key.lower()] = (key, val) return self._container[key.lower()] - def __getitem__(self, key): + def __getitem__(self, key): # noqa: D105 val = self._container[key.lower()] return ', '.join(val[1:]) - def __delitem__(self, key): + def __delitem__(self, key): # noqa: D105 del self._container[key.lower()] - def __contains__(self, key): + def __contains__(self, key): # noqa: D105 return key.lower() in self._container - def __eq__(self, other): + def __eq__(self, other): # noqa: D105 if not isinstance(other, Mapping) and not hasattr(other, 'keys'): return False if not isinstance(other, type(self)): @@ -82,7 +81,7 @@ def __eq__(self, other): return (dict((k.lower(), v) for k, v in self.itermerged()) == dict((k.lower(), v) for k, v in other.itermerged())) - def __ne__(self, other): + def __ne__(self, other): # noqa: D105 return not self.__eq__(other) if not PY3: # Python 2 @@ -91,16 +90,18 @@ def __ne__(self, other): __marker = object() - def __len__(self): + def __len__(self): # noqa: D105 return len(self._container) - def __iter__(self): + def __iter__(self): # noqa: D105 # Only provide the originally cased names for vals in self._container.values(): yield vals[0] def pop(self, key, default=__marker): - """D.pop(k[,d]) -> v, remove specified key and return the value. + """Remove specified key and return the value. + + D.pop(k[,d]) -> v If key is not found, d is returned if given, otherwise KeyError is raised. @@ -119,15 +120,16 @@ def pop(self, key, default=__marker): del self[key] return value - def discard(self, key): + def discard(self, key): # noqa: D102 try: del self[key] except KeyError: pass def add(self, key, val): - """Adds a (name, value) pair, doesn't overwrite the value if it already - exists. + """Add a (name, value) pair. + + Doesn't overwrite the value if it already exists. >>> headers = HTTPHeaderDict(foo='bar') >>> headers.add('Foo', 'baz') @@ -149,7 +151,8 @@ def add(self, key, val): self._container[key_lower] = [vals[0], vals[1], val] def extend(self, *args, **kwargs): - """Generic import function for any type of header-like object. + """Import any type of generic header-like object. + Adapted version of MutableMapping.update in order to insert items with self.add instead of self.__setitem__ """ @@ -175,8 +178,10 @@ def extend(self, *args, **kwargs): self.add(key, value) def getlist(self, key): - """Returns a list of all the values for the named field. Returns an - empty list if the key doesn't exist.""" + """Return a list of all the values for the named field. + + Returns an empty list if the key doesn't exist. + """ try: vals = self._container[key.lower()] except KeyError: @@ -192,7 +197,7 @@ def getlist(self, key): getallmatchingheaders = getlist iget = getlist - def __repr__(self): + def __repr__(self): # noqa: D105 return "%s(%s)" % (type(self).__name__, dict(self.itermerged())) def _copy_from(self, other): @@ -203,7 +208,7 @@ def _copy_from(self, other): val = list(val) self._container[key.lower()] = [key] + val - def copy(self): + def copy(self): # noqa: D102 clone = type(self)() clone._copy_from(self) return clone @@ -221,7 +226,7 @@ def itermerged(self): val = self._container[key.lower()] yield val[0], ', '.join(val[1:]) - def items(self): + def items(self): # noqa: D102 return list(self.iteritems()) @classmethod diff --git a/src/betamax/matchers/__init__.py b/src/betamax/matchers/__init__.py index 5d958ff..8131fdf 100644 --- a/src/betamax/matchers/__init__.py +++ b/src/betamax/matchers/__init__.py @@ -1,3 +1,4 @@ +# noqa: D104 from .base import BaseMatcher from .body import BodyMatcher from .digest_auth import DigestAuthMatcher diff --git a/src/betamax/matchers/base.py b/src/betamax/matchers/base.py index 5fbfa6d..1f01bc4 100644 --- a/src/betamax/matchers/base.py +++ b/src/betamax/matchers/base.py @@ -1,11 +1,12 @@ +# noqa: D100 # -*- coding: utf-8 -*- class BaseMatcher(object): + """Base class for custom matchers. - """ - Base class that ensures sub-classes that implement custom matchers can be - registered and have the only method that is required. + Ensures sub-classes that implement custom matchers can be registered + and have the only method that is required. Usage: @@ -35,13 +36,13 @@ def match(self, request, recorded_request): name = None - def __init__(self): + def __init__(self): # noqa: D107 if not self.name: raise ValueError('Matchers require names') self.on_init() def on_init(self): - """Method to implement if you wish something to happen in ``__init__``. + """Implement if you wish something to happen in ``__init__``. The return value is not checked and this is called at the end of ``__init__``. It is meant to provide the matcher author a way to @@ -51,7 +52,7 @@ def on_init(self): return None def match(self, request, recorded_request): - """A method that must be implemented by the user. + """Implement to determine if requests match. :param PreparedRequest request: A requests PreparedRequest object :param dict recorded_request: A dictionary containing the serialized diff --git a/src/betamax/matchers/body.py b/src/betamax/matchers/body.py index e3f6d81..aac4bf0 100644 --- a/src/betamax/matchers/body.py +++ b/src/betamax/matchers/body.py @@ -1,3 +1,4 @@ +# noqa: D100 # -*- coding: utf-8 -*- from .base import BaseMatcher @@ -5,10 +6,11 @@ class BodyMatcher(BaseMatcher): - # Matches based on the body of the request + """Match based on the body of the request.""" + name = 'body' - def match(self, request, recorded_request): + def match(self, request, recorded_request): # noqa: D102 recorded_request = util.deserialize_prepared_request(recorded_request) request_body = b'' diff --git a/src/betamax/matchers/digest_auth.py b/src/betamax/matchers/digest_auth.py index fa7b548..0787fea 100644 --- a/src/betamax/matchers/digest_auth.py +++ b/src/betamax/matchers/digest_auth.py @@ -1,10 +1,10 @@ +# noqa: D100 # -*- coding: utf-8 -*- from .base import BaseMatcher from betamax.util import from_list class DigestAuthMatcher(BaseMatcher): - """This matcher is provided to help those who need to use Digest Auth. .. note:: @@ -25,12 +25,12 @@ class DigestAuthMatcher(BaseMatcher): name = 'digest-auth' - def match(self, request, recorded_request): + def match(self, request, recorded_request): # noqa: D102 request_digest = self.digest_parts(request.headers) recorded_digest = self.digest_parts(recorded_request['headers']) return request_digest == recorded_digest - def digest_parts(self, headers): + def digest_parts(self, headers): # noqa: D102 auth = headers.get('Authorization') or headers.get('authorization') if not auth: return None diff --git a/src/betamax/matchers/headers.py b/src/betamax/matchers/headers.py index 9d7f718..786ed65 100644 --- a/src/betamax/matchers/headers.py +++ b/src/betamax/matchers/headers.py @@ -1,15 +1,17 @@ +# noqa: D100 # -*- coding: utf-8 -*- from .base import BaseMatcher class HeadersMatcher(BaseMatcher): - # Matches based on the headers of the request + """Match based on the headers of the request.""" + name = 'headers' - def match(self, request, recorded_request): + def match(self, request, recorded_request): # noqa: D102 return dict(request.headers) == self.flatten_headers(recorded_request) - def flatten_headers(self, request): + def flatten_headers(self, request): # noqa: D102 from betamax.util import from_list headers = request['headers'].items() return dict((k, from_list(v)) for (k, v) in headers) diff --git a/src/betamax/matchers/host.py b/src/betamax/matchers/host.py index 67445ea..24e0ef1 100644 --- a/src/betamax/matchers/host.py +++ b/src/betamax/matchers/host.py @@ -1,13 +1,15 @@ +# noqa: D100 # -*- coding: utf-8 -*- from .base import BaseMatcher from requests.compat import urlparse class HostMatcher(BaseMatcher): - # Matches based on the host of the request + """Match based on the host of the request.""" + name = 'host' - def match(self, request, recorded_request): + def match(self, request, recorded_request): # noqa: D102 request_host = urlparse(request.url).netloc recorded_host = urlparse(recorded_request['uri']).netloc return request_host == recorded_host diff --git a/src/betamax/matchers/method.py b/src/betamax/matchers/method.py index 53c0653..ae5ce91 100644 --- a/src/betamax/matchers/method.py +++ b/src/betamax/matchers/method.py @@ -1,10 +1,12 @@ +# noqa: D100 # -*- coding: utf-8 -*- from .base import BaseMatcher class MethodMatcher(BaseMatcher): - # Matches based on the method of the request + """Match based on the method of the request.""" + name = 'method' - def match(self, request, recorded_request): + def match(self, request, recorded_request): # noqa: D102 return request.method == recorded_request['method'] diff --git a/src/betamax/matchers/path.py b/src/betamax/matchers/path.py index 16f51c5..7c35740 100644 --- a/src/betamax/matchers/path.py +++ b/src/betamax/matchers/path.py @@ -1,13 +1,15 @@ +# noqa: D100 # -*- coding: utf-8 -*- from .base import BaseMatcher from requests.compat import urlparse class PathMatcher(BaseMatcher): - # Matches based on the path of the request + """Match based on the path of the request.""" + name = 'path' - def match(self, request, recorded_request): + def match(self, request, recorded_request): # noqa: D102 request_path = urlparse(request.url).path recorded_path = urlparse(recorded_request['uri']).path return request_path == recorded_path diff --git a/src/betamax/matchers/query.py b/src/betamax/matchers/query.py index 432104c..e3f98d8 100644 --- a/src/betamax/matchers/query.py +++ b/src/betamax/matchers/query.py @@ -1,3 +1,4 @@ +# noqa: D100 # -*- coding: utf-8 -*- import sys @@ -13,7 +14,8 @@ class QueryMatcher(BaseMatcher): - # Matches based on the query of the request + """Match based on the query of the request.""" + name = 'query' def to_dict(self, query): @@ -23,7 +25,7 @@ def to_dict(self, query): keep_blank_values=True, ) - def match(self, request, recorded_request): + def match(self, request, recorded_request): # noqa: D102 request_query_dict = self.to_dict(urlparse(request.url).query) recorded_query = urlparse(recorded_request['uri']).query if recorded_query and isPY2: diff --git a/src/betamax/matchers/uri.py b/src/betamax/matchers/uri.py index 8af0e76..26985b8 100644 --- a/src/betamax/matchers/uri.py +++ b/src/betamax/matchers/uri.py @@ -1,3 +1,4 @@ +# noqa: D100 # -*- coding: utf-8 -*- from .base import BaseMatcher from .query import QueryMatcher @@ -5,19 +6,20 @@ class URIMatcher(BaseMatcher): - # Matches based on the uri of the request + """Match based on the uri of the request.""" + name = 'uri' def on_init(self): - # Get something we can use to match query strings with + """Get something we can use to match query strings with.""" self.query_matcher = QueryMatcher().match - def match(self, request, recorded_request): + def match(self, request, recorded_request): # noqa: D102 queries_match = self.query_matcher(request, recorded_request) request_url, recorded_url = request.url, recorded_request['uri'] return self.all_equal(request_url, recorded_url) and queries_match - def parse(self, uri): + def parse(self, uri): # noqa: D102 parsed = urlparse(uri) return { 'scheme': parsed.scheme, @@ -26,7 +28,7 @@ def parse(self, uri): 'fragment': parsed.fragment } - def all_equal(self, new_uri, recorded_uri): + def all_equal(self, new_uri, recorded_uri): # noqa: D102 new_parsed = self.parse(new_uri) recorded_parsed = self.parse(recorded_uri) return (new_parsed == recorded_parsed) diff --git a/src/betamax/mock_response.py b/src/betamax/mock_response.py index ffcc1b6..3124f59 100644 --- a/src/betamax/mock_response.py +++ b/src/betamax/mock_response.py @@ -1,9 +1,10 @@ +# noqa: D100 from email import parser, message import sys -class MockHTTPResponse(object): - def __init__(self, headers): +class MockHTTPResponse(object): # noqa: D101 + def __init__(self, headers): # noqa: D107 from betamax.util import coerce_content h = ["%s: %s" % (k, v) for k in headers for v in headers.getlist(k)] @@ -18,10 +19,10 @@ def __init__(self, headers): self.msg = p.parsestr(h) self.msg.set_payload(h) - def isclosed(self): + def isclosed(self): # noqa: D102 return False -class EmailMessage(message.Message): - def getheaders(self, value, *args): +class EmailMessage(message.Message): # noqa: D101 + def getheaders(self, value, *args): # noqa: D102 return self.get_all(value, []) diff --git a/src/betamax/options.py b/src/betamax/options.py index c2bcc8f..84b6418 100644 --- a/src/betamax/options.py +++ b/src/betamax/options.py @@ -1,24 +1,25 @@ +# noqa: D100 from .cassette import Cassette from .exceptions import InvalidOption, validation_error_map -def validate_record(record): +def validate_record(record): # noqa: D103 return record in ['all', 'new_episodes', 'none', 'once'] -def validate_matchers(matchers): +def validate_matchers(matchers): # noqa: D103 from betamax.matchers import matcher_registry available_matchers = list(matcher_registry.keys()) return all(m in available_matchers for m in matchers) -def validate_serializer(serializer): +def validate_serializer(serializer): # noqa: D103 from betamax.serializers import serializer_registry return serializer in list(serializer_registry.keys()) def validate_placeholders(placeholders): - """Validate placeholders is a dict-like structure""" + """Validate placeholders is a dict-like structure.""" keys = ['placeholder', 'replace'] try: return all(sorted(list(p.keys())) == keys for p in placeholders) @@ -26,16 +27,16 @@ def validate_placeholders(placeholders): return False -def translate_cassette_options(): +def translate_cassette_options(): # noqa: D103 for (k, v) in Cassette.default_cassette_options.items(): yield (k, v) if k != 'record_mode' else ('record', v) -def isboolean(value): +def isboolean(value): # noqa: D103 return value in [True, False] -class Options(object): +class Options(object): # noqa: D101 valid_options = { 'match_requests_on': validate_matchers, 're_record_interval': lambda x: x is None or x > 0, @@ -58,32 +59,32 @@ class Options(object): 'allow_playback_repeats': False, } - def __init__(self, data=None): + def __init__(self, data=None): # noqa: D107 self.data = data or {} self.validate() self.defaults = Options.defaults.copy() self.defaults.update(translate_cassette_options()) - def __repr__(self): + def __repr__(self): # noqa: D105 return 'Options(%s)' % self.data - def __getitem__(self, key): + def __getitem__(self, key): # noqa: D105 return self.data.get(key, self.defaults.get(key)) - def __setitem__(self, key, value): + def __setitem__(self, key, value): # noqa: D105 self.data[key] = value return value - def __delitem__(self, key): + def __delitem__(self, key): # noqa: D105 del self.data[key] - def __contains__(self, key): + def __contains__(self, key): # noqa: D105 return key in self.data - def items(self): + def items(self): # noqa: D102 return self.data.items() - def validate(self): + def validate(self): # noqa: D102 for key, value in list(self.data.items()): if key not in Options.valid_options: raise InvalidOption('{0} is not a valid option'.format(key)) diff --git a/src/betamax/recorder.py b/src/betamax/recorder.py index d89b8bd..e0ffac5 100644 --- a/src/betamax/recorder.py +++ b/src/betamax/recorder.py @@ -1,3 +1,4 @@ +# noqa: D100 # -*- coding: utf-8 -*- from . import matchers, serializers from .adapter import BetamaxAdapter @@ -7,7 +8,6 @@ class Betamax(object): - """This object contains the main API of the request-vcr library. This object is entirely a context manager so all you have to do is: @@ -45,7 +45,7 @@ class Betamax(object): """ - def __init__(self, session, cassette_library_dir=None, + def __init__(self, session, cassette_library_dir=None, # noqa: D107 default_cassette_options={}): #: Store the requests.Session object being wrapped. self.session = session @@ -64,11 +64,11 @@ def __init__(self, session, cassette_library_dir=None, if cassette_library_dir: self.config.cassette_library_dir = cassette_library_dir - def __enter__(self): + def __enter__(self): # noqa: D105 self.start() return self - def __exit__(self, *ex_args): + def __exit__(self, *ex_args): # noqa: D105 self.stop() # ex_args comes through as the exception type, exception value and # exception traceback. If any of them are not None, we should probably diff --git a/src/betamax/serializers/__init__.py b/src/betamax/serializers/__init__.py index 2721e61..699777f 100644 --- a/src/betamax/serializers/__init__.py +++ b/src/betamax/serializers/__init__.py @@ -1,3 +1,4 @@ +# noqa: D104 # -*- coding: utf-8 -*- from .base import BaseSerializer from .json_serializer import JSONSerializer diff --git a/src/betamax/serializers/base.py b/src/betamax/serializers/base.py index 5b9e9e7..d3c2107 100644 --- a/src/betamax/serializers/base.py +++ b/src/betamax/serializers/base.py @@ -1,3 +1,4 @@ +# noqa: D100 # -*- coding: utf-8 -*- NOT_IMPLEMENTED_ERROR_MSG = ('This method must be implemented by classes' ' inheriting from BaseSerializer.') @@ -39,10 +40,10 @@ def deserialize(self, cassette_data): stored_as_binary = False @staticmethod - def generate_cassette_name(cassette_library_dir, cassette_name): + def generate_cassette_name(cassette_library_dir, cassette_name): # noqa: D102, E501 raise NotImplementedError(NOT_IMPLEMENTED_ERROR_MSG) - def __init__(self): + def __init__(self): # noqa: D107 if not self.name: raise ValueError("Serializer's name attribute must be a string" " value, not None.") @@ -50,7 +51,7 @@ def __init__(self): self.on_init() def on_init(self): - """Method to implement if you wish something to happen in ``__init__``. + """Implement this if you wish something to happen in ``__init__``. The return value is not checked and this is called at the end of ``__init__``. It is meant to provide the matcher author a way to @@ -60,7 +61,7 @@ def on_init(self): return None def serialize(self, cassette_data): - """A method that must be implemented by the Serializer author. + """Implement this if you wish to serialize the cassette data. :param dict cassette_data: A dictionary with two keys: ``http_interactions``, ``recorded_with``. @@ -69,7 +70,7 @@ def serialize(self, cassette_data): raise NotImplementedError(NOT_IMPLEMENTED_ERROR_MSG) def deserialize(self, cassette_data): - """A method that must be implemented by the Serializer author. + """Implement this if you wish to deserialize the cassette data. The return value is extremely important. If it is not empty, the dictionary returned must have the following structure:: diff --git a/src/betamax/serializers/json_serializer.py b/src/betamax/serializers/json_serializer.py index 74e9d94..bab9095 100644 --- a/src/betamax/serializers/json_serializer.py +++ b/src/betamax/serializers/json_serializer.py @@ -1,3 +1,4 @@ +# noqa: D100 from .base import BaseSerializer import json @@ -5,19 +6,20 @@ class JSONSerializer(BaseSerializer): - # Serializes and deserializes a cassette to JSON + """Serialize and deserialize a cassette to JSON.""" + name = 'json' stored_as_binary = False @staticmethod - def generate_cassette_name(cassette_library_dir, cassette_name): + def generate_cassette_name(cassette_library_dir, cassette_name): # noqa: D102, E501 return os.path.join(cassette_library_dir, '{0}.{1}'.format(cassette_name, 'json')) - def serialize(self, cassette_data): + def serialize(self, cassette_data): # noqa: D102 return json.dumps(cassette_data) - def deserialize(self, cassette_data): + def deserialize(self, cassette_data): # noqa: D102 try: deserialized_data = json.loads(cassette_data) except ValueError: diff --git a/src/betamax/serializers/proxy.py b/src/betamax/serializers/proxy.py index 418687a..b434b36 100644 --- a/src/betamax/serializers/proxy.py +++ b/src/betamax/serializers/proxy.py @@ -1,3 +1,4 @@ +# noqa: D100 # -*- coding: utf-8 -*- from .base import BaseSerializer from betamax.exceptions import MissingDirectoryError @@ -6,7 +7,6 @@ class SerializerProxy(BaseSerializer): - """ This is an internal implementation detail of the betamax library. @@ -22,7 +22,7 @@ class SerializerProxy(BaseSerializer): """ - def __init__(self, serializer, cassette_path, allow_serialization=False): + def __init__(self, serializer, cassette_path, allow_serialization=False): # noqa: D107, E501 self.proxied_serializer = serializer self.allow_serialization = allow_serialization self.cassette_path = cassette_path @@ -37,7 +37,7 @@ def _ensure_path_exists(self): if not os.path.exists(self.cassette_path): open(self.cassette_path, 'w+').close() - def corrected_file_mode(self, base_mode): + def corrected_file_mode(self, base_mode): # noqa: D102 storing_binary_data = getattr(self.proxied_serializer, 'stored_as_binary', False) @@ -46,7 +46,7 @@ def corrected_file_mode(self, base_mode): return base_mode @classmethod - def find(cls, serialize_with, cassette_library_dir, cassette_name): + def find(cls, serialize_with, cassette_library_dir, cassette_name): # noqa: D102, E501 from . import serializer_registry serializer = serializer_registry.get(serialize_with) if serializer is None: @@ -60,13 +60,13 @@ def find(cls, serialize_with, cassette_library_dir, cassette_name): return cls(serializer, cassette_path) @staticmethod - def generate_cassette_name(serializer, cassette_library_dir, + def generate_cassette_name(serializer, cassette_library_dir, # noqa: D102 cassette_name): return serializer.generate_cassette_name( cassette_library_dir, cassette_name ) - def serialize(self, cassette_data): + def serialize(self, cassette_data): # noqa: D102 if not self.allow_serialization: return @@ -76,7 +76,7 @@ def serialize(self, cassette_data): with open(self.cassette_path, mode) as fd: fd.write(self.proxied_serializer.serialize(cassette_data)) - def deserialize(self): + def deserialize(self): # noqa: D102 self._ensure_path_exists() data = {} diff --git a/src/betamax/util.py b/src/betamax/util.py index 3090acc..3526c5e 100644 --- a/src/betamax/util.py +++ b/src/betamax/util.py @@ -1,3 +1,4 @@ +# noqa: D100 from .mock_response import MockHTTPResponse from datetime import datetime from requests.models import PreparedRequest, Response @@ -16,26 +17,26 @@ import sys -def coerce_content(content, encoding=None): +def coerce_content(content, encoding=None): # noqa: D103 if hasattr(content, 'decode'): content = content.decode(encoding or 'utf-8', 'replace') return content -def body_io(string, encoding=None): +def body_io(string, encoding=None): # noqa: D103 if hasattr(string, 'encode'): string = string.encode(encoding or 'utf-8') return io.BytesIO(string) -def from_list(value): +def from_list(value): # noqa: D103 if isinstance(value, list): return value[0] return value def add_body(r, preserve_exact_body_bytes, body_dict): - """Simple function which takes a response or request and coerces the body. + """Take a response or request and coerce the body. This function adds either ``'string'`` or ``'base64_string'`` to ``body_dict``. If ``preserve_exact_body_bytes`` is ``True`` then it @@ -65,7 +66,7 @@ def add_body(r, preserve_exact_body_bytes, body_dict): body_dict['string'] = coerce_content(body, body_dict['encoding']) -def serialize_prepared_request(request, preserve_exact_body_bytes): +def serialize_prepared_request(request, preserve_exact_body_bytes): # noqa: D103, E501 headers = request.headers body = {'encoding': 'utf-8'} add_body(request, preserve_exact_body_bytes, body) @@ -79,7 +80,7 @@ def serialize_prepared_request(request, preserve_exact_body_bytes): } -def deserialize_prepared_request(serialized): +def deserialize_prepared_request(serialized): # noqa: D103 p = PreparedRequest() p._cookies = RequestsCookieJar() body = serialized['body'] @@ -96,7 +97,7 @@ def deserialize_prepared_request(serialized): return p -def serialize_response(response, preserve_exact_body_bytes): +def serialize_response(response, preserve_exact_body_bytes): # noqa: D103 body = {'encoding': response.encoding} add_body(response, preserve_exact_body_bytes, body) header_map = HTTPHeaderDict(response.raw.headers) @@ -112,7 +113,7 @@ def serialize_response(response, preserve_exact_body_bytes): } -def deserialize_response(serialized): +def deserialize_response(serialized): # noqa: D103 r = Response() r.encoding = serialized['body']['encoding'] header_dict = HTTPHeaderDict() @@ -136,7 +137,7 @@ def deserialize_response(serialized): return r -def add_urllib3_response(serialized, response, headers): +def add_urllib3_response(serialized, response, headers): # noqa: D103 if 'base64_string' in serialized['body']: body = io.BytesIO( base64.b64decode(serialized['body']['base64_string'].encode()) @@ -162,7 +163,7 @@ def add_urllib3_response(serialized, response, headers): response.raw = h -def timestamp(): +def timestamp(): # noqa: D103 stamp = datetime.utcnow().isoformat() try: i = stamp.rindex('.')