Skip to content

Commit 1495895

Browse files
authored
Merge pull request #15 from mutating/develop
0.0.15
2 parents 105edb2 + afb9b46 commit 1495895

4 files changed

Lines changed: 240 additions & 9 deletions

File tree

pristan/components/plugins_group.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def _pop_group(self, requested_name: str) -> List[Plugin[PluginResult]]:
109109
raise KeyError(requested_name)
110110

111111
removed_plugins = self.plugins_by_requested_names.pop(requested_name)
112-
self.plugins = [plugin for plugin in self.plugins if plugin.requested_name != requested_name]
112+
self.plugins[:] = [plugin for plugin in self.plugins if plugin.requested_name != requested_name]
113113
return removed_plugins
114114

115115
def _pop_exact_plugin(self, key: str) -> List[Plugin[PluginResult]]:

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "pristan"
7-
version = "0.0.14"
7+
version = "0.0.15"
88
authors = [{ name = "Evgeniy Blinov", email = "zheni-b@yandex.ru" }]
99
description = "Function-based plugin system with respect to typing"
1010
readme = "README.md"

tests/units/components/test_plugins_group.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,21 +248,29 @@ def test_getitem_good_key():
248248

249249
def test_pop_by_base_name(group_with_named_duplicates):
250250
group, plugins = group_with_named_duplicates
251+
plugins_reference = group.plugins
252+
251253
removed_plugins = group.pop('name')
252254

253255
assert removed_plugins == plugins[:3]
256+
assert group.plugins is plugins_reference
254257
assert group.plugins == [plugins[3]]
258+
assert plugins_reference == [plugins[3]]
255259
assert group.plugins_by_requested_names == {
256260
'name2': [plugins[3]],
257261
}
258262

259263

260264
def test_pop_first_plugin_by_name_1(group_with_named_duplicates):
261265
group, plugins = group_with_named_duplicates
266+
plugins_reference = group.plugins
267+
262268
removed_plugins = group.pop('name-1')
263269

