Browse Source

Use python3-style super()

In python3, super() does not always require a class and self reference.
In other words, super() is enough for most cases.
This is much simpler and it is time to switch it to the newer style.

pylint provides a check for this.
Let's enable 'super-with-arguments' check.

NOTE: _prepare_mappings() method of FormRegion in
openstack_dashboard/test/integration_tests/regions/forms.py is refactored.
super() (without explicit class and self referece) does not work when
a subclass method calls a same method in a parent class multiple times.
It looks better to prepare a separate method to provide a common logic.

Change-Id: Id9512a14be9f20dbd5ebd63d446570c7b7c825ff
changes/72/751972/4
Akihiro Motoki 1 year ago
parent
commit
e5d09edc20
  1. 2
      .pylintrc
  2. 7
      horizon/base.py
  3. 2
      horizon/browsers/base.py
  4. 2
      horizon/browsers/breadcrumb.py
  5. 10
      horizon/browsers/views.py
  6. 2
      horizon/contrib/staticfiles/finders.py
  7. 2
      horizon/exceptions.py
  8. 4
      horizon/forms/base.py
  9. 31
      horizon/forms/fields.py
  10. 8
      horizon/forms/views.py
  11. 2
      horizon/management/commands/startdash.py
  12. 2
      horizon/management/commands/startpanel.py
  13. 23
      horizon/tables/actions.py
  14. 10
      horizon/tables/base.py
  15. 8
      horizon/tables/formset.py
  16. 14
      horizon/tables/views.py
  17. 12
      horizon/tabs/base.py
  18. 4
      horizon/tabs/views.py
  19. 2
      horizon/test/firefox_binary.py
  20. 18
      horizon/test/helpers.py
  21. 2
      horizon/test/selenium/selenium_tests.py
  22. 8
      horizon/test/unit/forms/test_fields.py
  23. 2
      horizon/test/unit/forms/test_forms.py
  24. 4
      horizon/test/unit/middleware/test_base.py
  25. 2
      horizon/test/unit/middleware/test_operation_log.py
  26. 4
      horizon/test/unit/tabs/test_tabs.py
  27. 21
      horizon/test/unit/test_base.py
  28. 4
      horizon/test/unit/test_views.py
  29. 4
      horizon/test/unit/workflows/test_workflows.py
  30. 2
      horizon/test/utils.py
  31. 10
      horizon/test/webdriver.py
  32. 2
      horizon/utils/babel_extract_angular.py
  33. 6
      horizon/utils/csvbase.py
  34. 2
      horizon/utils/lazy_encoder.py
  35. 2
      horizon/utils/scss_filter.py
  36. 4
      horizon/views.py
  37. 16
      horizon/workflows/base.py
  38. 4
      horizon/workflows/views.py
  39. 4
      openstack_auth/forms.py
  40. 2
      openstack_auth/tests/data_v3.py
  41. 2
      openstack_auth/tests/unit/test_auth.py
  42. 2
      openstack_auth/tests/unit/test_utils.py
  43. 2
      openstack_dashboard/api/_nova.py
  44. 6
      openstack_dashboard/api/glance.py
  45. 2
      openstack_dashboard/api/keystone.py
  46. 24
      openstack_dashboard/api/neutron.py
  47. 2
      openstack_dashboard/api/rest/json_encoder.py
  48. 8
      openstack_dashboard/api/rest/utils.py
  49. 4
      openstack_dashboard/api/swift.py
  50. 2
      openstack_dashboard/contrib/developer/dashboard.py
  51. 2
      openstack_dashboard/contrib/developer/profiler/middleware.py
  52. 2
      openstack_dashboard/contrib/developer/profiler/views.py
  53. 2
      openstack_dashboard/dashboards/admin/aggregates/forms.py
  54. 2
      openstack_dashboard/dashboards/admin/aggregates/panel.py
  55. 2
      openstack_dashboard/dashboards/admin/aggregates/tables.py
  56. 4
      openstack_dashboard/dashboards/admin/aggregates/views.py
  57. 10
      openstack_dashboard/dashboards/admin/aggregates/workflows.py
  58. 2
      openstack_dashboard/dashboards/admin/defaults/views.py
  59. 6
      openstack_dashboard/dashboards/admin/defaults/workflows.py
  60. 2
      openstack_dashboard/dashboards/admin/flavors/tables.py
  61. 4
      openstack_dashboard/dashboards/admin/flavors/workflows.py
  62. 2
      openstack_dashboard/dashboards/admin/floating_ips/forms.py
  63. 2
      openstack_dashboard/dashboards/admin/floating_ips/views.py
  64. 8
      openstack_dashboard/dashboards/admin/group_types/specs/views.py
  65. 2
      openstack_dashboard/dashboards/admin/group_types/views.py
  66. 2
      openstack_dashboard/dashboards/admin/hypervisors/compute/forms.py
  67. 2
      openstack_dashboard/dashboards/admin/hypervisors/compute/tables.py
  68. 12
      openstack_dashboard/dashboards/admin/hypervisors/compute/views.py
  69. 4
      openstack_dashboard/dashboards/admin/hypervisors/views.py
  70. 2
      openstack_dashboard/dashboards/admin/images/tables.py
  71. 2
      openstack_dashboard/dashboards/admin/images/views.py
  72. 8
      openstack_dashboard/dashboards/admin/info/tables.py
  73. 2
      openstack_dashboard/dashboards/admin/info/views.py
  74. 2
      openstack_dashboard/dashboards/admin/instances/forms.py
  75. 2
      openstack_dashboard/dashboards/admin/instances/tables.py
  76. 4
      openstack_dashboard/dashboards/admin/instances/views.py
  77. 2
      openstack_dashboard/dashboards/admin/metadata_defs/forms.py
  78. 6
      openstack_dashboard/dashboards/admin/metadata_defs/views.py
  79. 2
      openstack_dashboard/dashboards/admin/networks/agents/forms.py
  80. 4
      openstack_dashboard/dashboards/admin/networks/agents/views.py
  81. 4
      openstack_dashboard/dashboards/admin/networks/forms.py
  82. 4
      openstack_dashboard/dashboards/admin/networks/ports/views.py
  83. 4
      openstack_dashboard/dashboards/admin/networks/ports/workflows.py
  84. 9
      openstack_dashboard/dashboards/admin/networks/subnets/tables.py
  85. 2
      openstack_dashboard/dashboards/admin/networks/subnets/views.py
  86. 7
      openstack_dashboard/dashboards/admin/networks/tables.py
  87. 4
      openstack_dashboard/dashboards/admin/networks/views.py
  88. 18
      openstack_dashboard/dashboards/admin/networks/workflows.py
  89. 4
      openstack_dashboard/dashboards/admin/overview/views.py
  90. 6
      openstack_dashboard/dashboards/admin/rbac_policies/forms.py
  91. 2
      openstack_dashboard/dashboards/admin/rbac_policies/tabs.py
  92. 2
      openstack_dashboard/dashboards/admin/rbac_policies/views.py
  93. 2
      openstack_dashboard/dashboards/admin/routers/forms.py
  94. 8
      openstack_dashboard/dashboards/admin/routers/tests.py
  95. 4
      openstack_dashboard/dashboards/admin/routers/views.py
  96. 2
      openstack_dashboard/dashboards/admin/snapshots/forms.py
  97. 2
      openstack_dashboard/dashboards/admin/snapshots/tables.py
  98. 4
      openstack_dashboard/dashboards/admin/snapshots/views.py
  99. 2
      openstack_dashboard/dashboards/admin/trunks/panel.py
  100. 2
      openstack_dashboard/dashboards/admin/vg_snapshots/views.py

