From 41949f7dc64a2ddb8a9c2cb845eac7bb8b94380b Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Wed, 1 Jul 2015 09:51:32 +0100 Subject: [PATCH] use conditional requirements for backport libraries Fixes #147 --- .travis.yml | 2 +- setup.py | 9 +++++++-- tests/unit/test_cassettes.py | 5 ++--- tests/unit/test_serialize.py | 2 +- tests/unit/test_vcr.py | 2 +- vcr/cassette.py | 11 ++++------- vcr/compat.py | 18 ++++++++++++++++++ vcr/config.py | 2 +- vcr/filters.py | 8 +++----- vcr/patch.py | 8 +++----- 10 files changed, 41 insertions(+), 26 deletions(-) create mode 100644 vcr/compat.py diff --git a/.travis.yml b/.travis.yml index 594b492..93fea8b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ python: - 3.4 - pypy install: -- pip install PyYAML pytest pytest-localserver --use-mirrors +- pip install . - if [ $WITH_LIB = "requests1.x" ] ; then pip install requests==1.2.3; fi - if [ $WITH_LIB = "requests2.2" ] ; then pip install requests==2.2.1; fi - if [ $WITH_LIB = "requests2.3" ] ; then pip install requests==2.3.0; fi diff --git a/setup.py b/setup.py index 1c6ec59..aeeb415 100644 --- a/setup.py +++ b/setup.py @@ -19,6 +19,7 @@ class PyTest(TestCommand): errno = pytest.main(self.test_args) sys.exit(errno) + setup( name='vcrpy', version='1.5.2', @@ -31,8 +32,12 @@ setup( author_email='me@kevinmccarthy.org', url='https://github.com/kevin1024/vcrpy', packages=find_packages(exclude=("tests*",)), - install_requires=['PyYAML', 'mock', 'six>=1.5', 'contextlib2', - 'wrapt', 'backport_collections'], + install_requires=['PyYAML', 'wrapt', 'six>=1.5'], + extras_require = { + ':python_version in "2.4, 2.5, 2.6"': + ['contextlib2', 'backport_collections', 'mock'], + ':python_version in "2.7, 3.1, 3.2"': ['contextlib2', 'mock'], + }, license='MIT', tests_require=['pytest', 'mock', 'pytest-localserver'], cmdclass={'test': PyTest}, diff --git a/tests/unit/test_cassettes.py b/tests/unit/test_cassettes.py index 947ffa4..e7d8b7c 100644 --- a/tests/unit/test_cassettes.py +++ b/tests/unit/test_cassettes.py @@ -3,11 +3,10 @@ import inspect import os from six.moves import http_client as httplib -import contextlib2 -import mock import pytest import yaml +from vcr.compat import mock, contextlib from vcr.cassette import Cassette from vcr.errors import UnhandledHTTPRequestError from vcr.patch import force_reset @@ -158,7 +157,7 @@ def test_nesting_cassette_context_managers(*args): second_response = copy.deepcopy(first_response) second_response['body']['string'] = b'second_response' - with contextlib2.ExitStack() as exit_stack: + with contextlib.ExitStack() as exit_stack: first_cassette = exit_stack.enter_context(Cassette.use(path='test')) exit_stack.enter_context(mock.patch.object(first_cassette, 'play_response', return_value=first_response)) diff --git a/tests/unit/test_serialize.py b/tests/unit/test_serialize.py index 5f2a9aa..41d97bd 100644 --- a/tests/unit/test_serialize.py +++ b/tests/unit/test_serialize.py @@ -1,6 +1,6 @@ -import mock import pytest +from vcr.compat import mock from vcr.serialize import deserialize from vcr.serializers import yamlserializer, jsonserializer diff --git a/tests/unit/test_vcr.py b/tests/unit/test_vcr.py index d58d96c..8b1de97 100644 --- a/tests/unit/test_vcr.py +++ b/tests/unit/test_vcr.py @@ -1,9 +1,9 @@ import os -import mock import pytest from vcr import VCR, use_cassette +from vcr.compat import mock from vcr.request import Request from vcr.stubs import VCRHTTPSConnection diff --git a/vcr/cassette.py b/vcr/cassette.py index 77b5395..87d2598 100644 --- a/vcr/cassette.py +++ b/vcr/cassette.py @@ -2,14 +2,11 @@ import functools import logging -import contextlib2 + import wrapt -try: - from collections import Counter -except ImportError: - from backport_collections import Counter # Internal imports +from .compat import contextlib, collections from .errors import UnhandledHTTPRequestError from .matchers import requests_match, uri, method from .patch import CassettePatcherBuilder @@ -43,7 +40,7 @@ class CassetteContextDecorator(object): self.__finish = None def _patch_generator(self, cassette): - with contextlib2.ExitStack() as exit_stack: + with contextlib.ExitStack() as exit_stack: for patcher in CassettePatcherBuilder(cassette).build(): exit_stack.enter_context(patcher) log.debug('Entered context for cassette at {0}.'.format(cassette._path)) @@ -148,7 +145,7 @@ class Cassette(object): # self.data is the list of (req, resp) tuples self.data = [] - self.play_counts = Counter() + self.play_counts = collections.Counter() self.dirty = False self.rewound = False diff --git a/vcr/compat.py b/vcr/compat.py new file mode 100644 index 0000000..e76c68f --- /dev/null +++ b/vcr/compat.py @@ -0,0 +1,18 @@ +try: + from unittest import mock +except ImportError: + import mock + +try: + import contextlib +except ImportError: + import contextlib2 as contextlib +else: + if not hasattr(contextlib, 'ExitStack'): + import contextlib2 as contextlib + +import collections +if not hasattr(collections, 'Counter'): + import backport_collections as collections + +__all__ = ['mock', 'contextlib', 'collections'] diff --git a/vcr/config.py b/vcr/config.py index fb03136..1faef3b 100644 --- a/vcr/config.py +++ b/vcr/config.py @@ -1,4 +1,3 @@ -import collections import copy import functools import inspect @@ -6,6 +5,7 @@ import os import six +from .compat import collections from .cassette import Cassette from .serializers import yamlserializer, jsonserializer from .util import compose diff --git a/vcr/filters.py b/vcr/filters.py index 84f06c8..14159d0 100644 --- a/vcr/filters.py +++ b/vcr/filters.py @@ -1,12 +1,10 @@ from six import BytesIO, text_type from six.moves.urllib.parse import urlparse, urlencode, urlunparse -try: - from collections import OrderedDict -except ImportError: - from backport_collections import OrderedDict import copy import json +from .compat import collections + def remove_headers(request, headers_to_remove): headers = copy.copy(request.headers) @@ -40,7 +38,7 @@ def remove_post_data_parameters(request, post_data_parameters_to_remove): del json_data[k] request.body = json.dumps(json_data).encode('utf-8') else: - post_data = OrderedDict() + post_data = collections.OrderedDict() if isinstance(request.body, text_type): request.body = request.body.encode('utf-8') diff --git a/vcr/patch.py b/vcr/patch.py index 1d9edb5..caed9fa 100644 --- a/vcr/patch.py +++ b/vcr/patch.py @@ -2,9 +2,7 @@ import functools import itertools -import contextlib2 -import mock - +from .compat import contextlib, mock from .stubs import VCRHTTPConnection, VCRHTTPSConnection from six.moves import http_client as httplib @@ -323,9 +321,9 @@ def reset_patchers(): _CertValidatingHTTPSConnection) -@contextlib2.contextmanager +@contextlib.contextmanager def force_reset(): - with contextlib2.ExitStack() as exit_stack: + with contextlib.ExitStack() as exit_stack: for patcher in reset_patchers(): exit_stack.enter_context(patcher) yield