264270
assert removed_plugins == [plugins[0]]
271+
assert group.plugins is plugins_reference
265272
assert [x.name for x in group.plugins] == ['name', 'name-2', 'name2']
273+
assert [x.name for x in plugins_reference] == ['name', 'name-2', 'name2']
266274
assert group.plugins_by_requested_names == {
267275
'name': [plugins[1], plugins[2]],
268276
'name2': [plugins[3]],
@@ -271,10 +279,14 @@ def test_pop_first_plugin_by_name_1(group_with_named_duplicates):
271279

272280
def test_pop_middle_plugin_renumbers_remaining_duplicates(group_with_named_duplicates):
273281
group, plugins = group_with_named_duplicates
282+
plugins_reference = group.plugins
283+
274284
removed_plugins = group.pop('name-2')
275285

276286
assert removed_plugins == [plugins[1]]
287+
assert group.plugins is plugins_reference
277288
assert [x.name for x in group.plugins] == ['name', 'name-2', 'name2']
289+
assert [x.name for x in plugins_reference] == ['name', 'name-2', 'name2']
278290
assert group.plugins_by_requested_names == {
279291
'name': [plugins[0], plugins[2]],
280292
'name2': [plugins[3]],
@@ -283,10 +295,14 @@ def test_pop_middle_plugin_renumbers_remaining_duplicates(group_with_named_dupli
283295

284296
def test_pop_last_plugin_keeps_compact_numbering(group_with_named_duplicates):
285297
group, plugins = group_with_named_duplicates
298+
plugins_reference = group.plugins
299+
286300
removed_plugins = group.pop('name-3')
287301

288302
assert removed_plugins == [plugins[2]]
303+
assert group.plugins is plugins_reference
289304
assert [x.name for x in group.plugins] == ['name', 'name-2', 'name2']
305+
assert [x.name for x in plugins_reference] == ['name', 'name-2', 'name2']
290306
assert group.plugins_by_requested_names == {
291307
'name': [plugins[0], plugins[1]],
292308
'name2': [plugins[3]],
@@ -295,11 +311,14 @@ def test_pop_last_plugin_keeps_compact_numbering(group_with_named_duplicates):
295311

296312
def test_pop_only_plugin_by_name_1_removes_requested_name_bucket(group_with_named_duplicates):
297313
group, plugins = group_with_named_duplicates
314+
plugins_reference = group.plugins
298315

299316
removed_plugins = group.pop('name2-1')
300317

301318
assert removed_plugins == [plugins[3]]
319+
assert group.plugins is plugins_reference
302320
assert group.plugins == plugins[:3]
321+
assert plugins_reference == plugins[:3]
303322
assert group.plugins_by_requested_names == {
304323
'name': plugins[:3],
305324
}

tests/units/decorators/test_slot.py

Lines changed: 219 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,21 +1081,23 @@ def plugin(): # noqa: F811
10811081

10821082

10831083
def test_delitem_removes_plugins_from_slot(folder_slot, folder_plugin):
1084+
bread_crumbs = []
1085+
10841086
@folder_slot(slot)
10851087
def some_slot():
1086-
...
1088+
bread_crumbs.append('slot')
10871089

10881090
@folder_plugin(some_slot)
10891091
def plugin():
1090-
...
1092+
bread_crumbs.append('plugin_1')
10911093

10921094
@folder_plugin(some_slot)
10931095
def plugin(): # noqa: F811
1094-
...
1096+
bread_crumbs.append('plugin_2')
10951097

10961098
@folder_plugin(some_slot)
10971099
def plugin2():
1098-
...
1100+
bread_crumbs.append('plugin2')
10991101

11001102
del some_slot['plugin']
11011103

@@ -1107,6 +1109,10 @@ def plugin2():
11071109
assert len(some_slot) == 1
11081110
assert 'plugin' not in some_slot
11091111

1112+
some_slot()
1113+
1114+
assert bread_crumbs == ['plugin2']
1115+
11101116

11111117
def test_pop_removes_plugin_and_returns_detached_selection(folder_slot):
11121118
bread_crumbs = []
@@ -1137,6 +1143,194 @@ def plugin_3(a):
11371143

11381144
assert bread_crumbs == ['plugin_2_1']
11391145

1146+
bread_crumbs.clear()
1147+
1148+
some_slot(1)
1149+
1150+
assert bread_crumbs == ['plugin_1_1', 'plugin_3_1']
1151+
1152+
1153+
def test_delitem_by_base_name_last_list_plugin_falls_back_to_slot_body(folder_slot, subscribable_list_type):
1154+
body_calls = []
1155+
1156+
@folder_slot(slot)
1157+
def some_slot(a) -> subscribable_list_type[int]:
1158+
body_calls.append(a)
1159+
return []
1160+
1161+
@some_slot.plugin('plugin')
1162+
def plugin_1(a):
1163+
return a
1164+
1165+
assert some_slot(1) == [1]
1166+
assert body_calls == []
1167+
1168+
del some_slot['plugin']
1169+
1170+
assert some_slot.keys() == ()
1171+
assert len(some_slot) == 0
1172+
assert 'plugin' not in some_slot
1173+
assert 'plugin-1' not in some_slot
1174+
assert [x.name for x in some_slot] == []
1175+
assert some_slot(1) == []
1176+
assert body_calls == [1]
1177+
1178+
1179+
def test_pop_by_base_name_last_list_plugin_falls_back_to_slot_body(folder_slot, subscribable_list_type):
1180+
body_calls = []
1181+
1182+
@folder_slot(slot)
1183+
def some_slot(a) -> subscribable_list_type[int]:
1184+
body_calls.append(a)
1185+
return []
1186+
1187+
@some_slot.plugin('plugin')
1188+
def plugin_1(a):
1189+
return a
1190+
1191+
assert some_slot(1) == [1]
1192+
assert body_calls == []
1193+
1194+
removed_plugins = some_slot.pop('plugin')
1195+
1196+
assert [x.name for x in removed_plugins] == ['plugin']
1197+
assert removed_plugins(2) == [2]
1198+
assert some_slot.keys() == ()
1199+
assert len(some_slot) == 0
1200+
assert 'plugin' not in some_slot
1201+
assert 'plugin-1' not in some_slot
1202+
assert [x.name for x in some_slot] == []
1203+
assert some_slot(2) == []
1204+
assert body_calls == [2]
1205+
1206+
1207+
def test_delitem_by_base_name_removes_group_from_list_slot_call(folder_slot, subscribable_list_type):
1208+
@folder_slot(slot)
1209+
def some_slot(a) -> subscribable_list_type[int]: # noqa: ARG001
1210+
return []
1211+
1212+
@some_slot.plugin('plugin')
1213+
def plugin_1(a):
1214+
return a
1215+
1216+
@some_slot.plugin('plugin')
1217+
def plugin_2(a):
1218+
return a + 1
1219+
1220+
@some_slot.plugin('other')
1221+
def other(a):
1222+
return a + 2
1223+
1224+
assert some_slot(1) == [1, 2, 3]
1225+
1226+
del some_slot['plugin']
1227+
1228+
assert some_slot.keys() == ('other',)
1229+
assert len(some_slot) == 1
1230+
assert 'plugin' not in some_slot
1231+
assert 'plugin-1' not in some_slot
1232+
assert 'plugin-2' not in some_slot
1233+
assert 'other' in some_slot
1234+
assert [x.name for x in some_slot] == ['other']
1235+
assert some_slot(1) == [3]
1236+
1237+
1238+
def test_pop_by_base_name_returns_detached_group_and_keeps_survivors_in_list_slot_call(folder_slot, subscribable_list_type):
1239+
@folder_slot(slot)
1240+
def some_slot(a) -> subscribable_list_type[int]: # noqa: ARG001
1241+
return []
1242+
1243+
@some_slot.plugin('plugin')
1244+
def plugin_1(a):
1245+
return a
1246+
1247+
@some_slot.plugin('plugin')
1248+
def plugin_2(a):
1249+
return a + 1
1250+
1251+
@some_slot.plugin('other')
1252+
def other(a):
1253+
return a + 2
1254+
1255+
assert some_slot(1) == [1, 2, 3]
1256+
1257+
removed_plugins = some_slot.pop('plugin')
1258+
1259+
assert [x.name for x in removed_plugins] == ['plugin', 'plugin-2']
1260+
assert removed_plugins(1) == [1, 2]
1261+
assert some_slot.keys() == ('other',)
1262+
assert len(some_slot) == 1
1263+
assert 'plugin' not in some_slot
1264+
assert 'plugin-1' not in some_slot
1265+
assert 'plugin-2' not in some_slot
1266+
assert 'other' in some_slot
1267+
assert [x.name for x in some_slot] == ['other']
1268+
assert some_slot(1) == [3]
1269+
1270+
1271+
def test_delitem_by_base_name_removes_group_from_dict_slot_call(folder_slot, subscribable_dict_type):
1272+
@folder_slot(slot)
1273+
def some_slot(a) -> subscribable_dict_type[str, int]: # noqa: ARG001
1274+
return {}
1275+
1276+
@some_slot.plugin('plugin')
1277+
def plugin_1(a):
1278+
return a
1279+
1280+
@some_slot.plugin('plugin')
1281+
def plugin_2(a):
1282+
return a + 1
1283+
1284+
@some_slot.plugin('other')
1285+
def other(a):
1286+
return a + 2
1287+
1288+
assert some_slot(1) == {'plugin': 1, 'plugin-2': 2, 'other': 3}
1289+
1290+
del some_slot['plugin']
1291+
1292+
assert some_slot.keys() == ('other',)
1293+
assert len(some_slot) == 1
1294+
assert 'plugin' not in some_slot
1295+
assert 'plugin-1' not in some_slot
1296+
assert 'plugin-2' not in some_slot
1297+
assert 'other' in some_slot
1298+
assert [x.name for x in some_slot] == ['other']
1299+
assert some_slot(1) == {'other': 3}
1300+
1301+
1302+
def test_pop_by_base_name_returns_detached_group_and_keeps_survivors_in_dict_slot_call(folder_slot, subscribable_dict_type):
1303+
@folder_slot(slot)
1304+
def some_slot(a) -> subscribable_dict_type[str, int]: # noqa: ARG001
1305+
return {}
1306+
1307+
@some_slot.plugin('plugin')
1308+
def plugin_1(a):
1309+
return a
1310+
1311+
@some_slot.plugin('plugin')
1312+
def plugin_2(a):
1313+
return a + 1
1314+
1315+
@some_slot.plugin('other')
1316+
def other(a):
1317+
return a + 2
1318+
1319+
assert some_slot(1) == {'plugin': 1, 'plugin-2': 2, 'other': 3}
1320+
1321+
removed_plugins = some_slot.pop('plugin')
1322+
1323+
assert [x.name for x in removed_plugins] == ['plugin', 'plugin-2']
1324+
assert removed_plugins(1) == {'plugin': 1, 'plugin-2': 2}
1325+
assert some_slot.keys() == ('other',)
1326+
assert len(some_slot) == 1
1327+
assert 'plugin' not in some_slot
1328+
assert 'plugin-1' not in some_slot
1329+
assert 'plugin-2' not in some_slot
1330+
assert 'other' in some_slot
1331+
assert [x.name for x in some_slot] == ['other']
1332+
assert some_slot(1) == {'other': 3}
1333+
11401334

11411335
def test_pop_returns_default_for_missing_key(folder_slot):
11421336
@folder_slot(slot)
@@ -1199,31 +1393,49 @@ def plugin_3(a, b=6):
11991393

12001394

12011395
def test_delitem_and_pop_support_exact_duplicate_keys(folder_slot):
1396+
bread_crumbs = []
1397+
12021398
@folder_slot(slot)
12031399
def some_slot():
12041400
...
12051401

12061402
@some_slot.plugin('plugin')
12071403
def plugin_1():
1208-
...
1404+
bread_crumbs.append('plugin_1')
12091405

12101406
@some_slot.plugin('plugin')
12111407
def plugin_2():
1212-
...
1408+
bread_crumbs.append('plugin_2')
12131409

12141410
@some_slot.plugin('plugin')
12151411
def plugin_3():
1216-
...
1412+
bread_crumbs.append('plugin_3')
12171413

12181414
del some_slot['plugin-1']
12191415

12201416
assert [x.name for x in some_slot.plugins.plugins] == ['plugin', 'plugin-2']
12211417

1418+
some_slot()
1419+
1420+
assert bread_crumbs == ['plugin_2', 'plugin_3']
1421+
1422+
bread_crumbs.clear()
1423+
12221424
removed_plugins = some_slot.pop('plugin-2')
12231425

12241426
assert [x.name for x in removed_plugins] == ['plugin-2']
12251427
assert [x.name for x in some_slot.plugins.plugins] == ['plugin']
12261428

1429+
removed_plugins()
1430+
1431+
assert bread_crumbs == ['plugin_3']
1432+
1433+
bread_crumbs.clear()
1434+
1435+
some_slot()
1436+
1437+
assert bread_crumbs == ['plugin_2']
1438+
12271439

12281440
def test_delitem_with_name_1_removes_first_plugin(folder_slot):
12291441
bread_crumbs = []

0 commit comments

Comments
 (0)