From 731c8421afe3093a78cdabb9c3cc28fa52cd1c8e Mon Sep 17 00:00:00 2001
From: José Padilla
Date: Sat, 29 Nov 2014 14:43:05 -0400
Subject: Remove YAML support from core
---
 README.md                                 | 49 ++++++++++++-----------
 docs/api-guide/parsers.md                 | 24 ++++--------
 docs/api-guide/renderers.md               | 42 +++-----------------
 docs/api-guide/settings.md                |  4 +-
 docs/api-guide/testing.md                 |  4 +-
 docs/index.md                             |  2 -
 docs/tutorial/2-requests-and-responses.md |  2 +-
 requirements-test.txt                     |  1 -
 rest_framework/compat.py                  |  7 ----
 rest_framework/parsers.py                 | 25 +-----------
 rest_framework/renderers.py               | 25 +-----------
 rest_framework/settings.py                |  4 +-
 rest_framework/utils/encoders.py          | 65 +------------------------------
 tests/test_renderers.py                   | 57 ++-------------------------
 tests/test_templatetags.py                | 13 +------
 tox.ini                                   |  1 -
 16 files changed, 52 insertions(+), 273 deletions(-)
diff --git a/README.md b/README.md
index c86bb65f..aafcb29b 100644
--- a/README.md
+++ b/README.md
@@ -53,7 +53,7 @@ Add `'rest_framework'` to your `INSTALLED_APPS` setting.
 
 Let's take a look at a quick example of using REST framework to build a simple model-backed API for accessing users and groups.
 
-Startup up a new project like so... 
+Startup up a new project like so...
 
     pip install django
     pip install djangorestframework
@@ -79,7 +79,7 @@ class UserViewSet(viewsets.ModelViewSet):
     queryset = User.objects.all()
     serializer_class = UserSerializer
 
-    
+
 # Routers provide a way of automatically determining the URL conf.
 router = routers.DefaultRouter()
 router.register(r'users', UserViewSet)
