diff --git a/README.rst b/README.rst
index 23910bb..768e850 100644
--- a/README.rst
+++ b/README.rst
@@ -1,16 +1,14 @@
-|Build Status| |Stories in Ready| |Gitter|
-
 VCR.py
 ======
 
-.. figure:: https://raw.github.com/kevin1024/vcrpy/master/vcr.png
+.. image:: vcr.png
    :alt: vcr.py
 
-   vcr.py
-
 This is a Python version of `Ruby's VCR
 library <https://github.com/vcr/vcr>`__.
 
+|Build Status| |Stories in Ready| |Gitter Chat|
+
 What it does
 ------------
 
@@ -758,6 +756,6 @@ more details
    :target: http://travis-ci.org/kevin1024/vcrpy
 .. |Stories in Ready| image:: https://badge.waffle.io/kevin1024/vcrpy.png?label=ready&title=Ready
    :target: https://waffle.io/kevin1024/vcrpy
-.. |Gitter| image:: https://badges.gitter.im/Join%20Chat.svg
+.. |Gitter Chat| image:: https://badges.gitter.im/Join%20Chat.svg
    :alt: Join the chat at https://gitter.im/kevin1024/vcrpy
    :target: https://gitter.im/kevin1024/vcrpy?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
diff --git a/vcr/cassette.py b/vcr/cassette.py
index bc7410f..6dc6c40 100644
--- a/vcr/cassette.py
+++ b/vcr/cassette.py
@@ -75,7 +75,7 @@ class CassetteContextDecorator(object):
             lambda key, _: key in self._non_cassette_arguments,
             self._args_getter()
         )
-        if 'path_transformer' in other_kwargs:
+        if other_kwargs.get('path_transformer'):
             transformer = other_kwargs['path_transformer']
             cassette_kwargs['path'] = transformer(cassette_kwargs['path'])
         self.__finish = self._patch_generator(self.cls.load(**cassette_kwargs))
diff --git a/vcr/config.py b/vcr/config.py
index 455d074..99e4cf7 100644
--- a/vcr/config.py
+++ b/vcr/config.py
@@ -2,25 +2,19 @@ import copy
 import functools
 import inspect
 import os
-import types
 
 import six
 
 from .compat import collections
 from .cassette import Cassette
 from .serializers import yamlserializer, jsonserializer
-from .util import compose, auto_decorate
+from .util import compose
 from . import matchers
 from . import filters
 
 
 class VCR(object):
 
-    @staticmethod
-    def is_test_method(method_name, function):
-        return method_name.startswith('test') and \
-            isinstance(function, types.FunctionType)
-
     @staticmethod
     def ensure_suffix(suffix):
         def ensure(path):
@@ -29,7 +23,7 @@ class VCR(object):
             return path
         return ensure
 
