diff --git a/.travis.yml b/.travis.yml index 8904a9f..bf9e82b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ language: python python: + - "3.7" - "3.8" - "3.9" - "3.10" diff --git a/demo_proj/demo_app/admin.py b/demo_proj/demo_app/admin.py index 13be29d..8c38f3f 100644 --- a/demo_proj/demo_app/admin.py +++ b/demo_proj/demo_app/admin.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.contrib import admin # Register your models here. diff --git a/demo_proj/demo_app/apps.py b/demo_proj/demo_app/apps.py index 9fcff05..1c3d06c 100644 --- a/demo_proj/demo_app/apps.py +++ b/demo_proj/demo_app/apps.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.apps import AppConfig from django.utils.translation import gettext_lazy as _ @@ -10,7 +7,7 @@ class DemoAppConfig(AppConfig): verbose_name = _('Demo application') def ready(self): - super(DemoAppConfig, self).ready() + super().ready() dummy_trans = _('Can deliver pizzas') dummy_trans = _('Can do stuff') diff --git a/demo_proj/demo_app/migrations/0001_initial.py b/demo_proj/demo_app/migrations/0001_initial.py index 7ad9618..47b3c54 100644 --- a/demo_proj/demo_app/migrations/0001_initial.py +++ b/demo_proj/demo_app/migrations/0001_initial.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.5 on 2018-06-30 08:41 -from __future__ import unicode_literals from django.db import migrations, models diff --git a/demo_proj/demo_app/models.py b/demo_proj/demo_app/models.py index 22295c3..a9cbe3f 100644 --- a/demo_proj/demo_app/models.py +++ b/demo_proj/demo_app/models.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import models from django.utils.translation import gettext_lazy as _ diff --git a/demo_proj/demo_app/tests.py b/demo_proj/demo_app/tests.py index 5982e6b..7ce503c 100644 --- a/demo_proj/demo_app/tests.py +++ b/demo_proj/demo_app/tests.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.test import TestCase # Create your tests here. diff --git a/demo_proj/demo_app/views.py b/demo_proj/demo_app/views.py index e784a0b..91ea44a 100644 --- a/demo_proj/demo_app/views.py +++ b/demo_proj/demo_app/views.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.shortcuts import render # Create your views here. diff --git a/setup.py b/setup.py index 910f992..6c67e40 100644 --- a/setup.py +++ b/setup.py @@ -26,11 +26,7 @@ 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', 'Programming Language :: Python', - 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', @@ -39,4 +35,4 @@ 'Topic :: Internet :: WWW/HTTP', 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', ], -) \ No newline at end of file +) diff --git a/tabular_permissions/admin.py b/tabular_permissions/admin.py index 76e4386..12d0ebf 100644 --- a/tabular_permissions/admin.py +++ b/tabular_permissions/admin.py @@ -8,19 +8,19 @@ User = get_user_model() -class UserTabularPermissionsMixin(object): +class UserTabularPermissionsMixin: def formfield_for_manytomany(self, db_field, request=None, **kwargs): - field = super(UserTabularPermissionsMixin, self).formfield_for_manytomany(db_field, request, **kwargs) + field = super().formfield_for_manytomany(db_field, request, **kwargs) if db_field.name == 'user_permissions': field.widget = TabularPermissionsWidget(db_field.verbose_name, db_field.name in self.filter_vertical) field.help_text = '' return field -class GroupTabularPermissionsMixin(object): +class GroupTabularPermissionsMixin: def formfield_for_manytomany(self, db_field, request=None, **kwargs): - field = super(GroupTabularPermissionsMixin, self).formfield_for_manytomany(db_field, request, **kwargs) + field = super().formfield_for_manytomany(db_field, request, **kwargs) if db_field.name == 'permissions': field.widget = TabularPermissionsWidget(db_field.verbose_name, db_field.name in self.filter_vertical, 'permissions') diff --git a/tabular_permissions/helpers.py b/tabular_permissions/helpers.py index 69e7194..9cf33ed 100644 --- a/tabular_permissions/helpers.py +++ b/tabular_permissions/helpers.py @@ -1,9 +1,8 @@ -from __future__ import unicode_literals from django.utils.translation import gettext_lazy as _ def get_perm_name(model_name, perm_name): - return '%s_%s' % (perm_name, model_name) + return f'{perm_name}_{model_name}' def dummy_permissions_exclude(model): diff --git a/tabular_permissions/widgets.py b/tabular_permissions/widgets.py index 413ba48..caaab75 100644 --- a/tabular_permissions/widgets.py +++ b/tabular_permissions/widgets.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from collections import OrderedDict from django import VERSION @@ -31,7 +29,7 @@ class Media: js = ('tabular_permissions/tabular_permissions.js',) def __init__(self, verbose_name, is_stacked, input_name='user_permissions', attrs=None, choices=()): - super(TabularPermissionsWidget, self).__init__(verbose_name, is_stacked, attrs, choices) + super().__init__(verbose_name, is_stacked, attrs, choices) self.managed_perms = [] self.input_name = input_name # in case of UserAdmin, it's 'user_permissions', GroupAdmin it's 'permissions' self.hide_original = True @@ -41,10 +39,10 @@ def render(self, name, value, attrs=None, renderer=None): apps_available = OrderedDict() # [] # main container to send to template user_permissions = Permission.objects.filter(id__in=value or []).values_list('id', flat=True) all_perms = Permission.objects.all().values('id', 'codename', 'content_type_id').order_by('codename') - excluded_perms = set([]) + excluded_perms = set() codename_id_map = {} for p in all_perms: - codename_id_map['%s_%s' % (p['codename'], p['content_type_id'])] = p['id'] + codename_id_map['{}_{}'.format(p['codename'], p['content_type_id'])] = p['id'] # reminder_perms used to detect if the tabular permissions covers all permissions, # if true, we don't need to make the default widget visible. @@ -71,18 +69,18 @@ def render(self, name, value, attrs=None, renderer=None): change_perm_name = get_perm_name(model_name, 'change') delete_perm_name = get_perm_name(model_name, 'delete') - view_perm_id = codename_id_map.get('%s_%s' % (view_perm_name, ct_id), + view_perm_id = codename_id_map.get(f'{view_perm_name}_{ct_id}', False) if 'view' in model._meta.default_permissions else False - add_perm_id = codename_id_map.get('%s_%s' % (add_perm_name, ct_id), + add_perm_id = codename_id_map.get(f'{add_perm_name}_{ct_id}', False) if 'add' in model._meta.default_permissions else False - change_perm_id = codename_id_map.get('%s_%s' % (change_perm_name, ct_id), + change_perm_id = codename_id_map.get(f'{change_perm_name}_{ct_id}', False) if 'change' in model._meta.default_permissions else False - delete_perm_id = codename_id_map.get('%s_%s' % (delete_perm_name, ct_id), + delete_perm_id = codename_id_map.get(f'{delete_perm_name}_{ct_id}', False) if 'delete' in model._meta.default_permissions else False if model._meta.permissions: custom_permissions_available = True for codename, perm_name in model._meta.permissions: - c_perm_id = codename_id_map.get('%s_%s' % (codename, ct_id), False) + c_perm_id = codename_id_map.get(f'{codename}_{ct_id}', False) verbose_name = TRANSLATION_FUNC(codename, perm_name, ct_id) model_custom_permissions.append( (codename, verbose_name, c_perm_id) @@ -93,12 +91,12 @@ def render(self, name, value, attrs=None, renderer=None): view_perm_id or add_perm_id or change_perm_id or delete_perm_id or model_custom_permissions): excluded_perms.update( [view_perm_id, add_perm_id, change_perm_id, delete_perm_id] + model_custom_permissions_ids) - reminder_perms.pop('%s_%s' % (view_perm_name, ct_id), False) - reminder_perms.pop('%s_%s' % (add_perm_name, ct_id), False) - reminder_perms.pop('%s_%s' % (change_perm_name, ct_id), False) - reminder_perms.pop('%s_%s' % (delete_perm_name, ct_id), False) + reminder_perms.pop(f'{view_perm_name}_{ct_id}', False) + reminder_perms.pop(f'{add_perm_name}_{ct_id}', False) + reminder_perms.pop(f'{change_perm_name}_{ct_id}', False) + reminder_perms.pop(f'{delete_perm_name}_{ct_id}', False) for c, v, _id in model_custom_permissions: - reminder_perms.pop('%s_%s' % (c, ct_id), False) + reminder_perms.pop(f'{c}_{ct_id}', False) # Because the logic of exclusion should/would work on both the tabular_permissin widget # and the normal widget diff --git a/tests/test_tabular_permissions/tests.py b/tests/test_tabular_permissions/tests.py index 36ee99a..65637a1 100644 --- a/tests/test_tabular_permissions/tests.py +++ b/tests/test_tabular_permissions/tests.py @@ -1,4 +1,3 @@ -from __future__ import unicode_literals from django import test from django.contrib.auth import get_user_model from django.contrib.auth.models import Permission @@ -124,7 +123,7 @@ class TabularPermissionsTestCase(test.TestCase): @classmethod def setUpClass(cls): - super(TabularPermissionsTestCase, cls).setUpClass() + super().setUpClass() cls.user = User.objects.create_superuser(username='super', password='secret', email='email@domain.com') def test_visible_on_group_admin(self): @@ -132,7 +131,7 @@ def test_visible_on_group_admin(self): Test tabular_permissions visible on GroupAdmin with right data-input-name """ self.client.login(username='super', password='secret') - response = self.client.get((reverse('admin:auth_group_add'))) + response = self.client.get(reverse('admin:auth_group_add')) self.assertEqual(response.status_code, 200) doc = pq(response.content) table = doc.find('#tabular_permissions')