/usr/lib/python3/dist-packages/appconf/base.py is in python3-django-appconf 1.0.1-4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | import sys
import six
from django.core.exceptions import ImproperlyConfigured
from .utils import import_attribute
class AppConfOptions(object):
def __init__(self, meta, prefix=None):
self.prefix = prefix
self.holder_path = getattr(meta, 'holder', 'django.conf.settings')
self.holder = import_attribute(self.holder_path)
self.proxy = getattr(meta, 'proxy', False)
self.required = getattr(meta, 'required', [])
self.configured_data = {}
def prefixed_name(self, name):
if name.startswith(self.prefix.upper()):
return name
return "%s_%s" % (self.prefix.upper(), name.upper())
def contribute_to_class(self, cls, name):
cls._meta = self
self.names = {}
self.defaults = {}
class AppConfMetaClass(type):
def __new__(cls, name, bases, attrs):
super_new = super(AppConfMetaClass, cls).__new__
parents = [b for b in bases if isinstance(b, AppConfMetaClass)]
if not parents:
return super_new(cls, name, bases, attrs)
# Create the class.
module = attrs.pop('__module__')
new_class = super_new(cls, name, bases, {'__module__': module})
attr_meta = attrs.pop('Meta', None)
if attr_meta:
meta = attr_meta
else:
attr_meta = type('Meta', (object,), {})
meta = getattr(new_class, 'Meta', None)
prefix = getattr(meta, 'prefix', getattr(meta, 'app_label', None))
if prefix is None:
# Figure out the prefix by looking one level up.
# For 'django.contrib.sites.models', this would be 'sites'.
model_module = sys.modules[new_class.__module__]
prefix = model_module.__name__.split('.')[-2]
new_class.add_to_class('_meta', AppConfOptions(meta, prefix))
new_class.add_to_class('Meta', attr_meta)
for parent in parents[::-1]:
if hasattr(parent, '_meta'):
new_class._meta.names.update(parent._meta.names)
new_class._meta.defaults.update(parent._meta.defaults)
new_class._meta.configured_data.update(
parent._meta.configured_data)
for name in filter(str.isupper, list(attrs.keys())):
prefixed_name = new_class._meta.prefixed_name(name)
new_class._meta.names[name] = prefixed_name
new_class._meta.defaults[prefixed_name] = attrs.pop(name)
# Add all attributes to the class.
for name, value in attrs.items():
new_class.add_to_class(name, value)
new_class._configure()
for name, value in six.iteritems(new_class._meta.configured_data):
prefixed_name = new_class._meta.prefixed_name(name)
setattr(new_class._meta.holder, prefixed_name, value)
new_class.add_to_class(name, value)
# Confirm presence of required settings.
for name in new_class._meta.required:
prefixed_name = new_class._meta.prefixed_name(name)
if not hasattr(new_class._meta.holder, prefixed_name):
raise ImproperlyConfigured('The required setting %s is'
' missing.' % prefixed_name)
return new_class
def add_to_class(cls, name, value):
if hasattr(value, 'contribute_to_class'):
value.contribute_to_class(cls, name)
else:
setattr(cls, name, value)
def _configure(cls):
# the ad-hoc settings class instance used to configure each value
obj = cls()
for name, prefixed_name in six.iteritems(obj._meta.names):
default_value = obj._meta.defaults.get(prefixed_name)
value = getattr(obj._meta.holder, prefixed_name, default_value)
callback = getattr(obj, "configure_%s" % name.lower(), None)
if callable(callback):
value = callback(value)
cls._meta.configured_data[name] = value
cls._meta.configured_data = obj.configure()
class AppConf(six.with_metaclass(AppConfMetaClass)):
"""
An app setting object to be used for handling app setting defaults
gracefully and providing a nice API for them.
"""
def __init__(self, **kwargs):
for name, value in six.iteritems(kwargs):
setattr(self, name, value)
def __dir__(self):
return sorted(list(set(self._meta.names.keys())))
# For instance access..
@property
def configured_data(self):
return self._meta.configured_data
# For Python < 2.6:
@property
def __members__(self):
return self.__dir__()
def __getattr__(self, name):
if self._meta.proxy:
return getattr(self._meta.holder, name)
raise AttributeError("%s not found. Use '%s' instead." %
(name, self._meta.holder_path))
def __setattr__(self, name, value):
if name == name.upper():
setattr(self._meta.holder,
self._meta.prefixed_name(name), value)
object.__setattr__(self, name, value)
def configure(self):
"""
Hook for doing any extra configuration, returning a dictionary
containing the configured data.
"""
return self.configured_data
|