@@ -100,7 +100,7 @@ Add the following to your `settings.py` module:
 ```python
 INSTALLED_APPS = (
     ...  # Make sure to include the default installed apps here.
-    'rest_framework',        
+    'rest_framework',
 )
 
 REST_FRAMEWORK = {
@@ -123,10 +123,10 @@ You can also interact with the API using command line tools such as [`curl`](htt
     $ curl -H 'Accept: application/json; indent=4' -u admin:password http://127.0.0.1:8000/users/
 	[
 	    {
-	        "url": "http://127.0.0.1:8000/users/1/", 
-	        "username": "admin", 
-	        "email": "admin@example.com", 
-	        "is_staff": true, 
+	        "url": "http://127.0.0.1:8000/users/1/",
+	        "username": "admin",
+	        "email": "admin@example.com",
+	        "is_staff": true,
 	    }
 	]
 
@@ -134,10 +134,10 @@ Or to create a new user:
 
     $ curl -X POST -d username=new -d email=new@example.com -d is_staff=false -H 'Accept: application/json; indent=4' -u admin:password http://127.0.0.1:8000/users/
     {
-        "url": "http://127.0.0.1:8000/users/2/", 
-        "username": "new", 
-        "email": "new@example.com", 
-        "is_staff": false, 
+        "url": "http://127.0.0.1:8000/users/2/",
+        "username": "new",
+        "email": "new@example.com",
+        "is_staff": false,
     }
 
 # Documentation & Support
@@ -159,24 +159,24 @@ Send a description of the issue via email to [rest-framework-security@googlegrou
 Copyright (c) 2011-2014, Tom Christie
 All rights reserved.
 
-Redistribution and use in source and binary forms, with or without 
+Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
 
-Redistributions of source code must retain the above copyright notice, this 
+Redistributions of source code must retain the above copyright notice, this
 list of conditions and the following disclaimer.
-Redistributions in binary form must reproduce the above copyright notice, this 
-list of conditions and the following disclaimer in the documentation and/or 
+Redistributions in binary form must reproduce the above copyright notice, this
+list of conditions and the following disclaimer in the documentation and/or
 other materials provided with the distribution.
 
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
@@ -214,7 +214,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 [docs]: http://www.django-rest-framework.org/
 [urlobject]: https://github.com/zacharyvoase/urlobject
 [markdown]: http://pypi.python.org/pypi/Markdown/
-[pyyaml]: http://pypi.python.org/pypi/PyYAML
 [defusedxml]: https://pypi.python.org/pypi/defusedxml
 [django-filter]: http://pypi.python.org/pypi/django-filter
 [security-mail]: mailto:rest-framework-security@googlegroups.com
diff --git a/docs/api-guide/parsers.md b/docs/api-guide/parsers.md
index 73e3a705..1e134c77 100644
--- a/docs/api-guide/parsers.md
+++ b/docs/api-guide/parsers.md
@@ -26,26 +26,26 @@ As an example, if you are sending `json` encoded data using jQuery with the [.aj
 
 ## Setting the parsers
 
-The default set of parsers may be set globally, using the `DEFAULT_PARSER_CLASSES` setting.  For example, the following settings would allow requests with `YAML` content.
+The default set of parsers may be set globally, using the `DEFAULT_PARSER_CLASSES` setting.  For example, the following settings would allow requests with `JSON` content.
 
     REST_FRAMEWORK = {
         'DEFAULT_PARSER_CLASSES': (
-            'rest_framework.parsers.YAMLParser',
+            'rest_framework.parsers.JSONParser',
         )
     }
 
 You can also set the parsers used for an individual view, or viewset,
 using the `APIView` class based views.
 
-	from rest_framework.parsers import YAMLParser
+	from rest_framework.parsers import JSONParser
 	from rest_framework.response import Response
     from rest_framework.views import APIView
 
     class ExampleView(APIView):
         """
-        A view that can accept POST requests with YAML content.
+        A view that can accept POST requests with JSON content.
         """
-        parser_classes = (YAMLParser,)
+        parser_classes = (JSONParser,)
 
         def post(self, request, format=None):
             return Response({'received data': request.data})
@@ -53,10 +53,10 @@ using the `APIView` class based views.
 Or, if you're using the `@api_view` decorator with function based views.
 
     @api_view(['POST'])
-    @parser_classes((YAMLParser,))
+    @parser_classes((JSONParser,))
     def example_view(request, format=None):
         """
-        A view that can accept POST requests with YAML content.
+        A view that can accept POST requests with JSON content.
         """
         return Response({'received data': request.data})
 
@@ -70,14 +70,6 @@ Parses `JSON` request content.
 
 **.media_type**: `application/json`
 
-## YAMLParser
-
-Parses `YAML` request content.
-
-Requires the `pyyaml` package to be installed.
-
-**.media_type**: `application/yaml`
-
 ## XMLParser
 
 Parses REST framework's default style of `XML` request content.
@@ -161,7 +153,7 @@ By default this will include the following keys: `view`, `request`, `args`, `kwa
 
 ## Example
 
-The following is an example plaintext parser that will populate the `request.data` property with a string representing the body of the request. 
+The following is an example plaintext parser that will populate the `request.data` property with a string representing the body of the request.
 
     class PlainTextParser(BaseParser):
     """
diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md
index 035ec1d2..aa8da088 100644
--- a/docs/api-guide/renderers.md
+++ b/docs/api-guide/renderers.md
@@ -18,11 +18,11 @@ For more information see the documentation on [content negotiation][conneg].
 
 ## Setting the renderers
 
-The default set of renderers may be set globally, using the `DEFAULT_RENDERER_CLASSES` setting.  For example, the following settings would use `YAML` as the main media type and also include the self describing API.
+The default set of renderers may be set globally, using the `DEFAULT_RENDERER_CLASSES` setting.  For example, the following settings would use `JSON` as the main media type and also include the self describing API.
 
     REST_FRAMEWORK = {
         'DEFAULT_RENDERER_CLASSES': (
-            'rest_framework.renderers.YAMLRenderer',
+            'rest_framework.renderers.JSONRenderer',
             'rest_framework.renderers.BrowsableAPIRenderer',
         )
     }
@@ -31,15 +31,15 @@ You can also set the renderers used for an individual view, or viewset,
 using the `APIView` class based views.
 
     from django.contrib.auth.models import User
-    from rest_framework.renderers import JSONRenderer, YAMLRenderer
+    from rest_framework.renderers import JSONRenderer
     from rest_framework.response import Response
     from rest_framework.views import APIView
 
     class UserCountView(APIView):
         """
