Auto registering class registry
Why

for module in [name for _, name, _ in pkgutil.iter_modules([package_dir])]:


and not

for _, module, _ in pkgutil.iter_modules([package_dir]):


? If it's about iterating eagerly, using list would work better than a list comprehension.

_ = __import__(module)


is also weird; why not just __import__(module)?

It makes sense for AutoRegClassRegistry to be an ABC, but by no means is this a requirement. It's worth noting that

def register(self):
    raise NotImplementedError("You must inherit from this class and override the register func")


has the wrong number of arguments, so will give an unhelpful error instead.

Don't use name mangling for self.__choices = [] unless there's good reason; _choices works just as well.

cls_short = getattr(cls, "SHORT", None)
if not cls_short:
    raise AttributeError("CLS {} doesn't have attribute 'SHORT' which is required to register to ClientStats")


seems like it breaks EAFTP;

cls_short = cls.SHORT


would work just as well and

try:
    cls_short = cls.SHORT
except AttributeError:
    raise AttributeError("CLS {} doesn't have attribute 'SHORT' which is required to register to ClientStats")


would be more descriptive of intent. The same happens immediately after.

The whole

if hasattr(self, cls_short):
    raise AttributeError("ClientStats already has a {} registered".format(cls_short))
setattr(self, cls_short, cls_short)
setattr(self, "{}_DESC".format(cls_short), cls_desc)
setattr(self, "{}_CLS".format(cls_short), cls)


looks really backwards, though; why not just put this in a simple data structure? Why does it have to be through messy attribute accesses.



This whole thing feels really dynamic, and dynamism should be a last resort. But I've never touched Django, so I can't really say whether what you're doing is justified or not.

As I said, I've never touched Django so I can't really say whether this could work, but I'd be tempted to do something more like

DailyStatExample = ClientStats.new("DSE", "Example stat class")


or

@ClientStats.register("DSE", "Example stat class")
class DailyStatExample:
    ...