Hi folks,

Let me make a stab at the 1000ft view for this.

TLDR: Django modules should work as libraries (e.g. ORM, mail, etc).  "from 
django.conf import settings" bootstrap undermines this.  unsetting begins a 
path to support the legacy structure, but still allows for the 
'librarification' of Django modules.  Then, we can move on with more 
options to whether we want to refactor things or not and how.

For the TLDR code entry point check out:
https://github.com/SlashRoot/django/blob/33c49245032115cf3fd6534d5a55313435419ffb/django/utils/unsetting.py#L37

On to the 'too long' version:
This work started at the Chicago DjangoCon sprint this past September. 
 Justin Holmes and I were talking to Adrian (and then roped in Jacob). 
 After discussing the problem and working out a possible way to move 
forward, it seemed like they both liked the idea.  Even more promising, 
during the sprint, Justin and I found that it was *working* as we started 
attacking different sections.

So, what is unsetting?  Basically, we see it as a problem that a large 
amount of Django code is not structured in 'library' form.  In order for 
most django libraries to be imported, settings need to be bootstrapped.

Jacob's use-case was "I'd like to import django.core.mail and use it even 
if I'm not running Django"

My use-case is Django's awesome (yes, I know opinions differ), 
simple-to-use ORM.

Stipulating that Django should work as a library without bootstrapping with 
settings, how do we get there?  We have some different options:
1. Refactor all the libraries to be more functional, and somehow pass 
settings through either the request object or other 'world-state' passing
2. A different refactor project that would move around all the code, so all 
the 'good' code is functional, and then all the public interfaces get the 
settings and call the 'good' code functionally.  Outside importers would 
then import the 'good' modules directly.
3. Unsetting: decorate all the methods/classes that use setting so they map 
to newly functional arguments.  If setting is there, and the functional 
arguments aren't sent in, then the setting bootstrap isn't necessary.

Attacking #1 and #2.  First, #1 would be controversial at every step, and 
for every module.  However world-state was passed around, it would be very 
difficult to make it backwards compatible.  #2 would mostly result in a 
documentation issue -- where to import from would be different for 
non-django importers than those in django.  This is not even to mention the 
settings references in several __init__.py files.

The general idea with #3 is trying to separate out the setting dependency 
*first*, and then opportunistically over time, we can start looking for 
opportunities to pass settings in a more functional way through our call 
chain.

django.utils.unsetting has the following example of how to migrate older 
code with some 'magical' decorators:


    The typical use case is a an old function/method looks like:
        def foobar(a, b, c=None):
            if getattr(settings, 'FOO_ENABLE_C', False):
                do_something(c)
            ...
    This decorator makes it easy to remove the need for a django settings 
import.
    You would modify this function above to something like:
        @uses_settings('FOO_ENABLE_C', 'enable_c')
        def foobar(a, b, c=None, enable_c=False):
            if enable_c:
                do_something(c)
            ...


For the first trial at this approach, we tried out utils.timezone:
https://github.com/SlashRoot/django/blob/33c49245032115cf3fd6534d5a55313435419ffb/django/utils/timezone.py#L302

and it seemed to have worked, so we moved on to django.core.mail, and other 
modules.

Actually, I, myself, have mostly been sitting on my butt the last few 
months.  However Justin and James have been working through other modules 
proving that this pretty light approach can work with no backwards 
incompatibility.

So, what do y'all think?  And let us know if we can answer any other 
questions about the approach.

cheers,
sky

On Tuesday, February 11, 2014 2:53:21 AM UTC-5, Florian Apolloner wrote:
>
>
>
> On Tuesday, February 11, 2014 8:33:09 AM UTC+1, Aymeric Augustin wrote:
>>
>> On 11 févr. 2014, at 03:27, James Farrington <jamestfa...@gmail.com> 
>> wrote:
>>
>> If you haven't heard about unsettings, it is an attempt to move away from 
>> using the settings global. There was a discussion at djangocon (which I 
>> wasn't there for, but I was told about it) which led to some of my 
>> colleagues and I working on it.
>>
>>
>> There was only a handful of people involved in that discussion. I 
>> overheard it and asked for details but couldn’t get an explanation of the 
>> design. I assume that 99,9% of the subscribers to this mailing-list are 
>> hearing the codename “unsettings” for the first time and 99,99% including 
>> most of the committers have no idea what it means.
>>
>
> ++, for me the current patch is nice to see, but such a feature needs 
> discussion on the mailing list __first__. So the next (first) step would 
> be: Explain (in __detail__) what you are after and how you want to achieve 
> this goal -- "it has been discussed at DjangoCon" doesn't count (hell, we 
> even switched to Jinja there ;))
>
> Cheers,
> Florian
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/f07e4039-168f-4809-abd9-5c46883f7fd0%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to