-        A view that returns the count of active users, in JSON or YAML.
+        A view that returns the count of active users in JSON.
         """
-        renderer_classes = (JSONRenderer, YAMLRenderer)
+        renderer_classes = (JSONRenderer, )
 
         def get(self, request, format=None):
             user_count = User.objects.filter(active=True).count()
@@ -113,38 +113,6 @@ The `jsonp` approach is essentially a browser hack, and is [only appropriate for
 
 **.charset**: `utf-8`
 
-## YAMLRenderer
-
-Renders the request data into `YAML`.
-
-Requires the `pyyaml` package to be installed.
-
-Note that non-ascii characters will be rendered using `\uXXXX` character escape.  For example:
-
-    unicode black star: "\u2605"
-
-**.media_type**: `application/yaml`
-
-**.format**: `'.yaml'`
-
-**.charset**: `utf-8`
-
-## UnicodeYAMLRenderer
-
-Renders the request data into `YAML`.
-
-Requires the `pyyaml` package to be installed.
-
-Note that non-ascii characters will not be character escaped.  For example:
-
-    unicode black star: ★
-
-**.media_type**: `application/yaml`
-
-**.format**: `'.yaml'`
-
-**.charset**: `utf-8`
-
 ## XMLRenderer
 
 Renders REST framework's default style of `XML` response content.
diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md
index 9005511b..623d89fb 100644
--- a/docs/api-guide/settings.md
+++ b/docs/api-guide/settings.md
@@ -12,10 +12,10 @@ For example your project's `settings.py` file might include something like this:
 
     REST_FRAMEWORK = {
         'DEFAULT_RENDERER_CLASSES': (
-            'rest_framework.renderers.YAMLRenderer',
+            'rest_framework.renderers.JSONRenderer',
         ),
         'DEFAULT_PARSER_CLASSES': (
-            'rest_framework.parsers.YAMLParser',
+            'rest_framework.parsers.JSONParser',
         )
     }
 
diff --git a/docs/api-guide/testing.md b/docs/api-guide/testing.md
index d059fdab..cd8c7820 100644
--- a/docs/api-guide/testing.md
+++ b/docs/api-guide/testing.md
@@ -255,14 +255,14 @@ The default format used to make test requests may be set using the `TEST_REQUEST
 
 If you need to test requests using something other than multipart or json requests, you can do so by setting the `TEST_REQUEST_RENDERER_CLASSES` setting.
 
-For example, to add support for using `format='yaml'` in test requests, you might have something like this in your `settings.py` file.
+For example, to add support for using `format='html'` in test requests, you might have something like this in your `settings.py` file.
 
     REST_FRAMEWORK = {
         ...
         'TEST_REQUEST_RENDERER_CLASSES': (
             'rest_framework.renderers.MultiPartRenderer',
             'rest_framework.renderers.JSONRenderer',
-            'rest_framework.renderers.YAMLRenderer'
+            'rest_framework.renderers.TemplateHTMLRenderer'
         )
     }
 
diff --git a/docs/index.md b/docs/index.md
index b5257c73..c2836dbb 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -54,7 +54,6 @@ REST framework requires the following:
 The following packages are optional:
 
 * [Markdown][markdown] (2.1.0+) - Markdown support for the browsable API.
-* [PyYAML][yaml] (3.10+) - YAML content-type support.
 * [defusedxml][defusedxml] (0.3+) - XML content-type support.
 * [django-filter][django-filter] (0.5.4+) - Filtering support.
 * [django-oauth-plus][django-oauth-plus] (2.0+) and [oauth2][oauth2] (1.5.211+) - OAuth 1.0a support.
@@ -258,7 +257,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 [mozilla]: http://www.mozilla.org/en-US/about/
 [eventbrite]: https://www.eventbrite.co.uk/about/
 [markdown]: http://pypi.python.org/pypi/Markdown/
-[yaml]: http://pypi.python.org/pypi/PyYAML
 [defusedxml]: https://pypi.python.org/pypi/defusedxml
 [django-filter]: http://pypi.python.org/pypi/django-filter
 [oauth2]: https://github.com/simplegeo/python-oauth2
diff --git a/docs/tutorial/2-requests-and-responses.md b/docs/tutorial/2-requests-and-responses.md
index f377c712..06a684b1 100644
--- a/docs/tutorial/2-requests-and-responses.md
+++ b/docs/tutorial/2-requests-and-responses.md
@@ -92,7 +92,7 @@ Here is the view for an individual snippet, in the `views.py` module.
 
 This should all feel very familiar - it is not a lot different from working with regular Django views.
 
-Notice that we're no longer explicitly tying our requests or responses to a given content type.  `request.data` can handle incoming `json` requests, but it can also handle `yaml` and other formats.  Similarly we're returning response objects with data, but allowing REST framework to render the response into the correct content type for us.
+Notice that we're no longer explicitly tying our requests or responses to a given content type.  `request.data` can handle incoming `json` requests, but it can also handle other formats.  Similarly we're returning response objects with data, but allowing REST framework to render the response into the correct content type for us.
 
 ## Adding optional format suffixes to our URLs
 
diff --git a/requirements-test.txt b/requirements-test.txt
index 06c8849a..bd09211e 100644
--- a/requirements-test.txt
+++ b/requirements-test.txt
@@ -6,7 +6,6 @@ flake8==2.2.2
 
 # Optional packages
 markdown>=2.1.0
-PyYAML>=3.10
 defusedxml>=0.3
 django-guardian==1.2.4
 django-filter>=0.5.4
diff --git a/rest_framework/compat.py b/rest_framework/compat.py
index 5bd85e74..52db9625 100644
--- a/rest_framework/compat.py
+++ b/rest_framework/compat.py
@@ -237,13 +237,6 @@ except ImportError:
     apply_markdown = None
 
 
-# Yaml is optional
-try:
-    import yaml
-except ImportError:
-    yaml = None
-
-
 # XML is optional
 try:
     import defusedxml.ElementTree as etree
diff --git a/rest_framework/parsers.py b/rest_framework/parsers.py
index ccb82f03..e6bb75f6 100644
--- a/rest_framework/parsers.py
+++ b/rest_framework/parsers.py
@@ -12,7 +12,7 @@ from django.http import QueryDict
 from django.http.multipartparser import MultiPartParser as DjangoMultiPartParser
 from django.http.multipartparser import MultiPartParserError, parse_header, ChunkIter
 from django.utils import six
-from rest_framework.compat import etree, yaml, force_text, urlparse
+from rest_framework.compat import etree, force_text, urlparse
 from rest_framework.exceptions import ParseError
 from rest_framework import renderers
 import json
@@ -65,29 +65,6 @@ class JSONParser(BaseParser):
             raise ParseError('JSON parse error - %s' % six.text_type(exc))
 
 
-class YAMLParser(BaseParser):
-    """
-    Parses YAML-serialized data.
-    """
-
-    media_type = 'application/yaml'
-
-    def parse(self, stream, media_type=None, parser_context=None):
-        """
-        Parses the incoming bytestream as YAML and returns the resulting data.
-        """
-        assert yaml, 'YAMLParser requires pyyaml to be installed'
-
-        parser_context = parser_context or {}
-        encoding = parser_context.get('encoding', settings.DEFAULT_CHARSET)
-
-        try:
-            data = stream.read().decode(encoding)
-            return yaml.safe_load(data)
-        except (ValueError, yaml.parser.ParserError) as exc:
-            raise ParseError('YAML parse error - %s' % six.text_type(exc))
-
-
 class FormParser(BaseParser):
     """
     Parser for form data.
diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py
index e87d16d0..a6e4f1bb 100644
--- a/rest_framework/renderers.py
+++ b/rest_framework/renderers.py
@@ -19,7 +19,7 @@ from django.utils import six
 from django.utils.xmlutils import SimplerXMLGenerator
 from rest_framework import exceptions, serializers, status, VERSION
 from rest_framework.compat import (
-    SHORT_SEPARATORS, LONG_SEPARATORS, StringIO, smart_text, yaml
+    SHORT_SEPARATORS, LONG_SEPARATORS, StringIO, smart_text
 )
 from rest_framework.exceptions import ParseError
 from rest_framework.settings import api_settings
@@ -189,29 +189,6 @@ class XMLRenderer(BaseRenderer):
             xml.characters(smart_text(data))
 
 
-class YAMLRenderer(BaseRenderer):
-    """
-    Renderer which serializes to YAML.
-    """
-
-    media_type = 'application/yaml'
-    format = 'yaml'
-    encoder = encoders.SafeDumper
-    charset = 'utf-8'
-    ensure_ascii = False
-
-    def render(self, data, accepted_media_type=None, renderer_context=None):
-        """
-        Renders `data` into serialized YAML.
-        """
-        assert yaml, 'YAMLRenderer requires pyyaml to be installed'
-
-        if data is None:
-            return ''
-
-        return yaml.dump(data, stream=None, encoding=self.charset, Dumper=self.encoder, allow_unicode=not self.ensure_ascii)
-
-
 class TemplateHTMLRenderer(BaseRenderer):
     """
     An HTML renderer for use with templates.
diff --git a/rest_framework/settings.py b/rest_framework/settings.py
index 1e8c27fc..3abc1fe8 100644
--- a/rest_framework/settings.py
+++ b/rest_framework/settings.py
@@ -5,11 +5,11 @@ For example your project's `settings.py` file might look like this:
 REST_FRAMEWORK = {
     'DEFAULT_RENDERER_CLASSES': (
         'rest_framework.renderers.JSONRenderer',
-        'rest_framework.renderers.YAMLRenderer',
+        'rest_framework.renderers.TemplateHTMLRenderer',
     )
     'DEFAULT_PARSER_CLASSES': (
         'rest_framework.parsers.JSONParser',
-        'rest_framework.parsers.YAMLParser',
+        'rest_framework.parsers.TemplateHTMLRenderer',
     )
 }
 
diff --git a/rest_framework/utils/encoders.py b/rest_framework/utils/encoders.py
index 4d6bb3a3..2c97f1d7 100644
--- a/rest_framework/utils/encoders.py
+++ b/rest_framework/utils/encoders.py
@@ -5,10 +5,9 @@ from __future__ import unicode_literals
 from django.db.models.query import QuerySet
 from django.utils import six, timezone
 from django.utils.functional import Promise
-from rest_framework.compat import force_text, OrderedDict
+from rest_framework.compat import force_text
 import datetime
 import decimal
-import types
 import json
 
 
@@ -56,65 +55,3 @@ class JSONEncoder(json.JSONEncoder):
         elif hasattr(obj, '__iter__'):
             return tuple(item for item in obj)
         return super(JSONEncoder, self).default(obj)
-
-
-try:
-    import yaml
-except ImportError:
-    SafeDumper = None
-else:
-    # Adapted from http://pyyaml.org/attachment/ticket/161/use_ordered_dict.py
-    class SafeDumper(yaml.SafeDumper):
-        """
-        Handles decimals as strings.
-        Handles OrderedDicts as usual dicts, but preserves field order, rather
-        than the usual behaviour of sorting the keys.
-        """
-        def represent_decimal(self, data):
-            return self.represent_scalar('tag:yaml.org,2002:str', six.text_type(data))
-
-        def represent_mapping(self, tag, mapping, flow_style=None):
-            value = []
-            node = yaml.MappingNode(tag, value, flow_style=flow_style)
-            if self.alias_key is not None:
-                self.represented_objects[self.alias_key] = node
-            best_style = True
-            if hasattr(mapping, 'items'):
-                mapping = list(mapping.items())
-                if not isinstance(mapping, OrderedDict):
-                    mapping.sort()
-            for item_key, item_value in mapping:
-                node_key = self.represent_data(item_key)
-                node_value = self.represent_data(item_value)
-                if not (isinstance(node_key, yaml.ScalarNode) and not node_key.style):
-                    best_style = False
-                if not (isinstance(node_value, yaml.ScalarNode) and not node_value.style):
-                    best_style = False
-                value.append((node_key, node_value))
-            if flow_style is None:
-                if self.default_flow_style is not None:
-                    node.flow_style = self.default_flow_style
-                else:
-                    node.flow_style = best_style
-            return node
-
-    SafeDumper.add_representer(
-        decimal.Decimal,
-        SafeDumper.represent_decimal
-    )
-    SafeDumper.add_representer(
-        OrderedDict,
-        yaml.representer.SafeRepresenter.represent_dict
-    )
-    # SafeDumper.add_representer(
-    #     DictWithMetadata,
-    #     yaml.representer.SafeRepresenter.represent_dict
-    # )
-    # SafeDumper.add_representer(
-    #     OrderedDictWithMetadata,
-    #     yaml.representer.SafeRepresenter.represent_dict
-    # )
-    SafeDumper.add_representer(
-        types.GeneratorType,
-        yaml.representer.SafeRepresenter.represent_list
-    )
diff --git a/tests/test_renderers.py b/tests/test_renderers.py
index 416d7f22..0603f800 100644
--- a/tests/test_renderers.py
+++ b/tests/test_renderers.py
@@ -9,12 +9,12 @@ from django.test import TestCase
 from django.utils import six, unittest
 from django.utils.translation import ugettext_lazy as _
 from rest_framework import status, permissions
-from rest_framework.compat import yaml, etree, StringIO, BytesIO
+from rest_framework.compat import etree, StringIO
 from rest_framework.response import Response
 from rest_framework.views import APIView
-from rest_framework.renderers import BaseRenderer, JSONRenderer, YAMLRenderer, \
-    XMLRenderer, JSONPRenderer, BrowsableAPIRenderer
-from rest_framework.parsers import YAMLParser, XMLParser
+from rest_framework.renderers import BaseRenderer, JSONRenderer, XMLRenderer, \
+    JSONPRenderer, BrowsableAPIRenderer
+from rest_framework.parsers import XMLParser
 from rest_framework.settings import api_settings
 from rest_framework.test import APIRequestFactory
 from collections import MutableMapping
@@ -452,55 +452,6 @@ class JSONPRendererTests(TestCase):
         )
 
 
-if yaml:
-    _yaml_repr = 'foo: [bar, baz]\n'
-
-    class YAMLRendererTests(TestCase):
-        """
-        Tests specific to the YAML Renderer
-        """
-
-        def test_render(self):
-            """
-            Test basic YAML rendering.
-            """
-            obj = {'foo': ['bar', 'baz']}
-            renderer = YAMLRenderer()
-            content = renderer.render(obj, 'application/yaml')
-            self.assertEqual(content.decode('utf-8'), _yaml_repr)
-
-        def test_render_and_parse(self):
-            """
-            Test rendering and then parsing returns the original object.
-            IE obj -> render -> parse -> obj.
-            """
-            obj = {'foo': ['bar', 'baz']}
-
-            renderer = YAMLRenderer()
-            parser = YAMLParser()
-
-            content = renderer.render(obj, 'application/yaml')
-            data = parser.parse(BytesIO(content))
-            self.assertEqual(obj, data)
-
-        def test_render_decimal(self):
-            """
-            Test YAML decimal rendering.
-            """
-            renderer = YAMLRenderer()
-            content = renderer.render({'field': Decimal('111.2')}, 'application/yaml')
-            self.assertYAMLContains(content.decode('utf-8'), "field: '111.2'")
-
-        def assertYAMLContains(self, content, string):
-            self.assertTrue(string in content, '%r not in %r' % (string, content))
-
-        def test_proper_encoding(self):
-            obj = {'countries': ['United Kingdom', 'France', 'España']}
-            renderer = YAMLRenderer()
-            content = renderer.render(obj, 'application/yaml')
-            self.assertEqual(content.strip(), 'countries: [United Kingdom, France, España]'.encode('utf-8'))
-
-
 class XMLRendererTestCase(TestCase):
     """
     Tests specific to the XML Renderer
