django-compressor / django-appconf

An app to handle configuration defaults of packaged Django apps gracefully
https://django-appconf.readthedocs.io
BSD 3-Clause "New" or "Revised" License
350 stars 47 forks source link

Improve AppConf.__dir__ #51

Closed orlnub123 closed 3 years ago

orlnub123 commented 4 years ago

The custom __dir__ leaves out some useful attributes. These include values passed to AppConf, attributes of the holder if AppConf is a proxy, the configure_* and configure methods, and configured_data.

Here's an example that showcases the above:

from types import SimpleNamespace
from appconf import AppConf

holder = SimpleNamespace(DEFAULT_TEST=1)

class TestConf(AppConf):
    TEST1 = 'test'

    def configure_test1(self, value):
        return 1

    def configure(self):
        test1 = self.configured_data['TEST1']
        default = self.DEFAULT_TEST
        self.configured_data['TEST2'] = test1 + default
        return self.configured_data

    class Meta:
        prefix = 'prefix'
        holder = '__main__.holder'
        proxy = True

conf = TestConf(TEST3=3)
print(dir(conf))

Ideally this would print ['DEFAULT_TEST', 'Meta', 'PREFIX_TEST1', 'PREFIX_TEST2', 'PREFIX_TEST3', 'TEST1', 'TEST2', 'TEST3', '_meta', 'configure', 'configure_test1', 'configured_data'], however it currently only prints ['TEST1'].

This PR takes the easy route and uses the default __dir__, supplementing it with the holder's __dir__ if the object is a proxy. Unfortunately that means some dunder methods show up. However, that makes it more similar to the __dir__ of Django's settings (and models?).

orlnub123 commented 4 years ago

It's quite surprising that the default __dir__ implementation in Python 2 lives in dir instead of in object. I'll have to rethink this...

orlnub123 commented 4 years ago

This new version should be functionally identical to the previous on Python 3.

orlnub123 commented 4 years ago

I don't think it'd be a good idea to completely change the output of dir in a patch release so I've made a new 1.1.0 section in the changelog. I can move it to 1.0.4 if you think otherwise.