diff --git a/sitetree/admin.py b/sitetree/admin.py index 0c7d86c6..fac33bdc 100644 --- a/sitetree/admin.py +++ b/sitetree/admin.py @@ -32,7 +32,7 @@ def get_model_url_name(model_nfo: Tuple[str, str], page: str, with_namespace: bo prefix = '' if with_namespace: prefix = 'admin:' - return ('%s%s_%s' % (prefix, '%s_%s' % model_nfo, page)).lower() + return (f'{prefix}%s_{page}' % '%s_%s' % model_nfo).lower() def get_tree_url_name(page: str, with_namespace: bool = False) -> str: @@ -154,7 +154,7 @@ def response_add(self, request, obj, post_url_continue=None, **kwargs): """ if post_url_continue is None: - post_url_continue = '../item_%s/' % obj.pk + post_url_continue = f'../item_{obj.pk}/' return self._redirect(request, super().response_add(request, obj, post_url_continue)) @@ -205,9 +205,9 @@ def _stack_known_urls(self, reverse_dict, ns=None): for url_name, url_rules in reverse_dict.items(): if isinstance(url_name, str): if ns is not None: - url_name = '%s:%s' % (ns, url_name) + url_name = f'{ns}:{url_name}' self.known_url_names.append(url_name) - self.known_url_rules.append('%s %s' % (url_name, ' '.join(url_rules[0][0][1]))) + self.known_url_rules.append(f"{url_name} {' '.join(url_rules[0][0][1])}") def get_tree(self, request: HttpRequest, tree_id: Optional[int], item_id: Optional[int] = None) -> 'TreeBase': """Fetches Tree for current or given TreeItem.""" @@ -332,22 +332,22 @@ def get_urls(self): sitetree_urls = [ url(r'^change/$', redirects_handler, name=get_tree_item_url_name('changelist')), - url(r'^((?P\d+)/)?%sitem_add/$' % prefix_change, + url(fr'^((?P\d+)/)?{prefix_change}item_add/$', self.admin_site.admin_view(self.tree_admin.item_add), name=get_tree_item_url_name('add')), - url(r'^(?P\d+)/%sitem_(?P\d+)/$' % prefix_change, + url(fr'^(?P\d+)/{prefix_change}item_(?P\d+)/$', self.admin_site.admin_view(self.tree_admin.item_edit), name=get_tree_item_url_name('change')), - url(r'^%sitem_(?P\d+)/$' % prefix_change, + url(fr'^{prefix_change}item_(?P\d+)/$', self.admin_site.admin_view(self.tree_admin.item_edit), name=get_tree_item_url_name('change')), - url(r'^((?P\d+)/)?%sitem_(?P\d+)/delete/$' % prefix_change, + url(fr'^((?P\d+)/)?{prefix_change}item_(?P\d+)/delete/$', self.admin_site.admin_view(self.tree_admin.item_delete), name=get_tree_item_url_name('delete')), - url(r'^((?P\d+)/)?%sitem_(?P\d+)/history/$' % prefix_change, + url(fr'^((?P\d+)/)?{prefix_change}item_(?P\d+)/history/$', self.admin_site.admin_view(self.tree_admin.item_history), name=get_tree_item_url_name('history')), - url(r'^(?P\d+)/%sitem_(?P\d+)/move_(?P(up|down))/$' % prefix_change, + url(fr'^(?P\d+)/{prefix_change}item_(?P\d+)/move_(?P(up|down))/$', self.admin_site.admin_view(self.tree_admin.item_move), name=get_tree_item_url_name('move')), ] if SMUGGLER_INSTALLED: diff --git a/sitetree/fields.py b/sitetree/fields.py index 6aa07bcd..6468e52f 100644 --- a/sitetree/fields.py +++ b/sitetree/fields.py @@ -63,7 +63,7 @@ def choices_init(self, tree: Optional['TreeBase']): def _build_choices(self): """Build choices list runtime using 'sitetree_tree' tag""" - tree_token = 'sitetree_tree from "%s" template "%s"' % (self.tree, self.template) + tree_token = f'sitetree_tree from "{self.tree}" template "{self.template}"' context_kwargs = {'current_app': 'admin'} context = template.Context(context_kwargs) diff --git a/sitetree/management/commands/sitetree_resync_apps.py b/sitetree/management/commands/sitetree_resync_apps.py index df24ca21..bc643fa0 100644 --- a/sitetree/management/commands/sitetree_resync_apps.py +++ b/sitetree/management/commands/sitetree_resync_apps.py @@ -37,23 +37,23 @@ def handle(self, *apps, **options): tree_modules = import_project_sitetree_modules() if not tree_modules: - self.stdout.write('No sitetrees found in project apps (searched in %%app%%/%s.py).\n' % APP_MODULE_NAME) + self.stdout.write(f'No sitetrees found in project apps (searched in %app%/{APP_MODULE_NAME}.py).\n') for module in tree_modules: sitetrees = getattr(module, 'sitetrees', None) app = module.__dict__['__package__'] if not apps or app in apps: if sitetrees is not None: - self.stdout.write('Sitetrees found in `%s` app ...\n' % app) + self.stdout.write(f'Sitetrees found in `{app}` app ...\n') for tree in sitetrees: - self.stdout.write(' Processing `%s` tree ...\n' % tree.alias) + self.stdout.write(f' Processing `{tree.alias}` tree ...\n') # Delete trees with the same name beforehand. MODEL_TREE_CLASS.objects.filter(alias=tree.alias).using(using).delete() # Drop id to let the DB handle it. tree.id = None tree.save(using=using) for item in tree.dynamic_items: - self.stdout.write(' Adding `%s` tree item ...\n' % item.title) + self.stdout.write(f' Adding `{item.title}` tree item ...\n') # Drop id to let the DB handle it. item.id = None if item.parent is not None: @@ -65,6 +65,7 @@ def handle(self, *apps, **options): # has been saved if hasattr(item.access_permissions, 'set'): item.access_permissions.set(item.permissions) + else: item.access_permissions = item.permissions diff --git a/sitetree/management/commands/sitetreedump.py b/sitetree/management/commands/sitetreedump.py index f077c112..13019596 100644 --- a/sitetree/management/commands/sitetreedump.py +++ b/sitetree/management/commands/sitetreedump.py @@ -56,4 +56,4 @@ def handle(self, *aliases, **options): return serializers.serialize('json', objects, indent=indent) except Exception as e: - raise CommandError('Unable to serialize sitetree(s): %s' % e) + raise CommandError(f'Unable to serialize sitetree(s): {e}') diff --git a/sitetree/management/commands/sitetreeload.py b/sitetree/management/commands/sitetreeload.py index 1d9bb74c..82a1bf82 100644 --- a/sitetree/management/commands/sitetreeload.py +++ b/sitetree/management/commands/sitetreeload.py @@ -51,8 +51,8 @@ def handle(self, *fixture_files, **options): try: items_into_tree = MODEL_TREE_CLASS.objects.get(alias=items_into_tree) except ObjectDoesNotExist: - raise CommandError('Target tree alised by `%s` does not exist. Please create it before import.' % - items_into_tree) + raise CommandError( + f'Target tree aliased `{items_into_tree}` does not exist. Please create it before import.') else: mode = 'append' @@ -69,7 +69,7 @@ def handle(self, *fixture_files, **options): for fixture_file in fixture_files: - self.stdout.write('Loading fixture from `%s` ...\n' % fixture_file) + self.stdout.write(f'Loading fixture from `{fixture_file}` ...\n') fixture = open(fixture_file, 'r') @@ -107,7 +107,7 @@ def handle(self, *fixture_files, **options): for tree in trees: - self.stdout.write('\nImporting tree `%s` ...\n' % tree.alias) + self.stdout.write(f'\nImporting tree `{tree.alias}` ...\n') orig_tree_id = tree.id if items_into_tree is None: @@ -125,7 +125,7 @@ def handle(self, *fixture_files, **options): for tree_item in tree_items[orig_tree_id]: parent_ahead = False - self.stdout.write('Importing item `%s` ...\n' % tree_item.title) + self.stdout.write(f'Importing item `{tree_item.title}` ...\n') tree_item.tree_id = tree.id orig_item_id = tree_item.id @@ -163,9 +163,9 @@ def handle(self, *fixture_files, **options): fixture.close() self.stderr.write( - self.style.ERROR('Fixture `%s` import error: %s\n' % ( - fixture_file, ''.join(traceback.format_exception(*sys.exc_info())) - )) + self.style.ERROR( + f"Fixture `{fixture_file}` import error: " + f"{''.join(traceback.format_exception(*sys.exc_info()))}\n") ) fixture.close() diff --git a/sitetree/sitetreeapp.py b/sitetree/sitetreeapp.py index 431d0219..8cf43318 100644 --- a/sitetree/sitetreeapp.py +++ b/sitetree/sitetreeapp.py @@ -101,7 +101,7 @@ def my_items_processor(tree_items, tree_sender): if tree_sender == 'menu.children': # Lets add 'Hooked: ' to resolved titles of every item. for item in tree_items: - item.title_resolved = 'Hooked: %s' % item.title_resolved + item.title_resolved = f'Hooked: {item.title_resolved}' # Return items list mutated or not. return tree_items @@ -267,7 +267,7 @@ def result(sitetrees): except ImportError as e: if settings.DEBUG: - warnings.warn('Unable to register dynamic sitetree(s) for `%s` application: %s. ' % (src, e)) + warnings.warn(f'Unable to register dynamic sitetree(s) for `{src}` application: {e}. ') return {} return result(src) @@ -413,7 +413,7 @@ def resolve_tree_i18n_alias(self, alias: str) -> str: return alias current_language_code = self.current_lang - i18n_tree_alias = '%s_%s' % (alias, current_language_code) + i18n_tree_alias = f'{alias}_{current_language_code}' trees_count = self.cache.get_entry('tree_aliases', i18n_tree_alias) if trees_count is False: @@ -575,7 +575,7 @@ def get_sitetree(self, alias: str) -> Tuple[str, List['TreeItemBase']]: else item.access_permissions.all()) item.perms = set( - ['%s.%s' % (perm.content_type.app_label, perm.codename) for perm in permissions_src]) + [f'{perm.content_type.app_label}.{perm.codename}' for perm in permissions_src]) # Contextual properties. item.url_resolved = url(item) @@ -694,18 +694,18 @@ def url(self, sitetree_item: Union['TreeItemBase', FilterExpression], context: C for view_argument in view_path[1:]: resolved = resolve_var(view_argument) # We enclose arg in double quotes as already resolved. - all_arguments.append('"%s"' % resolved) + all_arguments.append(f'"{resolved}"') view_path = view_path[0].strip('"\' ') - url_pattern = "'%s' %s" % (view_path, ' '.join(all_arguments)) + url_pattern = f"'{view_path}' {' '.join(all_arguments)}" else: - url_pattern = '%s' % sitetree_item.url + url_pattern = f'{sitetree_item.url}' if sitetree_item.urlaspattern: # Form token to pass to Django 'url' tag. - url_token = 'url %s as item.url_resolved' % url_pattern + url_token = f'url {url_pattern} as item.url_resolved' url_tag( Parser(None), Token(token_type=TOKEN_BLOCK, contents=url_token) @@ -784,8 +784,8 @@ def get_current_page_attr(self, attr_name: str, tree_alias: str, context: Contex if current_item is None: if settings.DEBUG and RAISE_ITEMS_ERRORS_ON_DEBUG: raise SiteTreeError( - 'Unable to resolve current sitetree item to get a `%s` for current page. Check whether ' - 'there is an appropriate sitetree item defined for current URL.' % attr_name) + f'Unable to resolve current sitetree item to get a `{attr_name}` for current page. Check whether ' + 'there is an appropriate sitetree item defined for current URL.') return '' @@ -1022,7 +1022,7 @@ def children( tree_items = self.get_children(tree_alias, parent_item) tree_items = self.filter_items(tree_items, navigation_type) - tree_items = self.apply_hook(tree_items, '%s.children' % navigation_type) + tree_items = self.apply_hook(tree_items, f'{navigation_type}.children') self.update_has_children(tree_alias, tree_items, navigation_type) my_template = get_template(use_template) @@ -1062,7 +1062,7 @@ def update_has_children(self, tree_alias: str, tree_items: List['TreeItemBase'], for tree_item in tree_items: children = get_children(tree_alias, tree_item) children = filter_items(children, navigation_type) - children = apply_hook(children, '%s.has_children' % navigation_type) + children = apply_hook(children, f'{navigation_type}.has_children') tree_item.has_children = len(children) > 0 def filter_items(self, items: List['TreeItemBase'], navigation_type: str = None) -> List['TreeItemBase']: @@ -1089,7 +1089,7 @@ def filter_items(self, items: List['TreeItemBase'], navigation_type: str = None) if not check_access(item, context): continue - if not getattr(item, 'in%s' % navigation_type, True): # Hidden for current nav type + if not getattr(item, f'in{navigation_type}', True): # Hidden for current nav type continue items_filtered.append(item) diff --git a/sitetree/templatetags/sitetree.py b/sitetree/templatetags/sitetree.py index 3eae52e7..e2c98619 100644 --- a/sitetree/templatetags/sitetree.py +++ b/sitetree/templatetags/sitetree.py @@ -215,7 +215,7 @@ def for_tag(cls, parser, token, preposition, error_hint): return cls(tree_alias, as_var) raise template.TemplateSyntaxError( - '%r tag requires at least two arguments. E.g. {%% %s %%}.' % (tokens[0], error_hint)) + f'{tokens[0]} tag requires at least two arguments. E.g. {{% {error_hint} %}}.') @classmethod def get_as_var(cls, tokens): diff --git a/sitetree/tests/conftest.py b/sitetree/tests/conftest.py index 70053444..5f2cd5d1 100644 --- a/sitetree/tests/conftest.py +++ b/sitetree/tests/conftest.py @@ -45,7 +45,7 @@ def attach_items(tree, items, parent=None): for permission in access_permissions: item.access_permissions.add(Permission.objects.get(codename=permission)) - items_map['%s' % item.url] = item + items_map[f'{item.url}'] = item children and attach_items(tree, children, parent=item) diff --git a/sitetree/tests/test_management.py b/sitetree/tests/test_management.py index 56f54085..37bb700f 100644 --- a/sitetree/tests/test_management.py +++ b/sitetree/tests/test_management.py @@ -12,7 +12,7 @@ def load(treedump, command_kwargs=None): f = tmpdir.join('somefile.json') f.write(treedump) command_kwargs = command_kwargs or {} - command_run('sitetreeload', ['%s' % f], command_kwargs) + command_run('sitetreeload', [f'{f}'], command_kwargs) treedump = ( '[' diff --git a/sitetree/tests/test_other.py b/sitetree/tests/test_other.py index b205f682..3c5eda04 100644 --- a/sitetree/tests/test_other.py +++ b/sitetree/tests/test_other.py @@ -21,8 +21,8 @@ def test_stress(template_render_tag, template_context, template_strip_tags, buil tree = template_strip_tags(template_render_tag('sitetree', 'sitetree_tree from "mytree"', context)) breadcrumbs = template_strip_tags(template_render_tag('sitetree', 'sitetree_breadcrumbs from "mytree"', context)) - menu = template_render_tag('sitetree', 'sitetree_menu from "mytree" include "%s"' % ALIAS_TRUNK, context) - menu_other = template_render_tag('sitetree', 'sitetree_menu from "othertree" include "%s"' % ALIAS_TRUNK, context) + menu = template_render_tag('sitetree', f'sitetree_menu from "mytree" include "{ALIAS_TRUNK}"', context) + menu_other = template_render_tag('sitetree', f'sitetree_menu from "othertree" include "{ALIAS_TRUNK}"', context) assert title == 'Private' assert title_other == 'Other title' diff --git a/sitetree/tests/test_templatetags.py b/sitetree/tests/test_templatetags.py index 7b1a4f8d..69b2799a 100644 --- a/sitetree/tests/test_templatetags.py +++ b/sitetree/tests/test_templatetags.py @@ -16,7 +16,7 @@ def test_items_hook(template_render_tag, template_context, common_tree): def my_processor(tree_items, tree_sender): for item in tree_items: - item.hint = 'hooked_hint_%s' % item.title + item.hint = f'hooked_hint_{item.title}' return tree_items register_items_hook(my_processor) @@ -228,14 +228,14 @@ def test_sitetree_breadcrumbs(template_render_tag, template_context, common_tree def check_page_attr_tag(realm, value, settings, monkeypatch, template_render_tag, template_context): with pytest.raises(TemplateSyntaxError): # Invalid tag arguments. - template_render_tag('sitetree', 'sitetree_page_%s' % realm) + template_render_tag('sitetree', f'sitetree_page_{realm}') context = template_context(request='/contacts/russia/') - result = template_render_tag('sitetree', 'sitetree_page_%s from "mytree"' % realm, context) + result = template_render_tag('sitetree', f'sitetree_page_{realm} from "mytree"', context) assert result == value - result = template_render_tag('sitetree', 'sitetree_page_%s from "mytree" as somevar' % realm, context) + result = template_render_tag('sitetree', f'sitetree_page_{realm} from "mytree" as somevar', context) assert result == '' assert context.get('somevar') == value @@ -243,19 +243,19 @@ def check_page_attr_tag(realm, value, settings, monkeypatch, template_render_tag settings.DEBUG = True with pytest.raises(SiteTreeError) as e: - template_render_tag('sitetree', 'sitetree_page_%s from "mytree"' % realm) + template_render_tag('sitetree', f'sitetree_page_{realm} from "mytree"') - assert 'django.core.context_processors.request' in '%s' % e.value + assert 'django.core.context_processors.request' in f'{e.value}' context = template_context(request='/unknown_url/') with pytest.raises(SiteTreeError) as e: - template_render_tag('sitetree', 'sitetree_page_%s from "mytree"' % realm, context) + template_render_tag('sitetree', f'sitetree_page_{realm} from "mytree"', context) - assert 'Unable to resolve current sitetree item' in '%s' % e.value + assert 'Unable to resolve current sitetree item' in f'{e.value}' monkeypatch.setattr('sitetree.sitetreeapp.RAISE_ITEMS_ERRORS_ON_DEBUG', False) - result = template_render_tag('sitetree', 'sitetree_page_%s from "mytree"' % realm, context) + result = template_render_tag('sitetree', f'sitetree_page_{realm} from "mytree"', context) assert result == '' @@ -295,7 +295,7 @@ def test_sitetree_url(template_render_tag, template_context, common_tree): def test_sitetree_menu(template_render_tag, template_context, common_tree): result = template_render_tag( - 'sitetree', 'sitetree_menu from "notree" include "%s"' % ALIAS_TRUNK, template_context()) # non-existing tree + 'sitetree', f'sitetree_menu from "notree" include "{ALIAS_TRUNK}"', template_context()) # non-existing tree assert result.strip() == '
    \n\t\n
' @@ -305,20 +305,20 @@ def test_sitetree_menu(template_render_tag, template_context, common_tree): item_ruweb = common_tree['/contacts/russia/web/'] context = template_context(request='/') - result = template_render_tag('sitetree', 'sitetree_menu from "mytree" include "%s"' % item_ruweb.alias, context) + result = template_render_tag('sitetree', f'sitetree_menu from "mytree" include "{item_ruweb.alias}"', context) assert '"/contacts/russia/web/"' not in result assert '"/contacts/russia/web/public/"' in result assert '"/contacts/russia/web/private/"' in result - result = template_render_tag('sitetree', 'sitetree_menu from "mytree" include "%s"' % item_ruweb.id, context) + result = template_render_tag('sitetree', f'sitetree_menu from "mytree" include "{item_ruweb.id}"', context) assert '"/contacts/russia/web/"' not in result assert '"/contacts/russia/web/public/"' in result assert '"/contacts/russia/web/private/"' in result context = template_context(request='/contacts/russia/web/') - result = template_render_tag('sitetree', 'sitetree_menu from "mytree" include "%s"' % ALIAS_TRUNK, context) + result = template_render_tag('sitetree', f'sitetree_menu from "mytree" include "{ALIAS_TRUNK}"', context) assert '"/users/moderators/"' in result assert '"/articles/cats/ugly/"' in result @@ -331,7 +331,7 @@ def test_sitetree_menu(template_render_tag, template_context, common_tree): assert 'class="current_branch">Home' in result context = template_context(request='/articles/') - result = template_render_tag('sitetree', 'sitetree_menu from "mytree" include "%s"' % ALIAS_THIS_CHILDREN, context) + result = template_render_tag('sitetree', f'sitetree_menu from "mytree" include "{ALIAS_THIS_CHILDREN}"', context) assert '"/articles/"' not in result assert '"/articles/cats/"' in result @@ -340,7 +340,7 @@ def test_sitetree_menu(template_render_tag, template_context, common_tree): context = template_context(request='/articles/cats/bad/') result = template_render_tag( - 'sitetree', 'sitetree_menu from "mytree" include "%s"' % ALIAS_THIS_SIBLINGS, context) + 'sitetree', f'sitetree_menu from "mytree" include "{ALIAS_THIS_SIBLINGS}"', context) assert '"/articles/cats/"' not in result assert '"/articles/cats/good/"' in result @@ -349,7 +349,7 @@ def test_sitetree_menu(template_render_tag, template_context, common_tree): context = template_context(request='/contacts/russia/web/public/') result = template_render_tag( - 'sitetree', 'sitetree_menu from "mytree" include "%s"' % ALIAS_THIS_PARENT_SIBLINGS, context) + 'sitetree', f'sitetree_menu from "mytree" include "{ALIAS_THIS_PARENT_SIBLINGS}"', context) assert '"/contacts/russia/"' not in result assert '"/contacts/russia/web/"' in result @@ -358,7 +358,7 @@ def test_sitetree_menu(template_render_tag, template_context, common_tree): context = template_context(request='/contacts/russia/web/public/') result = template_render_tag( - 'sitetree', 'sitetree_menu from "mytree" include "%s"' % ALIAS_THIS_ANCESTOR_CHILDREN, context) + 'sitetree', f'sitetree_menu from "mytree" include "{ALIAS_THIS_ANCESTOR_CHILDREN}"', context) assert '"/home/"' not in result assert '"/contacts/russia/web/public/"' in result diff --git a/sitetree/tests/test_utils.py b/sitetree/tests/test_utils.py index 1905a9e0..879ac7c8 100644 --- a/sitetree/tests/test_utils.py +++ b/sitetree/tests/test_utils.py @@ -51,7 +51,7 @@ def test_import_project_sitetree_modules(): def get_permission_and_name(): from django.contrib.auth.models import Permission perm = Permission.objects.all()[0] - perm_name = '%s.%s' % (perm.content_type.app_label, perm.codename) + perm_name = f'{perm.content_type.app_label}.{perm.codename}' return perm, perm_name diff --git a/sitetree/utils.py b/sitetree/utils.py index 03028608..c6f13644 100644 --- a/sitetree/utils.py +++ b/sitetree/utils.py @@ -131,13 +131,14 @@ def item( app, codename = perm.split('.') except ValueError: raise ValueError( - 'Wrong permission string format: supplied - `%s`; ' - 'expected - `.`.' % perm) + f'Wrong permission string format: supplied - `{perm}`; ' + 'expected - `.`.') try: perm = Permission.objects.get(codename=codename, content_type__app_label=app) + except Permission.DoesNotExist: - raise ValueError('Permission `%s.%s` does not exist.' % (app, codename)) + raise ValueError(f'Permission `{app}.{codename}` does not exist.') elif not isinstance(perm, (int, Permission)): raise ValueError('Permissions must be given as strings, ints, or `Permission` instances.') @@ -168,7 +169,7 @@ def import_app_sitetree_module(app: str) -> Optional[ModuleType]: module = import_module(app) try: - sub_module = import_module('%s.%s' % (app, module_name)) + sub_module = import_module(f'{app}.{module_name}') return sub_module except ImportError: @@ -204,7 +205,7 @@ def get_app_n_model(settings_entry_name: str) -> Tuple[str, str]: except ValueError: raise ImproperlyConfigured( - '`SITETREE_%s` must have the following format: `app_name.model_name`.' % settings_entry_name) + f'`SITETREE_{settings_entry_name}` must have the following format: `app_name.model_name`.') return app_name, model_name @@ -225,7 +226,7 @@ def get_model_class(settings_entry_name: str): if model is None: raise ImproperlyConfigured( - '`SITETREE_%s` refers to model `%s` that has not been installed.' % (settings_entry_name, model_name)) + f'`SITETREE_{settings_entry_name}` refers to model `{model_name}` that has not been installed.') return model