mirror of
https://github.com/jazzband/django-configurations.git
synced 2026-03-16 22:20:27 +00:00
Merge remote-tracking branch 'hiisi13/master'
Signed-off-by: Jannis Leidel <jannis@leidel.info>
This commit is contained in:
commit
44476bdd1d
3 changed files with 101 additions and 2 deletions
|
|
@ -1,3 +1,4 @@
|
|||
import inspect
|
||||
import sys
|
||||
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
|
|
@ -122,3 +123,76 @@ except ImportError:
|
|||
raise Exception
|
||||
except: # Needed because we might need to catch a SystemExit
|
||||
largs.append(arg)
|
||||
|
||||
|
||||
# Copied over from Sphinx
|
||||
if sys.version_info >= (3, 0):
|
||||
from functools import partial
|
||||
|
||||
def getargspec(func):
|
||||
"""Like inspect.getargspec but supports functools.partial as well."""
|
||||
if inspect.ismethod(func):
|
||||
func = func.__func__
|
||||
if type(func) is partial:
|
||||
orig_func = func.func
|
||||
argspec = getargspec(orig_func)
|
||||
args = list(argspec[0])
|
||||
defaults = list(argspec[3] or ())
|
||||
kwoargs = list(argspec[4])
|
||||
kwodefs = dict(argspec[5] or {})
|
||||
if func.args:
|
||||
args = args[len(func.args):]
|
||||
for arg in func.keywords or ():
|
||||
try:
|
||||
i = args.index(arg) - len(args)
|
||||
del args[i]
|
||||
try:
|
||||
del defaults[i]
|
||||
except IndexError:
|
||||
pass
|
||||
except ValueError: # must be a kwonly arg
|
||||
i = kwoargs.index(arg)
|
||||
del kwoargs[i]
|
||||
del kwodefs[arg]
|
||||
return inspect.FullArgSpec(args, argspec[1], argspec[2],
|
||||
tuple(defaults), kwoargs,
|
||||
kwodefs, argspec[6])
|
||||
while hasattr(func, '__wrapped__'):
|
||||
func = func.__wrapped__
|
||||
if not inspect.isfunction(func):
|
||||
raise TypeError('%r is not a Python function' % func)
|
||||
return inspect.getfullargspec(func)
|
||||
|
||||
else: # 2.6, 2.7
|
||||
from functools import partial
|
||||
|
||||
def getargspec(func):
|
||||
"""Like inspect.getargspec but supports functools.partial as well."""
|
||||
if inspect.ismethod(func):
|
||||
func = func.im_func
|
||||
parts = 0, ()
|
||||
if type(func) is partial:
|
||||
keywords = func.keywords
|
||||
if keywords is None:
|
||||
keywords = {}
|
||||
parts = len(func.args), keywords.keys()
|
||||
func = func.func
|
||||
if not inspect.isfunction(func):
|
||||
raise TypeError('%r is not a Python function' % func)
|
||||
args, varargs, varkw = inspect.getargs(func.func_code)
|
||||
func_defaults = func.func_defaults
|
||||
if func_defaults is None:
|
||||
func_defaults = []
|
||||
else:
|
||||
func_defaults = list(func_defaults)
|
||||
if parts[0]:
|
||||
args = args[parts[0]:]
|
||||
if parts[1]:
|
||||
for arg in parts[1]:
|
||||
i = args.index(arg) - len(args)
|
||||
del args[i]
|
||||
try:
|
||||
del func_defaults[i]
|
||||
except IndexError:
|
||||
pass
|
||||
return inspect.ArgSpec(args, varargs, varkw, func_defaults)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from django.core import validators
|
|||
from django.core.exceptions import ValidationError, ImproperlyConfigured
|
||||
from django.utils import six
|
||||
|
||||
from .utils import import_by_path
|
||||
from .utils import import_by_path, getargspec
|
||||
|
||||
|
||||
def setup_value(target, name, value):
|
||||
|
|
@ -140,10 +140,20 @@ class CastingMixin(object):
|
|||
error = 'Cannot use caster of {0} ({1!r})'.format(self,
|
||||
self.caster)
|
||||
raise ValueError(error)
|
||||
try:
|
||||
arg_names = getargspec(self._caster)[0]
|
||||
self._params = dict((name, kwargs[name])
|
||||
for name in arg_names
|
||||
if name in kwargs)
|
||||
except TypeError:
|
||||
self._params = {}
|
||||
|
||||
def to_python(self, value):
|
||||
try:
|
||||
return self._caster(value)
|
||||
if self._params:
|
||||
return self._caster(value, **self._params)
|
||||
else:
|
||||
return self._caster(value)
|
||||
except self.exception:
|
||||
raise ValueError(self.message.format(value))
|
||||
|
||||
|
|
|
|||
|
|
@ -295,6 +295,21 @@ class ValueTests(TestCase):
|
|||
'USER': '',
|
||||
}})
|
||||
|
||||
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, {})
|
||||
|
|
|
|||
Loading…
Reference in a new issue