-    def __init__(self, path_transformer=lambda x: x, before_record_request=None,
+    def __init__(self, path_transformer=None, before_record_request=None,
                  custom_patches=(), filter_query_parameters=(), ignore_hosts=(),
                  record_mode="once", ignore_localhost=False, filter_headers=(),
                  before_record_response=None, filter_post_data_parameters=(),
@@ -114,7 +108,7 @@ class VCR(object):
         matcher_names = kwargs.get('match_on', self.match_on)
         path_transformer = kwargs.get(
             'path_transformer',
-            self.path_transformer or self.ensure_suffix('.yaml')
+            self.path_transformer
         )
         func_path_generator = kwargs.get(
             'func_path_generator',
@@ -208,7 +202,7 @@ class VCR(object):
         if filter_query_parameters:
             filter_functions.append(functools.partial(
                 filters.remove_query_parameters,
-               query_parameters_to_remove=filter_query_parameters
+                query_parameters_to_remove=filter_query_parameters
             ))
         if filter_post_data_parameters:
             filter_functions.append(
@@ -256,7 +250,3 @@ class VCR(object):
 
     def register_matcher(self, name, matcher):
         self.matchers[name] = matcher
-
-    def test_case(self, predicate=None):
-        predicate = predicate or self.is_test_method
-        return six.with_metaclass(auto_decorate(self.use_cassette, predicate))
diff --git a/vcr/util.py b/vcr/util.py
index dd66320..b36ff75 100644
--- a/vcr/util.py
+++ b/vcr/util.py
@@ -1,6 +1,4 @@
 import collections
-import types
-
 
 # Shamelessly stolen from https://github.com/kennethreitz/requests/blob/master/requests/structures.py
 class CaseInsensitiveDict(collections.MutableMapping):
@@ -83,8 +81,9 @@ def partition_dict(predicate, dictionary):
 def compose(*functions):
     def composed(incoming):
         res = incoming
-        for function in functions[::-1]:
-            res = function(res)
+        for function in reversed(functions):
+            if function:
+                res = function(res)
         return res
     return composed
 
@@ -92,30 +91,3 @@ def read_body(request):
     if hasattr(request.body, 'read'):
         return request.body.read()
     return request.body
-
-
-def auto_decorate(
-    decorator,
-    predicate=lambda name, value: isinstance(value, types.FunctionType)
-):
-    def maybe_decorate(attribute, value):
-        if predicate(attribute, value):
-            value = decorator(value)
-        return value
-
-    class DecorateAll(type):
-
-        def __setattr__(cls, attribute, value):
-            return super(DecorateAll, cls).__setattr__(
-                attribute, maybe_decorate(attribute, value)
-            )
-
-        def __new__(cls, name, bases, attributes_dict):
-            new_attributes_dict = dict(
-                (attribute, maybe_decorate(attribute, value))
-                for attribute, value in attributes_dict.items()
-            )
-            return super(DecorateAll, cls).__new__(
-                cls, name, bases, new_attributes_dict
-            )
-    return DecorateAll

path_transformer doesn't default properly
In the code, we have

```python
class VCR(object):
    def __init__(self, path_transformer=lambda x: x, before_record_request=None,
```

and then later

```python
    def get_merged_config(self, **kwargs):
        path_transformer = kwargs.get(
            'path_transformer',
            self.path_transformer or self.ensure_suffix('.yaml')
        )
```

and then later

```python
        if 'path_transformer' in other_kwargs:
            transformer = other_kwargs['path_transformer']
            cassette_kwargs['path'] = transformer(cassette_kwargs['path'])
```

So there are two problems with this code:
  1. The default `ensure_suffix` doesn't fire because the parameter default is already the identity function which is truthy. The only way this fires is if the user specifies `path_transformer=None` which is surely not the intent.
  2. If the context manager is called with `path_transformer=None` then it will blow up.
diff --git a/tests/unit/test_cassettes.py b/tests/unit/test_cassettes.py
index e1e9fb9..413b154 100644
--- a/tests/unit/test_cassettes.py
+++ b/tests/unit/test_cassettes.py
@@ -245,6 +245,13 @@ def test_path_transformer_with_context_manager():
         assert cassette._path == 'a'
 
 
+def test_path_transformer_None():
+    with Cassette.use(
+        path='a', path_transformer=None,
+    ) as cassette:
+        assert cassette._path == 'a'
+
+
 def test_func_path_generator():
     def generator(function):
         return os.path.join(os.path.dirname(inspect.getfile(function)),
diff --git a/tests/unit/test_vcr.py b/tests/unit/test_vcr.py
index 7150f15..6cbf21b 100644
--- a/tests/unit/test_vcr.py
+++ b/tests/unit/test_vcr.py
@@ -1,13 +1,11 @@
 import os
 
 import pytest
-from six.moves import http_client as httplib
 
 from vcr import VCR, use_cassette
 from vcr.compat import mock
 from vcr.request import Request
 from vcr.stubs import VCRHTTPSConnection
-from vcr.patch import _HTTPConnection, force_reset
 
 
 def test_vcr_use_cassette():
@@ -100,6 +98,28 @@ def test_vcr_before_record_response_iterable():
             assert mock_filter.call_count == 1
 
 
+def test_vcr_path_transformer():
+    # Regression test for #199
+
+    # Prevent actually saving the cassette
+    with mock.patch('vcr.cassette.save_cassette'):
+
+        # Baseline: path should be unchanged
+        vcr = VCR()
+        with vcr.use_cassette('test') as cassette:
+            assert cassette._path == 'test'
+
+        # Regression test: path_transformer=None should do the same.
+        vcr = VCR(path_transformer=None)
+        with vcr.use_cassette('test') as cassette:
+            assert cassette._path == 'test'
+
+        # and it should still work with cassette_library_dir
+        vcr = VCR(cassette_library_dir='/foo')
+        with vcr.use_cassette('test') as cassette:
+            assert cassette._path == '/foo/test'
+
+
 @pytest.fixture
 def random_fixture():
     return 1
@@ -245,7 +265,6 @@ def test_path_transformer():
 
 def test_cassette_name_generator_defaults_to_using_module_function_defined_in():
     vcr = VCR(inject_cassette=True)
-
     @vcr.use_cassette
     def function_name(cassette):
         assert cassette._path == os.path.join(os.path.dirname(__file__),
@@ -277,29 +296,3 @@ def test_additional_matchers():
 
     function_defaults()
     function_additional()
-
-
-class TestVCRClass(VCR().test_case()):
-
-    def no_decoration(self):
-        assert httplib.HTTPConnection == _HTTPConnection
-        self.test_dynamically_added()
-        assert httplib.HTTPConnection == _HTTPConnection
-
-    def test_one(self):
-        with force_reset():
-            self.no_decoration()
-        with force_reset():
-            self.test_two()
-        assert httplib.HTTPConnection != _HTTPConnection
-
-    def test_two(self):
-        assert httplib.HTTPConnection != _HTTPConnection
-
-
-def test_dynamically_added(self):
-    assert httplib.HTTPConnection != _HTTPConnection
-
-
-TestVCRClass.test_dynamically_added = test_dynamically_added
-del test_dynamically_added

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-localserver mock
apt-get update apt-get install -y gcc
3.7
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
certifi @ file:///croot/certifi_1671487769961/work/certifi
exceptiongroup==1.2.2
importlib-metadata==6.7.0
iniconfig==2.0.0
MarkupSafe==2.1.5
mock==5.2.0
packaging==24.0
pluggy==1.2.0
pytest==7.4.4
pytest-localserver==0.9.0.post0
PyYAML==6.0.1
six==1.17.0
tomli==2.0.1
typing_extensions==4.7.1
-e git+https://github.com/kevin1024/vcrpy.git@d620095c3667cc7f9fd7ea1213948dd58db6aefb#egg=vcrpy
Werkzeug==2.2.3
wrapt==1.16.0
zipp==3.15.0

name: vcrpy
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2022.12.7=py37h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=22.3.1=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - exceptiongroup==1.2.2
      - importlib-metadata==6.7.0
      - iniconfig==2.0.0
      - markupsafe==2.1.5
      - mock==5.2.0
      - packaging==24.0
      - pluggy==1.2.0
      - pytest==7.4.4
      - pytest-localserver==0.9.0.post0
      - pyyaml==6.0.1
      - six==1.17.0
      - tomli==2.0.1
      - typing-extensions==4.7.1
      - werkzeug==2.2.3
      - wrapt==1.16.0
      - zipp==3.15.0
prefix: /opt/conda/envs/vcrpy

tests/unit/test_cassettes.py::test_path_transformer_None tests/unit/test_vcr.py::test_vcr_path_transformer
tests/unit/test_cassettes.py::test_use_as_decorator_on_coroutine tests/unit/test_cassettes.py::test_use_as_decorator_on_generator
tests/unit/test_cassettes.py::test_cassette_load tests/unit/test_cassettes.py::test_cassette_not_played tests/unit/test_cassettes.py::test_cassette_append tests/unit/test_cassettes.py::test_cassette_len tests/unit/test_cassettes.py::test_cassette_contains tests/unit/test_cassettes.py::test_cassette_responses_of tests/unit/test_cassettes.py::test_cassette_get_missing_response tests/unit/test_cassettes.py::test_cassette_cant_read_same_request_twice tests/unit/test_cassettes.py::test_function_decorated_with_use_cassette_can_be_invoked_multiple_times tests/unit/test_cassettes.py::test_arg_getter_functionality tests/unit/test_cassettes.py::test_cassette_not_all_played tests/unit/test_cassettes.py::test_cassette_all_played tests/unit/test_cassettes.py::test_before_record_response tests/unit/test_cassettes.py::test_nesting_cassette_context_managers tests/unit/test_cassettes.py::test_nesting_context_managers_by_checking_references_of_http_connection tests/unit/test_cassettes.py::test_custom_patchers tests/unit/test_cassettes.py::test_decorated_functions_are_reentrant tests/unit/test_cassettes.py::test_cassette_use_called_without_path_uses_function_to_generate_path tests/unit/test_cassettes.py::test_path_transformer_with_function_path tests/unit/test_cassettes.py::test_path_transformer_with_context_manager tests/unit/test_cassettes.py::test_func_path_generator tests/unit/test_vcr.py::test_vcr_use_cassette tests/unit/test_vcr.py::test_vcr_before_record_request_params tests/unit/test_vcr.py::test_vcr_before_record_response_iterable tests/unit/test_vcr.py::test_fixtures_with_use_cassette tests/unit/test_vcr.py::test_custom_patchers tests/unit/test_vcr.py::test_inject_cassette tests/unit/test_vcr.py::test_with_current_defaults tests/unit/test_vcr.py::test_cassette_library_dir_with_decoration_and_no_explicit_path tests/unit/test_vcr.py::test_cassette_library_dir_with_decoration_and_explicit_path tests/unit/test_vcr.py::test_cassette_library_dir_with_decoration_and_super_explicit_path tests/unit/test_vcr.py::test_cassette_library_dir_with_path_transformer tests/unit/test_vcr.py::test_use_cassette_with_no_extra_invocation tests/unit/test_vcr.py::test_path_transformer tests/unit/test_vcr.py::test_cassette_name_generator_defaults_to_using_module_function_defined_in tests/unit/test_vcr.py::test_ensure_suffix tests/unit/test_vcr.py::test_additional_matchers
README.rst vcr/cassette.py vcr/util.py vcr/config.py
README.rst vcr/cassette.py vcr/util.py vcr/config.py