Skip to content

Commit 27242ac

Browse files
committed
added validation to AppRegistry to make sure there are no duplicate app names
1 parent 5d50e76 commit 27242ac

File tree

3 files changed

+36
-1
lines changed

3 files changed

+36
-1
lines changed

piccolo/conf/apps.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from dataclasses import dataclass, field
33
from importlib import import_module
44
import inspect
5+
import itertools
56
from types import ModuleType
67
import typing as t
78

@@ -108,10 +109,32 @@ class AppRegistry:
108109

109110
def __post_init__(self):
110111
self.app_configs: t.Dict[str, AppConfig] = {}
112+
app_names = []
113+
111114
for app in self.apps:
112115
app_conf_module = import_module(app)
113116
app_config: AppConfig = getattr(app_conf_module, "APP_CONFIG")
114117
self.app_configs[app_config.app_name] = app_config
118+
app_names.append(app_config.app_name)
119+
120+
self._validate_app_names(app_names)
121+
122+
@staticmethod
123+
def _validate_app_names(app_names: t.List[str]):
124+
"""
125+
Raise a ValueError if an app_name is repeated.
126+
"""
127+
app_names.sort()
128+
grouped = itertools.groupby(app_names)
129+
for key, value in grouped:
130+
count = len([i for i in value])
131+
if count > 1:
132+
raise ValueError(
133+
f"There are {count} apps with the name `{key}`. This can "
134+
"cause unexpected behavior. Make sure each app has a "
135+
"unique name, and you haven't registered the same app "
136+
"multiple times."
137+
)
115138

116139
def get_app_config(self, app_name: str) -> t.Optional[AppConfig]:
117140
return self.app_configs.get(app_name)

piccolo/engine/postgres.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ def get_version(self) -> float:
223223
)
224224

225225
try:
226-
response: t.Sequence[t.Dict] = future.result()
226+
response: t.Sequence[t.Dict] = future.result() # type: ignore
227227
except ConnectionRefusedError as exception:
228228
# Suppressing the exception, otherwise importing piccolo_conf.py
229229
# containing an engine will raise an ImportError.

tests/conf/test_apps.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,18 @@ def test_init(self):
99
app_config = app_registry.get_app_config(app_name="user")
1010
self.assertTrue(isinstance(app_config, AppConfig))
1111

12+
def test_duplicate_app_names(self):
13+
"""
14+
An exception should be if apps with duplicate names are registered.
15+
"""
16+
with self.assertRaises(ValueError):
17+
AppRegistry(
18+
apps=[
19+
"piccolo.apps.user.piccolo_app",
20+
"piccolo.apps.user.piccolo_app",
21+
]
22+
)
23+
1224

1325
class TestTableFinder(TestCase):
1426
def test_table_finder(self):

0 commit comments

Comments
 (0)