Skip to content

Commit 9cac7c7

Browse files
committed
Move lib.py to _lib.py
1 parent 028f8e0 commit 9cac7c7

File tree

3 files changed

+23
-5
lines changed

3 files changed

+23
-5
lines changed

src/typed_app_settings/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""A package to create and use app specific settings with type hints."""
22

3-
__version__ = "0.1-post1"
3+
__version__ = "0.1-post2"
44

5-
from .lib import typed_settings_prefix, typed_settings_dict, UndefinedValue
5+
from ._lib import typed_settings_prefix, typed_settings_dict, UndefinedValue
66

77
__all__ = "typed_settings_prefix", "typed_settings_dict", "UndefinedValue"

src/typed_app_settings/lib.py renamed to src/typed_app_settings/_lib.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121

2222
class _SettingNotFoundError(Exception):
23-
...
23+
pass
2424

2525

2626
class UndefinedValue:
@@ -49,12 +49,14 @@ def __repr__(self):
4949

5050

5151
def _import_module(path: str, /) -> types.ModuleType:
52+
"""Import a module from a provided path."""
5253
package, _, module_name = path.rpartition(".")
5354

5455
return importlib.import_module(name=module_name, package=package)
5556

5657

5758
def _import_class(path: str, /) -> Type:
59+
"""Import a class from a provided path."""
5860
module_path, _, class_name = path.rpartition(".")
5961
package, _, module_name = module_path.rpartition(".")
6062
module = importlib.import_module(name=module_name, package=package)
@@ -63,6 +65,10 @@ def _import_class(path: str, /) -> Type:
6365

6466

6567
def _raise_on_set_attribute(self, attr_name, value: Any):
68+
"""
69+
Raise AttributeError when an attribute is set on the settings instance.
70+
Except the attr_name ends with _ATTR_RESOLVED_POSTFIX.
71+
"""
6672
if not attr_name.endswith(_ATTR_RESOLVED_POSTFIX):
6773
raise AttributeError(f"Can't set attribute {attr_name}")
6874
self.__dict__[attr_name] = value
@@ -98,30 +104,38 @@ def _class_decorator(cls: Type[_T]) -> Type[_T]:
98104
type_hints = get_annotations(cls)
99105

100106
for attr_name, value in inspect.getmembers(cls):
107+
# Skip dunder attributes and methods.
101108
if (
102109
attr_name.startswith("__") and attr_name.endswith("__")
103110
) or not attr_name.isupper():
104111
continue
105112

113+
# Define names for the "real" attribute and the resolved value
106114
hidden_attr_name = f"_{attr_name}"
107115
resolved_attr_name = f"_{attr_name}{_ATTR_RESOLVED_POSTFIX}"
108116

117+
# Property getter which substitutes the class member and handles
118+
# overriding of settings via settings.py.
109119
def getter(
110120
self,
111121
attr_name: str = attr_name,
112122
hidden_attr_name: str = hidden_attr_name,
113123
resolved_attr_name: str = resolved_attr_name,
114124
) -> Any:
125+
# Check if the setting was resolved previously and return that
126+
# already resolved value.
115127
value = getattr(self, resolved_attr_name)
116128
if value is not UndefinedValue:
117129
return value
118130

119131
annotation = type_hints.get(attr_name)
132+
# Check if the setting is overridden via settings.py.
120133
try:
121134
value = django_settings_getter(attr_name)
122135
except _SettingNotFoundError:
123136
value = getattr(self, hidden_attr_name)
124137

138+
# Perform checks and "magical" behaviours.
125139
if isinstance(value, UndefinedValue):
126140
raise ImproperlyConfigured(
127141
f"{attr_name!r} needs to be configured in your settings module"
@@ -131,6 +145,7 @@ def getter(
131145
elif _check_type(annotation) and isinstance(value, str):
132146
value = _import_class(value)
133147

148+
# Store the resolved setting in the instance.
134149
setattr(self, resolved_attr_name, value)
135150

136151
return value

tests/test_typed_app_settings.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@
88

99
from django.conf import settings as django_settings
1010
from django.core.exceptions import ImproperlyConfigured
11-
from typed_app_settings import UndefinedValue, typed_settings_prefix
12-
from typed_app_settings.lib import typed_settings_dict
11+
from typed_app_settings import (
12+
UndefinedValue,
13+
typed_settings_dict,
14+
typed_settings_prefix,
15+
)
1316

1417
django_settings.configure(
1518
DEBUG=True,

0 commit comments

Comments
 (0)