From e33eeeb871e4a93c16afe76095a0c198d8365e4b Mon Sep 17 00:00:00 2001 From: Dmitry Kozhedubov Date: Sun, 2 Mar 2014 13:30:27 +0400 Subject: [PATCH] Ability to pass keyword args to CastingMixin casters --- configurations/values.py | 14 +++++++++++++- tests/test_values.py | 15 +++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/configurations/values.py b/configurations/values.py index 1e51bdb..771843f 100644 --- a/configurations/values.py +++ b/configurations/values.py @@ -3,6 +3,7 @@ import copy import decimal import os import sys +import inspect from django.core import validators from django.core.exceptions import ValidationError, ImproperlyConfigured @@ -95,6 +96,7 @@ class BooleanValue(Value): class CastingMixin(object): exception = (TypeError, ValueError) message = 'Cannot interpret value {0!r}' + kwargs = {} def __init__(self, *args, **kwargs): super(CastingMixin, self).__init__(*args, **kwargs) @@ -106,10 +108,20 @@ class CastingMixin(object): error = 'Cannot use caster of {0} ({1!r})'.format(self, self.caster) raise ValueError(error) + self.process_kwargs(kwargs) + + def process_kwargs(self, kwargs): + if kwargs: + arg_names = inspect.getargspec(self._caster)[0] + self.kwargs = dict((name, kwargs[name]) for name in arg_names \ + if name in kwargs) def to_python(self, value): try: - return self._caster(value) + if self.kwargs: + return self._caster(value, **self.kwargs) + else: + return self._caster(value) except self.exception: raise ValueError(self.message.format(value)) diff --git a/tests/test_values.py b/tests/test_values.py index 191595b..de4482c 100644 --- a/tests/test_values.py +++ b/tests/test_values.py @@ -253,6 +253,21 @@ class ValueTests(TestCase): 'USER': None, }}) + def test_database_url_additional_args(self): + + def mock_database_url_caster(self, url, engine=None): + return { 'URL': url, 'ENGINE': engine } + + with patch('configurations.values.DatabaseURLValue.caster', mock_database_url_caster): + value = DatabaseURLValue(engine='django_mysqlpool.backends.mysqlpool') + with env(DATABASE_URL='sqlite://'): + self.assertEqual(value.setup('DATABASE_URL'), { + 'default': { + 'URL': 'sqlite://', + 'ENGINE': 'django_mysqlpool.backends.mysqlpool' + } + }) + def test_email_url_value(self): value = EmailURLValue() self.assertEqual(value.default, {})