diff --git a/tests/test_templatetags.py b/tests/test_templatetags.py
index b04a937e..0cee91f1 100644
--- a/tests/test_templatetags.py
+++ b/tests/test_templatetags.py
@@ -54,7 +54,7 @@ class Issue1386Tests(TestCase):
 
 class URLizerTests(TestCase):
     """
-    Test if both JSON and YAML URLs are transformed into links well
+    Test if JSON URLs are transformed into links well
     """
     def _urlize_dict_check(self, data):
         """
@@ -73,14 +73,3 @@ class URLizerTests(TestCase):
         data['"foo_set": [\n    "http://api/foos/1/"\n], '] = \
             '"foo_set": [\n    "http://api/foos/1/"\n], '
         self._urlize_dict_check(data)
-
-    def test_yaml_with_url(self):
-        """
-        Test if YAML URLs are transformed into links well
-        """
-        data = {}
-        data['''{users: 'http://api/users/'}'''] = \
-            '''{users: 'http://api/users/'}'''
-        data['''foo_set: ['http://api/foos/1/']'''] = \
-            '''foo_set: ['http://api/foos/1/']'''
-        self._urlize_dict_check(data)
diff --git a/tox.ini b/tox.ini
index d5cb9ef9..edfeb33d 100644
--- a/tox.ini
+++ b/tox.ini
@@ -24,7 +24,6 @@ deps =
        django-filter==0.7
        defusedxml==0.3
        markdown>=2.1.0
-       PyYAML>=3.10
 
 [testenv:py27-flake8]
 deps =
-- 
cgit v1.2.3