2
.pylintrc

@ -56,8 +56,6 @@ disable=
inconsistent-return-statements, # TODO
interface-not-implemented,
no-self-use,
# python3 way: Let's do it once we have a consensus.
super-with-arguments, # TODO
too-many-ancestors,
too-many-arguments,
too-many-branches,

7
horizon/base.py

@ -108,7 +108,7 @@ class HorizonComponent(object):
policy_rules = tuple()
def __init__(self):
super(HorizonComponent, self).__init__()
super().__init__()
if not self.slug:
raise ImproperlyConfigured('Every %s must have a slug.'
% self.__class__)
@ -476,7 +476,7 @@ class Dashboard(Registry, HorizonComponent):
return "<Dashboard: %s>" % self.slug
def __init__(self, *args, **kwargs):
super(Dashboard, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self._panel_groups = None
def get_panel(self, panel):
@ -1023,8 +1023,7 @@ class HorizonSite(Site):
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(HorizonSite, cls).__new__(cls,
*args, **kwargs)
cls._instance = super().__new__(cls, *args, **kwargs)
return cls._instance

2
horizon/browsers/base.py

@ -93,7 +93,7 @@ class ResourceBrowser(html.HTMLElement):
breadcrumb_url = None
def __init__(self, request, tables_dict=None, attrs=None, **kwargs):
super(ResourceBrowser, self).__init__()
super().__init__()
self.name = self.name or self.__class__.__name__
self.verbose_name = self.verbose_name or self.name.title()
self.request = request

2
horizon/browsers/breadcrumb.py

@ -20,7 +20,7 @@ from horizon.utils import html
class Breadcrumb(html.HTMLElement):
def __init__(self, request, template, root,
subfolder_path, url, attr=None):
super(Breadcrumb, self).__init__()
super().__init__()
self.template = template
self.request = request
self.root = root

10
horizon/browsers/views.py

@ -32,7 +32,7 @@ class ResourceBrowserView(MultiTableView):
self.table_classes = (self.browser_class.navigation_table_class,
self.browser_class.content_table_class)
self.navigation_selection = False
super(ResourceBrowserView, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
@memoized.memoized_method
def get_browser(self):
@ -45,7 +45,7 @@ class ResourceBrowserView(MultiTableView):
return browser
def get_tables(self):
tables = super(ResourceBrowserView, self).get_tables()
tables = super().get_tables()
# Tells the navigation table what is selected.
navigation_table = tables[
self.browser_class.navigation_table_class._meta.name]
@ -55,7 +55,7 @@ class ResourceBrowserView(MultiTableView):
return tables
def get_context_data(self, **kwargs):
context = super(ResourceBrowserView, self).get_context_data(**kwargs)
context = super().get_context_data(**kwargs)
browser = self.get_browser()
context["%s_browser" % browser.name] = browser
return context
@ -78,7 +78,7 @@ class AngularIndexView(generic.TemplateView):
page_title = None
def get_context_data(self, **kwargs):
context = super(AngularIndexView, self).get_context_data(**kwargs)
context = super().get_context_data(**kwargs)
context["title"] = self.title
context["csrf_http"] = settings.CSRF_COOKIE_HTTPONLY
if self.page_title is None:
@ -97,7 +97,7 @@ class AngularDetailsView(generic.TemplateView):
template_name = 'angular.html'
def get_context_data(self, **kwargs):
context = super(AngularDetailsView, self).get_context_data(**kwargs)
context = super().get_context_data(**kwargs)
# some parameters are needed for navigation side bar and breadcrumb.
title = _("Horizon")
context["title"] = title

2
horizon/contrib/staticfiles/finders.py

@ -22,7 +22,7 @@ class HorizonStaticFinder(AppDirectoriesFinder):
"""Static files finder that also looks into the directory of each panel."""
def __init__(self, app_names=None, *args, **kwargs):
super(HorizonStaticFinder, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
app_configs = apps.get_app_configs()
for app_config in app_configs:
if 'openstack_dashboard' in app_config.path:

2
horizon/exceptions.py

@ -108,7 +108,7 @@ class ServiceCatalogException(HorizonException):
"""
def __init__(self, service_name):
message = _('Invalid service catalog: %s') % service_name
super(ServiceCatalogException, self).__init__(message)
super().__init__(message)
class AlreadyExists(HorizonException):

4
horizon/forms/base.py

@ -26,7 +26,7 @@ class SelfHandlingMixin(object):
if not hasattr(self, "handle"):
raise NotImplementedError("%s does not define a handle method."
% self.__class__.__name__)
super(SelfHandlingMixin, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
class SelfHandlingForm(SelfHandlingMixin, forms.Form):
@ -56,6 +56,6 @@ class DateForm(forms.Form):
end = forms.DateField(input_formats=("%Y-%m-%d",))
def __init__(self, *args, **kwargs):
super(DateForm, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.fields['start'].widget.attrs['data-date-format'] = "yyyy-mm-dd"
self.fields['end'].widget.attrs['data-date-format'] = "yyyy-mm-dd"

31
horizon/forms/fields.py

@ -80,10 +80,10 @@ class IPField(fields.Field):
self.min_mask = kwargs.pop("mask_range_from", 0)
self.version = kwargs.pop('version', IPv4)
super(IPField, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
def validate(self, value):
super(IPField, self).validate(value)
super().validate(value)
if not value and not self.required:
return
@ -109,7 +109,7 @@ class IPField(fields.Field):
raise ValidationError(self.invalid_mask_message)
def clean(self, value):
super(IPField, self).clean(value)
super().clean(value)
return str(getattr(self, "ip", ""))
@ -120,13 +120,13 @@ class MultiIPField(IPField):
if value:
addresses = value.split(',')
for ip in addresses:
super(MultiIPField, self).validate(ip)
super().validate(ip)
self.addresses.append(ip)
else:
super(MultiIPField, self).validate(value)
super().validate(value)
def clean(self, value):
super(MultiIPField, self).clean(value)
super().clean(value)
return str(','.join(getattr(self, "addresses", [])))
@ -139,7 +139,7 @@ class MACAddressField(fields.Field):
.. xxxx.xxxx.xxxx
"""
def validate(self, value):
super(MACAddressField, self).validate(value)
super().validate(value)
if not value:
return
@ -153,7 +153,7 @@ class MACAddressField(fields.Field):
code="invalid_mac")
def clean(self, value):
super(MACAddressField, self).clean(value)
super().clean(value)
return str(getattr(self, "mac_address", ""))
@ -221,7 +221,7 @@ class SelectWidget(widgets.Widget):
self.data_attrs = data_attrs
self.transform = transform
self.transform_html_attrs = transform_html_attrs
super(SelectWidget, self).__init__(attrs)
super().__init__(attrs)
def render(self, name, value, attrs=None, renderer=None):
if value is None:
@ -356,7 +356,7 @@ class DynamicSelectWidget(SelectWidget):
add_item_url = self.get_add_item_url()
if add_item_url is not None:
self.attrs[self._data_add_url_attr] = add_item_url
return super(DynamicSelectWidget, self).render(*args, **kwargs)
return super().render(*args, **kwargs)
def get_add_item_url(self):
if callable(self.add_item_link):
@ -393,7 +393,7 @@ class DynamicChoiceField(fields.ChoiceField):
add_item_link_args=None,
*args,
**kwargs):
super(DynamicChoiceField, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.widget.add_item_link = add_item_link
self.widget.add_item_link_args = add_item_link_args
@ -425,7 +425,7 @@ class ThemableCheckboxInput(widgets.CheckboxInput):
return html.format_html(
u'<div class="themable-checkbox">{}<label for="{}"></label></div>',
super(ThemableCheckboxInput, self).render(name, value, attrs),
super().render(name, value, attrs),
label_for
)
@ -520,7 +520,7 @@ class ThemableCheckboxChoiceInput(ChoiceInput):
input_type = 'checkbox'
def __init__(self, *args, **kwargs):
super(ThemableCheckboxChoiceInput, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
# NOTE(e0ne): Django sets default value to None
if self.value:
self.value = set(force_text(v) for v in self.value)
@ -601,7 +601,7 @@ class ExternalFileField(fields.FileField):
paired with ExternalUploadMeta metaclass embedded into the Form class.
"""
def __init__(self, *args, **kwargs):
super(ExternalFileField, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.widget.attrs.update({'data-external-upload': 'true'})
@ -651,5 +651,4 @@ class ExternalUploadMeta(forms.DeclarativeFieldsMetaclass):
new_attrs[new_attr_name] = hidden_field
meth_name = 'clean_' + new_attr_name
new_attrs[meth_name] = make_clean_method(new_attr_name)
return super(ExternalUploadMeta, cls).__new__(
cls, name, bases, new_attrs)
return super().__new__(cls, name, bases, new_attrs)

8
horizon/forms/views.py

@ -46,13 +46,13 @@ class ModalBackdropMixin(object):
modal_backdrop = 'static'
def __init__(self, *args, **kwargs):
super(ModalBackdropMixin, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
config = settings.HORIZON_CONFIG
if 'modal_backdrop' in config:
self.modal_backdrop = config['modal_backdrop']
def get_context_data(self, **kwargs):
context = super(ModalBackdropMixin, self).get_context_data(**kwargs)
context = super().get_context_data(**kwargs)
context['modal_backdrop'] = self.modal_backdrop
return context
@ -73,7 +73,7 @@ class ModalFormMixin(ModalBackdropMixin):
return template
def get_context_data(self, **kwargs):
context = super(ModalFormMixin, self).get_context_data(**kwargs)
context = super().get_context_data(**kwargs)
if self.request.is_ajax():
context['hide'] = True
if ADD_TO_FIELD_HEADER in self.request.META:
@ -140,7 +140,7 @@ class ModalFormView(ModalFormMixin, views.HorizonFormView):
cancel_url = None
def get_context_data(self, **kwargs):
context = super(ModalFormView, self).get_context_data(**kwargs)
context = super().get_context_data(**kwargs)
context['modal_id'] = self.modal_id
context['modal_header'] = self.modal_header
context['form_id'] = self.form_id

2
horizon/management/commands/startdash.py

@ -59,7 +59,7 @@ class Command(TemplateCommand):
"Python module and cannot be used as an app "
"name. Please try another name." % dash_name)
super(Command, self).handle('dash', dash_name, **options)
super().handle('dash', dash_name, **options)
target = options.pop("target", None)
if not target:

2
horizon/management/commands/startpanel.py

@ -92,7 +92,7 @@ class Command(TemplateCommand):
"Python module and cannot be used as an app "
"name. Please try another name." % panel_name)
super(Command, self).handle('panel', panel_name, target, **options)
super().handle('panel', panel_name, target, **options)
if not target:
target = os.path.join(os.curdir, panel_name)

23
horizon/tables/actions.py

@ -76,8 +76,7 @@ class BaseActionMetaClass(type):
def __call__(cls, *args, **kwargs):
cls.base_options.update(kwargs)
# Adding cls.base_options to each init call.
klass = super(BaseActionMetaClass, cls).__call__(
*args, **cls.base_options)
klass = super().__call__(*args, **cls.base_options)
return klass
@ -85,7 +84,7 @@ class BaseAction(html.HTMLElement, metaclass=BaseActionMetaClass):
"""Common base class for all ``Action`` classes."""
def __init__(self, **kwargs):
super(BaseAction, self).__init__()
super().__init__()
self.datum = kwargs.get('datum', None)
self.table = kwargs.get('table', None)
self.handles_multiple = kwargs.get('handles_multiple', False)
@ -258,7 +257,7 @@ class Action(BaseAction):
def __init__(self, single_func=None, multiple_func=None, handle_func=None,
attrs=None, **kwargs):
super(Action, self).__init__(**kwargs)
super().__init__(**kwargs)
self.method = kwargs.get('method', "POST")
self.requires_input = kwargs.get('requires_input', True)
@ -344,7 +343,7 @@ class LinkAction(BaseAction):
ajax = False
def __init__(self, attrs=None, **kwargs):
super(LinkAction, self).__init__(**kwargs)
super().__init__(**kwargs)
self.method = kwargs.get('method', "GET")
self.bound_url = kwargs.get('bound_url', None)
self.name = kwargs.get('name', self.name)
@ -377,7 +376,7 @@ class LinkAction(BaseAction):
action_dict)
def associate_with_table(self, table):
super(LinkAction, self).associate_with_table(table)
super().associate_with_table(table)
if self.ajax:
self.attrs['data-update-url'] = self.get_ajax_update_url()
@ -468,7 +467,7 @@ class FilterAction(BaseAction):
name = "filter"
def __init__(self, **kwargs):
super(FilterAction, self).__init__(**kwargs)
super().__init__(**kwargs)
self.method = kwargs.get('method', "POST")
self.name = kwargs.get('name', self.name)
self.verbose_name = kwargs.get('verbose_name', _("Filter"))
@ -560,7 +559,7 @@ class FixedFilterAction(FilterAction):
"""A filter action with fixed buttons."""
def __init__(self, **kwargs):
super(FixedFilterAction, self).__init__(**kwargs)
super().__init__(**kwargs)
self.filter_type = kwargs.get('filter_type', "fixed")
self.needs_preloading = kwargs.get('needs_preloading', True)
@ -654,7 +653,7 @@ class BatchAction(Action):
default_message_level = "success"
def __init__(self, **kwargs):
super(BatchAction, self).__init__(**kwargs)
super().__init__(**kwargs)
action_present_method = callable(getattr(self, 'action_present', None))
action_past_method = callable(getattr(self, 'action_past', None))
@ -687,7 +686,7 @@ class BatchAction(Action):
action = request.GET.get('action')
if action != 'row_update' and not self.table.data and not datum:
return False
return super(BatchAction, self)._allowed(request, datum)
return super()._allowed(request, datum)
def _get_action_name(self, items=None, past=False):
"""Retreive action name based on the number of items and `past` flag.
@ -746,7 +745,7 @@ class BatchAction(Action):
def get_default_attrs(self):
"""Returns a list of the default HTML attributes for the action."""
attrs = super(BatchAction, self).get_default_attrs()
attrs = super().get_default_attrs()
attrs.update({'data-batch-action': 'true'})
return attrs
@ -869,7 +868,7 @@ class DeleteAction(BatchAction):
name = "delete"
def __init__(self, **kwargs):
super(DeleteAction, self).__init__(**kwargs)
super().__init__(**kwargs)
self.name = kwargs.get('name', self.name)
self.icon = "trash"
self.action_type = "danger"

10
horizon/tables/base.py

@ -305,7 +305,7 @@ class Column(html.HTMLElement):
allowed_data_types = allowed_data_types or []
self.classes = list(classes or getattr(self, "classes", []))
super(Column, self).__init__()
super().__init__()
self.attrs.update(attrs or {})
if callable(transform):
@ -478,7 +478,7 @@ class Column(html.HTMLElement):
if settings.INTEGRATION_TESTS_SUPPORT:
def get_default_attrs(self):
attrs = super(Column, self).get_default_attrs()
attrs = super().get_default_attrs()
attrs.update({'data-selenium': self.name})
return attrs
@ -510,7 +510,7 @@ class WrappingColumn(Column):
"""A column that wraps its contents. Useful for data like UUIDs or names"""
def __init__(self, *args, **kwargs):
super(WrappingColumn, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.classes.append('word-break')
@ -580,7 +580,7 @@ class Row(html.HTMLElement):
ajax_cell_action_name = "cell_update"
def __init__(self, table, datum=None):
super(Row, self).__init__()
super().__init__()
self.table = table
self.datum = datum
self.selected = False
@ -709,7 +709,7 @@ class Cell(html.HTMLElement):
def __init__(self, datum, column, row, attrs=None, classes=None):
self.classes = classes or getattr(self, "classes", [])
super(Cell, self).__init__()
super().__init__()
self.attrs.update(attrs or {})
self.datum = datum

8
horizon/tables/formset.py

@ -27,7 +27,7 @@ class FormsetCell(horizon_tables.Cell):
"""A DataTable cell that knows about its field from the formset."""
def __init__(self, *args, **kwargs):
super(FormsetCell, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
try:
self.field = (self.row.form or {})[self.column.name]
except KeyError:
@ -46,7 +46,7 @@ class FormsetRow(horizon_tables.Row):
def __init__(self, column, datum, form):
self.form = form
super(FormsetRow, self).__init__(column, datum)
super().__init__(column, datum)
if not self.cells:
# We need to be able to handle empty rows, because there may
# be extra empty forms in a formset. The original DataTable breaks
@ -72,7 +72,7 @@ class FormsetDataTableMixin(object):
formset_class = None
def __init__(self, *args, **kwargs):
super(FormsetDataTableMixin, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self._formset = None
# Override Meta settings, because we need custom Form and Cell classes,
@ -151,7 +151,7 @@ class FormsetDataTableMixin(object):
# We need to support ``None`` when there are more forms than data.
if datum is None:
return None
return super(FormsetDataTableMixin, self).get_object_id(datum)
return super().get_object_id(datum)
class FormsetDataTable(FormsetDataTableMixin, horizon_tables.DataTable):

14
horizon/tables/views.py

@ -26,7 +26,7 @@ class MultiTableMixin(object):
data_method_pattern = "get_%s_data"
def __init__(self, *args, **kwargs):
super(MultiTableMixin, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.table_classes = getattr(self, "table_classes", [])
self._data = {}
self._tables = {}
@ -102,7 +102,7 @@ class MultiTableMixin(object):
return self._tables
def get_context_data(self, **kwargs):
context = super(MultiTableMixin, self).get_context_data(**kwargs)
context = super().get_context_data(**kwargs)
tables = self.get_tables()
for name, table in tables.items():
context["%s_table" % name] = table
@ -274,7 +274,7 @@ class DataTableView(MultiTableView):
return self.table
def get_context_data(self, **kwargs):
context = super(DataTableView, self).get_context_data(**kwargs)
context = super().get_context_data(**kwargs)
if hasattr(self, "table"):
context[self.context_object_name] = self.table
return context
@ -354,7 +354,7 @@ class MixedDataTableView(DataTableView):
type_string)
def get_table(self):
self.table = super(MixedDataTableView, self).get_table()
self.table = super().get_table()
if not self.table._meta.mixed_data_type:
raise AttributeError('You must have at least two elements in '
'the data_types attribute '
@ -365,7 +365,7 @@ class MixedDataTableView(DataTableView):
class PagedTableMixin(object):
def __init__(self, *args, **kwargs):
super(PagedTableMixin, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self._has_prev_data = False
self._has_more_data = False
@ -391,7 +391,7 @@ class PagedTableMixin(object):
class PagedTableWithPageMenu(object):
def __init__(self, *args, **kwargs):
super(PagedTableWithPageMenu, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self._current_page = 1
self._number_of_pages = 0
self._total_of_entries = 0
@ -401,7 +401,7 @@ class PagedTableWithPageMenu(object):
name = table.name
self._tables[name]._meta.current_page = self.current_page
self._tables[name]._meta.number_of_pages = self.number_of_pages
return super(PagedTableWithPageMenu, self).handle_table(table)
return super().handle_table(table)
def has_prev_data(self, table):
return self._current_page > 1

12
horizon/tabs/base.py

@ -102,7 +102,7 @@ class TabGroup(html.HTMLElement):
return self._active
def __init__(self, request, **kwargs):
super(TabGroup, self).__init__()
super().__init__()
if not hasattr(self, "tabs"):
raise NotImplementedError('%s must declare a "tabs" attribute.'
% self.__class__)
@ -187,7 +187,7 @@ class TabGroup(html.HTMLElement):
Defaults to ``["nav", "nav-tabs", "ajax-tabs"]``.
"""
default_classes = super(TabGroup, self).get_default_classes()
default_classes = super().get_default_classes()
default_classes.extend(CSS_TAB_GROUP_CLASSES)
return default_classes
@ -309,7 +309,7 @@ class Tab(html.HTMLElement):
permissions = []
def __init__(self, tab_group, request=None):
super(Tab, self).__init__()
super().__init__()
# Priority: constructor, class-defined, fallback
if not self.name:
raise ValueError("%s must have a name." % self.__class__.__name__)
@ -393,7 +393,7 @@ class Tab(html.HTMLElement):
If the tab is not enabled, the classes the class ``"disabled"``
will be added.
"""
default_classes = super(Tab, self).get_default_classes()
default_classes = super().get_default_classes()
if self.is_active():
default_classes.extend(CSS_ACTIVE_TAB_CLASSES)
if not self._enabled:
@ -471,7 +471,7 @@ class TableTab(Tab):
table_classes = []
def __init__(self, tab_group, request):
super(TableTab, self).__init__(tab_group, request)
super().__init__(tab_group, request)
if not self.table_classes:
class_name = self.__class__.__name__
raise NotImplementedError("You must define a table_class "
@ -522,7 +522,7 @@ class TableTab(Tab):
If only one table class is provided, a shortcut ``table`` context
variable is also added containing the single table.
"""
context = super(TableTab, self).get_context_data(request, **kwargs)
context = super().get_context_data(request, **kwargs)
# If the data hasn't been manually loaded before now,
# make certain it's loaded before setting the context.
self.load_table_data()

4
horizon/tabs/views.py

@ -45,7 +45,7 @@ class TabView(views.HorizonTemplateView):
def get_context_data(self, **kwargs):
"""Adds the ``tab_group`` variable to the context data."""
context = super(TabView, self).get_context_data(**kwargs)
context = super().get_context_data(**kwargs)
try:
tab_group = self.get_tabs(self.request, **kwargs)
context["tab_group"] = tab_group
@ -73,7 +73,7 @@ class TabView(views.HorizonTemplateView):
class TabbedTableView(tables.MultiTableMixin, TabView):
def __init__(self, *args, **kwargs):
super(TabbedTableView, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.table_classes = []
self._table_dict = {}

2
horizon/test/firefox_binary.py

@ -82,7 +82,7 @@ class WebDriver(firefox.webdriver.WebDriver):
# called from WebDriver.__init__, retry __init__.
for i in range(self.CONNREFUSED_RETRY_COUNT + 1):
try:
super(WebDriver, self).__init__(
super().__init__(
firefox_profile, FirefoxBinary(), timeout,
desired_capabilities, proxy)
if i > 0:

18
horizon/test/helpers.py

@ -118,14 +118,14 @@ class SessionStore(SessionBase):
class RequestFactoryWithMessages(RequestFactory):
def get(self, *args, **kwargs):
req = super(RequestFactoryWithMessages, self).get(*args, **kwargs)
req = super().get(*args, **kwargs)
req.user = User()
req.session = SessionStore()
req._messages = default_storage(req)
return req
def post(self, *args, **kwargs):
req = super(RequestFactoryWithMessages, self).post(*args, **kwargs)
req = super().post(*args, **kwargs)
req.user = User()
req.session = SessionStore()
req._messages = default_storage(req)
@ -143,7 +143,7 @@ class TestCase(django_test.TestCase):
"""
def setUp(self):
super(TestCase, self).setUp()
super().setUp()
self._setup_test_data()
self._setup_factory()
self._setup_user()
@ -171,7 +171,7 @@ class TestCase(django_test.TestCase):
self.request.session = self.client.session
def tearDown(self):
super(TestCase, self).tearDown()
super().tearDown()
del os.environ["HORIZON_TEST_RUN"]
def set_permissions(self, permissions=None):
@ -250,7 +250,7 @@ class SeleniumTestCase(LiveServerTestCase):
cls.vdisplay = xvfbwrapper.Xvfb(width=1280, height=720)
cls.vdisplay.start()
cls.selenium = WebDriver()
super(SeleniumTestCase, cls).setUpClass()
super().setUpClass()
@classmethod
def tearDownClass(cls):
@ -259,13 +259,13 @@ class SeleniumTestCase(LiveServerTestCase):
time.sleep(1)
if hasattr(cls, 'vdisplay'):
cls.vdisplay.stop()
super(SeleniumTestCase, cls).tearDownClass()
super().tearDownClass()
def setUp(self):
socket.setdefaulttimeout(60)
self.selenium.implicitly_wait(30)
self.ui = selenium_ui
super(SeleniumTestCase, self).setUp()
super().setUp()
class JasmineTests(SeleniumTestCase):
@ -351,7 +351,7 @@ class update_settings(django_test_utils.override_settings):
copied = copy.copy(value)
copied.update(new_value)
kwargs[key] = copied
super(update_settings, self).__init__(**kwargs)
super().__init__(**kwargs)
class IsA(object):
@ -366,4 +366,4 @@ class IsA(object):
class IsHttpRequest(IsA):
"""Class to compare param is django.http.HttpRequest."""
def __init__(self):
super(IsHttpRequest, self).__init__(http.HttpRequest)
super().__init__(http.HttpRequest)

2
horizon/test/selenium/selenium_tests.py

@ -41,7 +41,7 @@ class LazyLoadedTabsTests(test.SeleniumTestCase):
select_all_selector = 'th.multi_select_column input[type=checkbox]'
def setUp(self):
super(LazyLoadedTabsTests, self).setUp()
super().setUp()
wait = self.ui.WebDriverWait(self.selenium, 120)
self.get_element = self.selenium.find_element_by_css_selector
self.get_elements = self.selenium.find_elements_by_css_selector

8
horizon/test/unit/forms/test_fields.py

@ -227,7 +227,7 @@ class ChoiceFieldForm(forms.SelfHandlingForm):
transform_html_attrs=title_dic.get))
def __init__(self, request, *args, **kwargs):
super(ChoiceFieldForm, self).__init__(request, *args, **kwargs)
super().__init__(request, *args, **kwargs)
choices = ([('choice1', 'label1'),
('choice2', 'label2')])
self.fields['test_choices'].choices = choices
@ -241,7 +241,7 @@ class ChoiceFieldTests(test.TestCase):
template = 'horizon/common/_form_fields.html'
def setUp(self):
super(ChoiceFieldTests, self).setUp()
super().setUp()
self.form = ChoiceFieldForm(self.request)
def _render_form(self):
@ -282,7 +282,7 @@ class ThemableChoiceFieldForm(forms.SelfHandlingForm):
transform_html_attrs=title_dic.get))
def __init__(self, request, *args, **kwargs):
super(ThemableChoiceFieldForm, self).__init__(request, *args, **kwargs)
super().__init__(request, *args, **kwargs)
choices = ([('choice1', 'label1'),
('choice2', 'label2')])
self.fields['test_choices'].choices = choices
@ -296,7 +296,7 @@ class ThemableChoiceFieldTests(test.TestCase):
template = 'horizon/common/_form_fields.html'
def setUp(self):
super(ThemableChoiceFieldTests, self).setUp()
super().setUp()
self.form = ThemableChoiceFieldForm(self.request)
def _render_form(self):

2
horizon/test/unit/forms/test_forms.py

@ -80,7 +80,7 @@ class FormErrorTests(test.TestCase):
template = 'horizon/common/_form_fields.html'
def setUp(self):
super(FormErrorTests, self).setUp()
super().setUp()
# Note(Itxaka): We pass data to the form so its bound and has the
# proper cleaned_data fields
self.form = FormForTesting(self.request, data={'fake': 'data'})

4
horizon/test/unit/middleware/test_base.py

@ -35,11 +35,11 @@ class MiddlewareTests(django_test.TestCase):
self._timezone_backup = timezone.get_current_timezone_name()
self.factory = test.RequestFactoryWithMessages()
self.get_response = mock.Mock()
super(MiddlewareTests, self).setUp()
super().setUp()
def tearDown(self):
timezone.activate(self._timezone_backup)
super(MiddlewareTests, self).tearDown()
super().tearDown()
def test_redirect_login_fail_to_login(self):
url = settings.LOGIN_URL

2
horizon/test/unit/middleware/test_operation_log.py

@ -33,7 +33,7 @@ class OperationLogMiddlewareTest(django_test.TestCase):
http_referer = u'/dashboard/test_http_referer'
def setUp(self):
super(OperationLogMiddlewareTest, self).setUp()
super().setUp()
self.factory = test.RequestFactoryWithMessages()
def test_middleware_not_used(self):

4
horizon/test/unit/tabs/test_tabs.py

@ -340,11 +340,11 @@ class TabTests(test.TestCase):
class TabExceptionTests(test.TestCase):
def setUp(self):
super(TabExceptionTests, self).setUp()
super().setUp()
self._original_tabs = copy.copy(TabWithTableView.tab_group_class.tabs)
def tearDown(self):
super(TabExceptionTests, self).tearDown()
super().tearDown()
TabWithTableView.tab_group_class.tabs = self._original_tabs
@override_settings(SESSION_REFRESH=False)

21
horizon/test/unit/test_base.py

@ -70,7 +70,7 @@ class RbacYesAccessPanel(horizon.Panel):
class BaseHorizonTests(test.TestCase):
def setUp(self):
super(BaseHorizonTests, self).setUp()
super().setUp()
# Adjust our horizon config and register our custom dashboards/panels.
self.old_default_dash = settings.HORIZON_CONFIG['default_dashboard']
settings.HORIZON_CONFIG['default_dashboard'] = 'cats'
@ -93,7 +93,7 @@ class BaseHorizonTests(test.TestCase):
self._discovered_panels[dash] = panels
def tearDown(self):
super(BaseHorizonTests, self).tearDown()
super().tearDown()
# Restore our settings
settings.HORIZON_CONFIG['default_dashboard'] = self.old_default_dash
settings.HORIZON_CONFIG['dashboards'] = self.old_dashboards
@ -349,12 +349,12 @@ class HorizonTests(BaseHorizonTests):
settings.SECURE_PROXY_SSL_HEADER = None
class GetUserHomeTests(BaseHorizonTests):
class GetUserHomeTests(test.TestCase):
"""Test get_user_home parameters."""
def setUp(self):
self.orig_user_home = settings.HORIZON_CONFIG['user_home']
super(BaseHorizonTests, self).setUp()
super().setUp()
self.original_username = "testname"
self.test_user = User()
self.test_user.username = self.original_username
@ -362,6 +362,7 @@ class GetUserHomeTests(BaseHorizonTests):
def tearDown(self):
settings.HORIZON_CONFIG['user_home'] = self.orig_user_home
conf.HORIZON_CONFIG._setup()
super().tearDown()
def test_using_callable(self):
def themable_user_fnc(user):
@ -399,7 +400,7 @@ class CustomPanelTests(BaseHorizonTests):
"""
def setUp(self):
super(CustomPanelTests, self).setUp()
super().setUp()
settings.HORIZON_CONFIG['customization_module'] = \
'horizon.test.customization.cust_test1'
# refresh config
@ -414,7 +415,7 @@ class CustomPanelTests(BaseHorizonTests):
self._discovered_dashboards.append(Dogs)
Dogs.register(Puppies)
Cats.register(Tigers)
super(CustomPanelTests, self).tearDown()
super().tearDown()
settings.HORIZON_CONFIG.pop('customization_module')
# refresh config
conf.HORIZON_CONFIG._setup()
@ -440,14 +441,14 @@ class CustomPermissionsTests(BaseHorizonTests):
'horizon.test.customization.cust_test2'
# refresh config
conf.HORIZON_CONFIG._setup()
super(CustomPermissionsTests, self).setUp()
super().setUp()
def tearDown(self):
# Restore permissions
dogs = horizon.get_dashboard("dogs")
puppies = dogs.get_panel("puppies")
puppies.permissions = tuple([])
super(CustomPermissionsTests, self).tearDown()
super().tearDown()
settings.HORIZON_CONFIG.pop('customization_module')
# refresh config
conf.HORIZON_CONFIG._setup()
@ -489,7 +490,7 @@ class CustomPermissionsTests(BaseHorizonTests):
class RbacHorizonTests(test.TestCase):
def setUp(self):
super(RbacHorizonTests, self).setUp()
super().setUp()
# Adjust our horizon config and register our custom dashboards/panels.
self.old_default_dash = settings.HORIZON_CONFIG['default_dashboard']
settings.HORIZON_CONFIG['default_dashboard'] = 'cats'
@ -513,7 +514,7 @@ class RbacHorizonTests(test.TestCase):
self._discovered_panels[dash] = panels
def tearDown(self):
super(RbacHorizonTests, self).tearDown()
super().tearDown()
# Restore our settings
settings.HORIZON_CONFIG['default_dashboard'] = self.old_default_dash
settings.HORIZON_CONFIG['dashboards'] = self.old_dashboards

4
horizon/test/unit/test_views.py

@ -28,7 +28,7 @@ class ViewData(object):
template_name = 'fake'
def get_context_data(self, **kwargs):
context = super(ViewData, self).get_context_data(**kwargs)
context = super().get_context_data(**kwargs)
context['object'] = {'name': 'myName'}
return context
@ -61,7 +61,7 @@ class ViewWithTransTitle(views.PageTitleMixin, generic.TemplateView):
class PageTitleTests(test.TestCase):
def setUp(self):
super(PageTitleTests, self).setUp()
super().setUp()
self.request = client.RequestFactory().get('fake')
def _dispatch(self, viewClass):

4
horizon/test/unit/workflows/test_workflows.py

@ -184,14 +184,14 @@ class FullscreenWorkflowView(workflows.WorkflowView):
class WorkflowsTests(test.TestCase):
def setUp(self):
super(WorkflowsTests, self).setUp()
super().setUp()
self.policy_patcher = mock.patch(
'openstack_auth.policy.check', lambda action, request: True)
self.policy_check = self.policy_patcher.start()
self.addCleanup(mock.patch.stopall)
def tearDown(self):
super(WorkflowsTests, self).tearDown()
super().tearDown()
self._reset_workflow()
def _reset_workflow(self):

2
horizon/test/utils.py

@ -23,4 +23,4 @@ class ObjDictWrapper(dict):
self[item] = value
def __repr__(self):
return '<ObjDictWrapper %s>' % super(ObjDictWrapper, self).__repr__()
return '<ObjDictWrapper %s>' % super().__repr__()

10
horizon/test/webdriver.py

@ -40,8 +40,7 @@ class WrapperFindOverride(object):
repeat = range(2)
for i in repeat:
try:
web_el = super(WrapperFindOverride, self).find_element(
by, value)
web_el = super().find_element(by, value)
except exceptions.NoSuchElementException:
if i == repeat[-1]:
raise
@ -52,8 +51,7 @@ class WrapperFindOverride(object):
repeat = range(2)
for i in repeat:
try:
web_els = super(WrapperFindOverride, self).find_elements(
by, value)
web_els = super().find_elements(by, value)
except exceptions.NoSuchElementException:
if i == repeat[-1]:
raise
@ -77,7 +75,7 @@ class WebElementWrapper(WrapperFindOverride, webelement.WebElement):
"""
def __init__(self, parent, id_, locator, src_element, index=None):
super(WebElementWrapper, self).__init__(parent, id_)
super().__init__(parent, id_)
self.locator = locator
self.src_element = src_element
# in case element was looked up previously via find_elements
@ -102,7 +100,7 @@ class WebElementWrapper(WrapperFindOverride, webelement.WebElement):
repeat = range(20)
for i in repeat:
try:
return super(WebElementWrapper, self)._execute(command, params)
return super()._execute(command, params)
except (exceptions.StaleElementReferenceException,
exceptions.ElementClickInterceptedException):
if i == repeat[-1]:

2
horizon/utils/babel_extract_angular.py

@ -54,7 +54,7 @@ class AngularGettextHTMLParser(parser.HTMLParser):
"""
def __init__(self):
super(AngularGettextHTMLParser, self).__init__(
super().__init__(
convert_charrefs=False
)

6
horizon/utils/csvbase.py

@ -29,7 +29,7 @@ class CsvDataMixin(object):
"""
def __init__(self):
self.out = io.StringIO()
super(CsvDataMixin, self).__init__()
super().__init__()
if hasattr(self, "columns"):
columns = [self.encode(col) for col in self.columns]
self.writer = csv.DictWriter(self.out, columns,
@ -65,7 +65,7 @@ class BaseCsvResponse(CsvDataMixin, HttpResponse):
"""Base CSV response class. Provides handling of CSV data."""
def __init__(self, request, template, context, content_type, **kwargs):
super(BaseCsvResponse, self).__init__()
super().__init__()
self['Content-Disposition'] = 'attachment; filename="%s"' % (
kwargs.get("filename", "export.csv"),)
self['Content-Type'] = content_type
@ -97,7 +97,7 @@ class BaseCsvStreamingResponse(CsvDataMixin, StreamingHttpResponse):
"""Base CSV Streaming class. Provides streaming response for CSV data."""
def __init__(self, request, template, context, content_type, **kwargs):
super(BaseCsvStreamingResponse, self).__init__()
super().__init__()
self['Content-Disposition'] = 'attachment; filename="%s"' % (
kwargs.get("filename", "export.csv"),)
self['Content-Type'] = content_type

2
horizon/utils/lazy_encoder.py

@ -22,4 +22,4 @@ class LazyTranslationEncoder(DjangoJSONEncoder):
def default(self, obj):
if isinstance(obj, Promise):
return force_text(obj)
return super(LazyTranslationEncoder, self).default(obj)
return super().default(obj)

2
horizon/utils/scss_filter.py

@ -23,7 +23,7 @@ from scss.types import String
class HorizonScssFilter(DjangoScssFilter):
def __init__(self, *args, **kwargs):
super(HorizonScssFilter, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.namespace = Namespace()

4
horizon/views.py

@ -68,7 +68,7 @@ class PageTitleMixin(object):
"""
context = self.render_context_with_title(context)
return super(PageTitleMixin, self).render_to_response(context)
return super().render_to_response(context)
def trace(name):
@ -83,7 +83,7 @@ def trace(name):
class HorizonTemplateView(PageTitleMixin, generic.TemplateView):
@trace('horizon.render_to_response')
def render_to_response(self, context):
return super(HorizonTemplateView, self).render_to_response(context)
return super().render_to_response(context)
class HorizonFormView(PageTitleMixin, generic.FormView):

16
horizon/workflows/base.py

@ -42,11 +42,11 @@ LOG = logging.getLogger(__name__)
class WorkflowContext(dict):
def __init__(self, workflow, *args, **kwargs):
super(WorkflowContext, self).__init__(*args,