From c72392dab4b4cf6f5d9b35a3dcb582fbfe38ebb8 Mon Sep 17 00:00:00 2001 From: Roberto Aguilar Date: Fri, 6 Sep 2013 15:56:06 +0000 Subject: [PATCH] Added yaml directly into BUILTIN_SERIALIZERS. The serializer definitely exists, but the dependent yaml module may not be installed. The register_serializer() function will catch exceptions and will stub in a fake serializer object that will raise the exception when the serializer is used. --- django/core/serializers/__init__.py | 40 +++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/django/core/serializers/__init__.py b/django/core/serializers/__init__.py index dc3d139d3b..4c9b5ba37a 100644 --- a/django/core/serializers/__init__.py +++ b/django/core/serializers/__init__.py @@ -17,6 +17,7 @@ To add your own serializers, use the SERIALIZATION_MODULES setting:: """ import importlib +import sys from django.conf import settings from django.utils import six @@ -27,17 +28,29 @@ BUILTIN_SERIALIZERS = { "xml" : "django.core.serializers.xml_serializer", "python" : "django.core.serializers.python", "json" : "django.core.serializers.json", + "yaml" : "django.core.serializers.pyyaml", } -# Check for PyYaml and register the serializer if it's available. -try: - import yaml - BUILTIN_SERIALIZERS["yaml"] = "django.core.serializers.pyyaml" -except ImportError: - pass - _serializers = {} + +class BadSerializer(object): + """ + Stub serializer to hold exception raised during registration + + This allows the serializer registration to cache serializers and if there + is an error raised in the process of creating a serializer it will be + raised and passed along to the caller when the serializer is used. + """ + internal_use_only = False + + def __init__(self, exception): + self.exception = exception + + def __call__(self, *args, **kwargs): + raise self.exception + + def register_serializer(format, serializer_module, serializers=None): """Register a new serializer. @@ -53,12 +66,23 @@ def register_serializer(format, serializer_module, serializers=None): """ if serializers is None and not _serializers: _load_serializers() - module = importlib.import_module(serializer_module) + + try: + module = importlib.import_module(serializer_module) + except ImportError, exc: + bad_serializer = BadSerializer(exc) + + module = type('BadSerializerModule', (object,), { + 'Deserializer': bad_serializer, + 'Serializer': bad_serializer, + }) + if serializers is None: _serializers[format] = module else: serializers[format] = module + def unregister_serializer(format): "Unregister a given serializer. This is not a thread-safe operation." if not _serializers: