Skip to content

Commit 42f6d92

Browse files
committed
Add some cleanup and more docs
1 parent c2fada5 commit 42f6d92

File tree

2 files changed

+23
-13
lines changed

2 files changed

+23
-13
lines changed

readthedocs/core/utils/extend.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,16 @@
66
from django.utils.module_loading import import_by_path
77

88

9-
def get_override_class(proxy_class, default_class):
9+
def get_override_class(proxy_class, default_class=None):
10+
"""Determine which class to use in an override class
11+
12+
The `proxy_class` is the main class that is used, and `default_class` is the
13+
default class that this proxy class will instantiate. If `default_class` is
14+
not defined, this will be inferred from the `proxy_class`, as is defined in
15+
:py:cls:`SettingsOverrideObject`.
16+
"""
17+
if default_class is None:
18+
default_class = getattr(proxy_class, '_default_class')
1019
class_id = '.'.join([
1120
inspect.getmodule(proxy_class).__name__,
1221
proxy_class.__name__
@@ -33,22 +42,23 @@ class SettingsOverrideObject(object):
3342
"""Base class for creating class that can be overridden
3443
3544
This is used for extension points in the code, where we want to extend a
36-
class without monkey patching it. This abstract class allows for lazy
37-
inheritance, creating a class from the specified class or from a setting,
38-
but only once the class is called.
45+
class without monkey patching it. This class will proxy classmethod calls
46+
and instantiation to an underlying class, determined by used of
47+
:py:cvar:`_default_class` or an override class from settings.
3948
40-
Default to an instance of the class defined by :py:cvar:`_default_class`.
49+
The default target class is defined by :py:cvar:`_default_class`.
4150
42-
Next, look for an override setting class path in
43-
``settings.CLASS_OVERRIDES``, which should be a dictionary of class paths.
44-
The setting should be a dictionary keyed by the object path name::
51+
To override this class, an override setting class path can be added to
52+
``settings.CLASS_OVERRIDES``. This settings should be a dictionary keyed by
53+
source class paths, with values to the override classes::
4554
4655
CLASS_OVERRIDES = {
4756
'readthedocs.core.resolver.Resolver': 'something.resolver.Resolver',
4857
}
4958
5059
Lastly, if ``settings.CLASS_OVERRIDES`` is missing, or the key is not found,
51-
attempt to pull the key :py:cvar:`_override_setting` from ``settings``.
60+
attempt to pull the key :py:cvar:`_override_setting` from ``settings``. This
61+
matches the pattern we've been using previously.
5262
"""
5363

5464
__metaclass__ = SettingsOverrideMeta
@@ -59,7 +69,7 @@ class without monkey patching it. This abstract class allows for lazy
5969
def __new__(cls, *args, **kwargs):
6070
"""Set up wrapped object
6171
62-
Create an instance of the underlying proxy class and return instead of
72+
Create an instance of the underlying target class and return instead of
6373
this class.
6474
"""
6575
return get_override_class(cls, cls._default_class)(*args, **kwargs)

readthedocs/privacy/backend.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import logging
2-
31
from django.db import models
42

53
from guardian.shortcuts import get_objects_for_user
@@ -14,7 +12,6 @@
1412
get_override_class)
1513
from readthedocs.projects import constants
1614

17-
log = logging.getLogger(__name__)
1815

1916
class ProjectManager(models.Manager):
2017

@@ -87,6 +84,9 @@ class VersionManager(models.Manager):
8784

8885
@classmethod
8986
def from_queryset(cls, queryset_class, class_name=None):
87+
# This is overridden because :py:meth:`models.Manager.from_queryset`
88+
# uses `inspect` to retrieve the class methods, and the proxy class has
89+
# no direct members.
9090
queryset_class = get_override_class(
9191
VersionQuerySet,
9292
VersionQuerySet._default_class

0 commit comments

Comments
 (0)