Gate on H4xx docstrings for pep8

In an effort to help horizon more friendly to OpenStack hacking
guidelines, we now gate on H40* violations.

Change-Id: Id07294543660368d2f7f5ac363710176ab23b874
Signed-off-by: Paul Belanger <paul.belanger@polybeacon.com>
This commit is contained in:
Paul Belanger 2013-11-01 14:02:41 -04:00
parent 94129baebb
commit da8c69afa6
76 changed files with 411 additions and 577 deletions

View File

@ -390,15 +390,13 @@ class Dashboard(Registry, HorizonComponent):
self._panel_groups = None
def get_panel(self, panel):
"""
Returns the specified :class:`~horizon.Panel` instance registered
"""Returns the specified :class:`~horizon.Panel` instance registered
with this dashboard.
"""
return self._registered(panel)
def get_panels(self):
"""
Returns the :class:`~horizon.Panel` instances registered with this
"""Returns the :class:`~horizon.Panel` instances registered with this
dashboard in order, without any panel groupings.
"""
all_panels = []
@ -787,8 +785,7 @@ class Site(Registry, HorizonComponent):
class HorizonSite(Site):
"""
A singleton implementation of Site such that all dealings with horizon
"""A singleton implementation of Site such that all dealings with horizon
get the same instance no matter what. There can be only one.
"""
_instance = None

View File

@ -121,9 +121,8 @@ class ResourceBrowser(html.HTMLElement):
% (attr_name, self.__class__.__name__))
def set_tables(self, tables):
"""
Sets the table instances on the browser from a dictionary mapping table
names to table instances (as constructed by MultiTableView).
"""Sets the table instances on the browser from a dictionary mapping
table names to table instances (as constructed by MultiTableView).
"""
self.navigation_table = tables[self.navigation_table_class._meta.name]
self.content_table = tables[self.content_table_class._meta.name]

View File

@ -43,8 +43,7 @@ class HorizonReporterFilter(SafeExceptionReporterFilter):
# TODO(gabriel): This bugfix is cribbed from Django's code. When 1.4.1
# is available we can remove this code.
def get_traceback_frame_variables(self, request, tb_frame):
"""
Replaces the values of variables marked as sensitive with
"""Replaces the values of variables marked as sensitive with
stars (*********).
"""
# Loop through the frame's callers to see if the sensitive_variables
@ -98,8 +97,7 @@ class HorizonException(Exception):
class Http302(HorizonException):
"""
Error class which can be raised from within a handler to cause an
"""Error class which can be raised from within a handler to cause an
early bailout and redirect at the middleware level.
"""
status_code = 302
@ -110,8 +108,7 @@ class Http302(HorizonException):
class NotAuthorized(HorizonException):
"""
Raised whenever a user attempts to access a resource which they do not
"""Raised whenever a user attempts to access a resource which they do not
have permission-based access to (such as when failing the
:func:`~horizon.decorators.require_perms` decorator).
@ -123,8 +120,8 @@ class NotAuthorized(HorizonException):
class NotAuthenticated(HorizonException):
"""
Raised when a user is trying to make requests and they are not logged in.
"""Raised when a user is trying to make requests and they are not logged
in.
The included :class:`~horizon.middleware.HorizonMiddleware` catches
``NotAuthenticated`` and handles it gracefully by displaying an error
@ -144,9 +141,8 @@ class RecoverableError(HorizonException):
class ServiceCatalogException(HorizonException):
"""
Raised when a requested service is not available in the ``ServiceCatalog``
returned by Keystone.
"""Raised when a requested service is not available in the
``ServiceCatalog`` returned by Keystone.
"""
def __init__(self, service_name):
message = 'Invalid service catalog service: %s' % service_name
@ -154,8 +150,7 @@ class ServiceCatalogException(HorizonException):
class AlreadyExists(HorizonException):
"""
Exception to be raised when trying to create an API resource which
"""Exception to be raised when trying to create an API resource which
already exists.
"""
def __init__(self, name, resource_type):
@ -178,16 +173,14 @@ class WorkflowError(HorizonException):
class WorkflowValidationError(HorizonException):
"""
Exception raised during workflow validation if required data is missing,
"""Exception raised during workflow validation if required data is missing,
or existing data is not valid.
"""
pass
class HandledException(HorizonException):
"""
Used internally to track exceptions that have gone through
"""Used internally to track exceptions that have gone through
:func:`horizon.exceptions.handle` more than once.
"""
def __init__(self, wrapped):
@ -205,8 +198,7 @@ def error_color(msg):
def check_message(keywords, message):
"""
Checks an exception for given keywords and raises a new ``ActionError``
"""Checks an exception for given keywords and raises a new ``ActionError``
with the desired message if the keywords are found. This allows selective
control over API error messages.
"""

View File

@ -32,15 +32,13 @@ class SelfHandlingMixin(object):
class SelfHandlingForm(SelfHandlingMixin, forms.Form):
"""
A base :class:`Form <django:django.forms.Form>` class which includes
"""A base :class:`Form <django:django.forms.Form>` class which includes
processing logic in its subclasses.
"""
required_css_class = 'required'
def api_error(self, message):
"""
Adds an error to the form's error dictionary after validation
"""Adds an error to the form's error dictionary after validation
based on problems reported via the API. This is useful when you
wish for API errors to appear as errors on the form rather than
using the messages framework.

View File

@ -20,9 +20,8 @@ from django.forms import widgets
class DynamicSelectWidget(widgets.Select):
"""
A subclass of the ``Select`` widget which renders extra attributes for use
in callbacks to handle dynamic changes to the available choices.
"""A subclass of the ``Select`` widget which renders extra attributes for
use in callbacks to handle dynamic changes to the available choices.
"""
_data_add_url_attr = "data-add-item-url"
@ -46,8 +45,7 @@ class DynamicSelectWidget(widgets.Select):
class DynamicChoiceField(fields.ChoiceField):
"""
A subclass of ``ChoiceField`` with additional properties that make
"""A subclass of ``ChoiceField`` with additional properties that make
dynamically updating its elements easier.
Notably, the field declaration takes an extra argument, ``add_item_link``

View File

@ -49,8 +49,7 @@ class ModalFormMixin(object):
class ModalFormView(ModalFormMixin, generic.FormView):
"""
The main view class from which all views which handle forms in Horizon
"""The main view class from which all views which handle forms in Horizon
should inherit. It takes care of all details with processing
:class:`~horizon.forms.base.SelfHandlingForm` classes, and modal concerns
when the associated template inherits from
@ -65,25 +64,21 @@ class ModalFormView(ModalFormMixin, generic.FormView):
"""
def get_object_id(self, obj):
"""
For dynamic insertion of resources created in modals, this method
"""For dynamic insertion of resources created in modals, this method
returns the id of the created object. Defaults to returning the ``id``
attribute.
"""
return obj.id
def get_object_display(self, obj):
"""
For dynamic insertion of resources created in modals, this method
"""For dynamic insertion of resources created in modals, this method
returns the display name of the created object. Defaults to returning
the ``name`` attribute.
"""
return obj.name
def get_form(self, form_class):
"""
Returns an instance of the form to be used in this view.
"""
"""Returns an instance of the form to be used in this view."""
return form_class(self.request, **self.get_form_kwargs())
def form_valid(self, form):

View File

@ -26,9 +26,7 @@ from django.utils.safestring import SafeData # noqa
def add_message(request, level, message, extra_tags='', fail_silently=False):
"""
Attempts to add a message to the request using the 'messages' app.
"""
"""Attempts to add a message to the request using the 'messages' app."""
if request.is_ajax():
tag = constants.DEFAULT_TAGS[level]
# if message is marked as safe, pass "safe" tag as extra_tags so that
@ -44,40 +42,30 @@ def add_message(request, level, message, extra_tags='', fail_silently=False):
def debug(request, message, extra_tags='', fail_silently=False):
"""
Adds a message with the ``DEBUG`` level.
"""
"""Adds a message with the ``DEBUG`` level."""
add_message(request, constants.DEBUG, message, extra_tags=extra_tags,
fail_silently=fail_silently)
def info(request, message, extra_tags='', fail_silently=False):
"""
Adds a message with the ``INFO`` level.
"""
"""Adds a message with the ``INFO`` level."""
add_message(request, constants.INFO, message, extra_tags=extra_tags,
fail_silently=fail_silently)
def success(request, message, extra_tags='', fail_silently=False):
"""
Adds a message with the ``SUCCESS`` level.
"""
"""Adds a message with the ``SUCCESS`` level."""
add_message(request, constants.SUCCESS, message, extra_tags=extra_tags,
fail_silently=fail_silently)
def warning(request, message, extra_tags='', fail_silently=False):
"""
Adds a message with the ``WARNING`` level.
"""
"""Adds a message with the ``WARNING`` level."""
add_message(request, constants.WARNING, message, extra_tags=extra_tags,
fail_silently=fail_silently)
def error(request, message, extra_tags='', fail_silently=False):
"""
Adds a message with the ``ERROR`` level.
"""
"""Adds a message with the ``ERROR`` level."""
add_message(request, constants.ERROR, message, extra_tags=extra_tags,
fail_silently=fail_silently)

View File

@ -75,8 +75,7 @@ class HorizonMiddleware(object):
request.session['last_activity'] = timestamp
def process_exception(self, request, exception):
"""
Catches internal Horizon exception classes such as NotAuthorized,
"""Catches internal Horizon exception classes such as NotAuthorized,
NotFound and Http302 and handles them gracefully.
"""
if isinstance(exception, (exceptions.NotAuthorized,
@ -108,8 +107,7 @@ class HorizonMiddleware(object):
return shortcuts.redirect(exception.location)
def process_response(self, request, response):
"""
Convert HttpResponseRedirect to HttpResponse if request is via ajax
"""Convert HttpResponseRedirect to HttpResponse if request is via ajax
to allow ajax request to redirect url
"""
if request.is_ajax() and hasattr(request, 'horizon'):

View File

@ -101,16 +101,14 @@ class BaseAction(html.HTMLElement):
pass
def get_default_classes(self):
"""
Returns a list of the default classes for the action. Defaults to
"""Returns a list of the default classes for the action. Defaults to
``["btn", "btn-small"]``.
"""
return getattr(settings, "ACTION_CSS_CLASSES", ACTION_CSS_CLASSES)
def get_default_attrs(self):
"""
Returns a list of the default HTML attributes for the action. Defaults
to returning an ``id`` attribute with the value
"""Returns a list of the default HTML attributes for the action.
Defaults to returning an ``id`` attribute with the value
``{{ table.name }}__action_{{ action.name }}__{{ creation counter }}``.
"""
if self.datum is not None:
@ -434,8 +432,7 @@ class FilterAction(BaseAction):
class FixedFilterAction(FilterAction):
""" A filter action with fixed buttons.
"""
"""A filter action with fixed buttons."""
filter_type = 'fixed'
needs_preloading = True
@ -543,8 +540,7 @@ class BatchAction(Action):
return super(BatchAction, self)._allowed(request, datum)
def _conjugate(self, items=None, past=False):
"""
Builds combinations like 'Delete Object' and 'Deleted
"""Builds combinations like 'Delete Object' and 'Deleted
Objects' based on the number of items and `past` flag.
"""
action_type = "past" if past else "present"
@ -565,8 +561,8 @@ class BatchAction(Action):
return msgstr % {'action': action, 'data_type': data_type}
def action(self, request, datum_id):
"""
Required. Accepts a single object id and performs the specific action.
"""Required. Accepts a single object id and performs the specific
action.
Return values are discarded, errors raised are caught and logged.
"""
@ -574,17 +570,13 @@ class BatchAction(Action):
'BatchAction: %s' % self.data_type_singular)
def update(self, request, datum):
"""
Switches the action verbose name, if needed
"""
"""Switches the action verbose name, if needed."""
if getattr(self, 'action_present', False):
self.verbose_name = self._conjugate()
self.verbose_name_plural = self._conjugate('plural')
def get_success_url(self, request=None):
"""
Returns the URL to redirect to after a successful action.
"""
"""Returns the URL to redirect to after a successful action."""
if self.success_url:
return self.success_url
return request.get_full_path()

View File

@ -270,10 +270,9 @@ class Column(html.HTMLElement):
return '<%s: %s>' % (self.__class__.__name__, self.name)
def get_raw_data(self, datum):
"""
Returns the raw data for this column, before any filters or formatting
are applied to it. This is useful when doing calculations on data in
the table.
"""Returns the raw data for this column, before any filters or
formatting are applied to it. This is useful when doing calculations
on data in the table.
"""
# Callable transformations
if callable(self.transform):
@ -295,8 +294,8 @@ class Column(html.HTMLElement):
return data
def get_data(self, datum):
"""
Returns the final display data for this column from the given inputs.
"""Returns the final display data for this column from the given
inputs.
The return value will be either the attribute specified for this column
or the return value of the attr:`~horizon.tables.Column.transform`
@ -355,8 +354,7 @@ class Column(html.HTMLElement):
return self.link
def get_summation(self):
"""
Returns the summary value for the data in this column if a
"""Returns the summary value for the data in this column if a
valid summation method is specified for it. Otherwise returns ``None``.
"""
if self.summation not in self.summation_methods:
@ -444,8 +442,7 @@ class Row(html.HTMLElement):
self.cells = []
def load_cells(self, datum=None):
"""
Load the row's data (either provided at initialization or as an
"""Load the row's data (either provided at initialization or as an
argument to this function), initiailize all the cells contained
by this row, and set the appropriate row properties which require
the row's data to be determined.
@ -537,8 +534,7 @@ class Row(html.HTMLElement):
return "%s?%s" % (table_url, params)
def get_data(self, request, obj_id):
"""
Fetches the updated data for the row based on the object id
"""Fetches the updated data for the row based on the object id
passed in. Must be implemented by a subclass to allow AJAX updating.
"""
raise NotImplementedError("You must define a get_data method on %s"
@ -565,8 +561,7 @@ class Cell(html.HTMLElement):
@property
def value(self):
"""
Returns a formatted version of the data for final output.
"""Returns a formatted version of the data for final output.
This takes into consideration the
:attr:`~horizon.tables.Column.link`` and
@ -1041,8 +1036,7 @@ class DataTable(object):
return self._no_data_message
def get_object_by_id(self, lookup):
"""
Returns the data object from the table's dataset which matches
"""Returns the data object from the table's dataset which matches
the ``lookup`` parameter specified. An error will be raised if
the match is not a single data object.
@ -1071,8 +1065,7 @@ class DataTable(object):
@property
def has_actions(self):
"""
Boolean. Indicates whether there are any available actions on this
"""Boolean. Indicates whether there are any available actions on this
table.
"""
if not self.base_actions:
@ -1081,8 +1074,7 @@ class DataTable(object):
@property
def needs_form_wrapper(self):
"""
Boolean. Indicates whather this table should be rendered wrapped in
"""Boolean. Indicates whather this table should be rendered wrapped in
a ``<form>`` tag or not.
"""
# If needs_form_wrapper is explicitly set, defer to that.
@ -1132,9 +1124,9 @@ class DataTable(object):
return table_actions_template.render(context)
def render_row_actions(self, datum):
"""Renders the actions specified in ``Meta.row_actions`` using the
current row data.
"""
Renders the actions specified in ``Meta.row_actions`` using the
current row data. """
template_path = self._meta.row_actions_template
row_actions_template = template.loader.get_template(template_path)
bound_actions = self.get_row_actions(datum)
@ -1145,8 +1137,7 @@ class DataTable(object):
@staticmethod
def parse_action(action_string):
"""
Parses the ``action`` parameter (a string) sent back with the
"""Parses the ``action`` parameter (a string) sent back with the
POST data. By default this parses a string formatted as
``{{ table_name }}__{{ action_name }}__{{ row_id }}`` and returns
each of the pieces. The ``row_id`` is optional.
@ -1163,8 +1154,7 @@ class DataTable(object):
return table, action, object_id
def take_action(self, action_name, obj_id=None, obj_ids=None):
"""
Locates the appropriate action and routes the object
"""Locates the appropriate action and routes the object
data to it. The action should return an HTTP redirect
if successful, or a value which evaluates to ``False``
if unsuccessful.
@ -1212,9 +1202,8 @@ class DataTable(object):
return table, action, obj_id
def maybe_preempt(self):
"""
Determine whether the request should be handled by a preemptive action
on this table or by an AJAX row update before loading any data.
"""Determine whether the request should be handled by a preemptive
action on this table or by an AJAX row update before loading any data.
"""
request = self.request
table_name, action_name, obj_id = self.check_handler(request)
@ -1247,9 +1236,8 @@ class DataTable(object):
return None
def maybe_handle(self):
"""
Determine whether the request should be handled by any action on this
table after data has been loaded.
"""Determine whether the request should be handled by any action on
this table after data has been loaded.
"""
request = self.request
table_name, action_name, obj_id = self.check_handler(request)
@ -1291,8 +1279,7 @@ class DataTable(object):
return None
def has_more_data(self):
"""
Returns a boolean value indicating whether there is more data
"""Returns a boolean value indicating whether there is more data
available to this table from the source (generally an API).
The method is largely meant for internal use, but if you want to
@ -1301,8 +1288,7 @@ class DataTable(object):
return self._meta.has_more_data
def get_marker(self):
"""
Returns the identifier for the last object in the current data set
"""Returns the identifier for the last object in the current data set
for APIs that use marker/limit-based paging.
"""
return http.urlquote_plus(self.get_object_id(self.data[-1]))
@ -1312,8 +1298,7 @@ class DataTable(object):
return "=".join([self._meta.pagination_param, self.get_marker()])
def calculate_row_status(self, statuses):
"""
Returns a boolean value determining the overall row status
"""Returns a boolean value determining the overall row status
based on the dictionary of column name to status mappings passed in.
By default, it uses the following logic:
@ -1339,8 +1324,7 @@ class DataTable(object):
return True
def get_row_status_class(self, status):
"""
Returns a css class name determined by the status value. This class
"""Returns a css class name determined by the status value. This class
name is used to indicate the status of the rows in the table if
any ``status_columns`` have been specified.
"""

View File

@ -123,8 +123,7 @@ class MultiTableMixin(object):
class MultiTableView(MultiTableMixin, generic.TemplateView):
"""
A class-based generic view to handle the display and processing of
"""A class-based generic view to handle the display and processing of
multiple :class:`~horizon.tables.DataTable` classes in a single view.
Three steps are required to use this view: set the ``table_classes``

View File

@ -30,8 +30,7 @@ CSS_DISABLED_TAB_CLASSES = ["disabled"]
class TabGroup(html.HTMLElement):
"""
A container class which knows how to manage and render
"""A container class which knows how to manage and render
:class:`~horizon.tabs.Tab` objects.
.. attribute:: slug
@ -110,9 +109,7 @@ class TabGroup(html.HTMLElement):
return "<%s: %s>" % (self.__class__.__name__, self.slug)
def load_tab_data(self):
"""
Preload all data that for the tabs that will be displayed.
"""
"""Preload all data that for the tabs that will be displayed."""
for tab in self._tabs.values():
if tab.load and not tab.data_loaded:
try:
@ -122,15 +119,13 @@ class TabGroup(html.HTMLElement):
exceptions.handle(self.request)
def get_id(self):
"""
Returns the id for this tab group. Defaults to the value of the tab
"""Returns the id for this tab group. Defaults to the value of the tab
group's :attr:`horizon.tabs.Tab.slug`.
"""
return self.slug
def get_default_classes(self):
"""
Returns a list of the default classes for the tab group. Defaults to
"""Returns a list of the default classes for the tab group. Defaults to
``["nav", "nav-tabs", "ajax-tabs"]``.
"""
default_classes = super(TabGroup, self).get_default_classes()
@ -138,8 +133,7 @@ class TabGroup(html.HTMLElement):
return default_classes
def tabs_not_available(self):
"""
In the event that no tabs are either allowed or enabled, this method
"""In the event that no tabs are either allowed or enabled, this method
is the fallback handler. By default it's a no-op, but it exists
to make redirecting or raising exceptions possible for subclasses.
"""
@ -208,8 +202,7 @@ class TabGroup(html.HTMLElement):
class Tab(html.HTMLElement):
"""
A reusable interface for constructing a tab within a
"""A reusable interface for constructing a tab within a
:class:`~horizon.tabs.TabGroup`.
.. attribute:: name
@ -286,8 +279,7 @@ class Tab(html.HTMLElement):
return getattr(self, "_data", None) is not None
def render(self):
"""
Renders the tab to HTML using the
"""Renders the tab to HTML using the
:meth:`~horizon.tabs.Tab.get_context_data` method and
the :meth:`~horizon.tabs.Tab.get_template_name` method.
@ -309,8 +301,7 @@ class Tab(html.HTMLElement):
return render_to_string(self.get_template_name(self.request), context)
def get_id(self):
"""
Returns the id for this tab. Defaults to
"""Returns the id for this tab. Defaults to
``"{{ tab_group.slug }}__{{ tab.slug }}"``.
"""
return SEPARATOR.join([self.tab_group.slug, self.slug])
@ -319,8 +310,7 @@ class Tab(html.HTMLElement):
return "=".join((self.tab_group.param_name, self.get_id()))
def get_default_classes(self):
"""
Returns a list of the default classes for the tab. Defaults to
"""Returns a list of the default classes for the tab. Defaults to
and empty list (``[]``), however additional classes may be added
depending on the state of the tab as follows:
@ -338,8 +328,7 @@ class Tab(html.HTMLElement):
return default_classes
def get_template_name(self, request):
"""
Returns the name of the template to be used for rendering this tab.
"""Returns the name of the template to be used for rendering this tab.
By default it returns the value of the ``template_name`` attribute
on the ``Tab`` class.
@ -351,16 +340,14 @@ class Tab(html.HTMLElement):
return self.template_name
def get_context_data(self, request):
"""
This method should return a dictionary of context data used to render
the tab. Required.
"""This method should return a dictionary of context data used to
render the tab. Required.
"""
raise NotImplementedError("%s needs to define a get_context_data "
"method." % self.__class__.__name__)
def enabled(self, request):
"""
Determines whether or not the tab should be accessible
"""Determines whether or not the tab should be accessible
(e.g. be rendered into the HTML on load and respond to a click event).
If a tab returns ``False`` from ``enabled`` it will ignore the value
@ -371,8 +358,7 @@ class Tab(html.HTMLElement):
return True
def allowed(self, request):
"""
Determines whether or not the tab is displayed.
"""Determines whether or not the tab is displayed.
Tab instances can override this method to specify conditions under
which this tab should not be shown at all by returning ``False``.
@ -382,8 +368,7 @@ class Tab(html.HTMLElement):
return True
def post(self, request, *args, **kwargs):
"""
Handles POST data sent to a tab.
"""Handles POST data sent to a tab.
Tab instances can override this method to have tab-specific POST logic
without polluting the TabView code.
@ -394,8 +379,7 @@ class Tab(html.HTMLElement):
class TableTab(Tab):
"""
A :class:`~horizon.tabs.Tab` class which knows how to deal with
"""A :class:`~horizon.tabs.Tab` class which knows how to deal with
:class:`~horizon.tables.DataTable` classes rendered inside of it.
This distinct class is required due to the complexity involved in handling
@ -427,8 +411,7 @@ class TableTab(Tab):
self._table_data_loaded = False
def load_table_data(self):
"""
Calls the ``get_{{ table_name }}_data`` methods for each table class
"""Calls the ``get_{{ table_name }}_data`` methods for each table class
and sets the data on the tables.
"""
# We only want the data to be loaded once, so we track if we have...
@ -448,8 +431,7 @@ class TableTab(Tab):
self._table_data_loaded = True
def get_context_data(self, request):
"""
Adds a ``{{ table_name }}_table`` item to the context for each table
"""Adds a ``{{ table_name }}_table`` item to the context for each table
in the :attr:`~horizon.tabs.TableTab.table_classes` attribute.
If only one table class is provided, a shortcut ``table`` context

View File

@ -19,8 +19,8 @@ from horizon.tabs.base import TableTab # noqa
class TabView(generic.TemplateView):
"""
A generic class-based view for displaying a :class:`horizon.tabs.TabGroup`.
"""A generic class-based view for displaying a
:class:`horizon.tabs.TabGroup`.
This view handles selecting specific tabs and deals with AJAX requests
gracefully.
@ -57,8 +57,7 @@ class TabView(generic.TemplateView):
return context
def handle_tabbed_response(self, tab_group, context):
"""
Sends back an AJAX-appropriate response for the tab group if
"""Sends back an AJAX-appropriate response for the tab group if
required, otherwise renders the response as normal.
"""
if self.request.is_ajax():
@ -90,8 +89,7 @@ class TabbedTableView(tables.MultiTableMixin, TabView):
self._table_dict = {}
def load_tabs(self):
"""
Loads the tab group, and compiles the table instances for each
"""Loads the tab group, and compiles the table instances for each
table attached to any :class:`horizon.tabs.TableTab` instances on
the tab group. This step is necessary before processing any
tab or table actions.
@ -111,8 +109,7 @@ class TabbedTableView(tables.MultiTableMixin, TabView):
return {}
def handle_table(self, table_dict):
"""
For the given dict containing a ``DataTable`` and a ``TableTab``
"""For the given dict containing a ``DataTable`` and a ``TableTab``
instance, it loads the table data for that tab and calls the
table's :meth:`~horizon.tables.DataTable.maybe_handle` method. The
return value will be the result of ``maybe_handle``.

View File

@ -30,8 +30,7 @@ register = template.Library()
@register.filter
def has_permissions(user, component):
"""
Checks if the given user meets the permissions requirements for
"""Checks if the given user meets the permissions requirements for
the component.
"""
return user.has_perms(getattr(component, 'permissions', set()))
@ -111,8 +110,7 @@ class JSTemplateNode(template.Node):
@register.tag
def jstemplate(parser, token):
"""
Replaces ``[[[`` and ``]]]`` with ``{{{`` and ``}}}``,
"""Replaces ``[[[`` and ``]]]`` with ``{{{`` and ``}}}``,
``[[`` and ``]]`` with ``{{`` and ``}}`` and
``[%`` and ``%]`` with ``{%`` and ``%}`` to avoid conflicts
with Django's template engine when using any of the Mustache-based

View File

@ -32,8 +32,8 @@ register = template.Library()
class ParseDateNode(template.Node):
def render(self, datestring):
"""
Parses a date-like input string into a timezone aware Python datetime.
"""Parses a date-like input string into a timezone aware Python
datetime.
"""
formats = ["%Y-%m-%dT%H:%M:%S.%f", "%Y-%m-%d %H:%M:%S.%f",
"%Y-%m-%dT%H:%M:%S", "%Y-%m-%d %H:%M:%S"]

View File

@ -74,7 +74,8 @@ def mbformat(mb):
@register.filter(name='mb_float_format')
def mb_float_format(mb):
"""Takes a size value in mb, and prints returns the data in a
saner unit. """
saner unit.
"""
if not mb:
return 0
return filesizeformat(mb * 1024 * 1024, float_format)

View File

@ -75,8 +75,7 @@ class RequestFactoryWithMessages(RequestFactory):
@unittest.skipIf(os.environ.get('SKIP_UNITTESTS', False),
"The SKIP_UNITTESTS env variable is set.")
class TestCase(django_test.TestCase):
"""
Specialized base test case class for Horizon which gives access to
"""Specialized base test case class for Horizon which gives access to
numerous additional features:
* The ``mox`` mocking framework via ``self.mox``.
@ -115,15 +114,13 @@ class TestCase(django_test.TestCase):
del self.user._perm_cache
def assertNoMessages(self, response=None):
"""
Asserts that no messages have been attached by the ``contrib.messages``
framework.
"""Asserts that no messages have been attached by the
``contrib.messages`` framework.
"""
self.assertMessageCount(response, success=0, warn=0, info=0, error=0)
def assertMessageCount(self, response=None, **kwargs):
"""
Asserts that the specified number of messages have been attached
"""Asserts that the specified number of messages have been attached
for various message types. Usage would look like
``self.assertMessageCount(success=1)``.
"""

View File

@ -102,12 +102,11 @@ class BaseHorizonTests(test.TestCase):
dash.register(panel)
def _reload_urls(self):
'''
Clears out the URL caches, reloads the root urls module, and
"""Clears out the URL caches, reloads the root urls module, and
re-triggers the autodiscovery mechanism for Horizon. Allows URLs
to be re-calculated after registering new dashboards. Useful
only for testing and should never be used on a live site.
'''
"""
urlresolvers.clear_url_caches()
reload(import_module(settings.ROOT_URLCONF))
base.Horizon._urls()

View File

@ -29,22 +29,22 @@ from horizon.test import helpers as test
def single_line(text):
''' Quick utility to make comparing template output easier. '''
"""Quick utility to make comparing template output easier."""
return re.sub(' +',
' ',
normalize_newlines(text).replace('\n', '')).strip()
class TemplateTagTests(test.TestCase):
'''Test Custom Template Tag'''
"""Test Custom Template Tag."""
def render_template_tag(self, tag_name, tag_require=''):
'''Render a Custom Template Tag to string'''
"""Render a Custom Template Tag to string."""
template = Template("{%% load %s %%}{%% %s %%}"
% (tag_require, tag_name))
return template.render(Context())
def test_site_branding_tag(self):
'''Test if site_branding tag renders the correct setting'''
"""Test if site_branding tag renders the correct setting."""
rendered_str = self.render_template_tag("site_branding", "branding")
self.assertEqual(settings.SITE_BRANDING, rendered_str.strip(),
"tag site_branding renders %s" % rendered_str.strip())

View File

@ -27,8 +27,7 @@ IPv6 = 2
class IPField(forms.Field):
"""
Form field for entering IP/range values, with validation.
"""Form field for entering IP/range values, with validation.
Supports IPv4/IPv6 in the format:
.. xxx.xxx.xxx.xxx
.. xxx.xxx.xxx.xxx/zz
@ -102,9 +101,7 @@ class IPField(forms.Field):
class MultiIPField(IPField):
"""
Extends IPField to allow comma-separated lists of addresses
"""
"""Extends IPField to allow comma-separated lists of addresses."""
def validate(self, value):
self.addresses = []
if value:
@ -121,8 +118,7 @@ class MultiIPField(IPField):
class SelectWidget(widgets.Select):
"""
Customizable select widget, that allows to render
"""Customizable select widget, that allows to render
data-xxx attributes from choices.
.. attribute:: data_attrs

View File

@ -29,8 +29,7 @@ def replace_underscores(string):
@register.filter
def parse_isotime(timestr):
"""
This duplicates oslo timeutils parse_isotime but with a
"""This duplicates oslo timeutils parse_isotime but with a
@register.filter annotation.
"""
try:

View File

@ -22,22 +22,19 @@ class HTMLElement(object):
self.classes = getattr(self, "classes", [])
def get_default_classes(self):
"""
Returns an iterable of default classes which should be combined with
"""Returns an iterable of default classes which should be combined with
any other declared classes.
"""
return []
def get_default_attrs(self):
"""
Returns a dict of default attributes which should be combined with
"""Returns a dict of default attributes which should be combined with
other declared attributes.
"""
return {}
def get_final_attrs(self):
"""
Returns a dict containing the final attributes of this element
"""Returns a dict containing the final attributes of this element
which will be rendered.
"""
final_attrs = copy.copy(self.get_default_attrs())
@ -53,16 +50,13 @@ class HTMLElement(object):
@property
def attr_string(self):
"""
Returns a flattened string of HTML attributes based on the
"""Returns a flattened string of HTML attributes based on the
``attrs`` dict provided to the class.
"""
return flatatt(self.get_final_attrs())
@property
def class_string(self):
"""
Returns a list of class name of HTML Element in string
"""
"""Returns a list of class name of HTML Element in string."""
classes_str = " ".join(self.classes)
return classes_str

View File

@ -39,7 +39,7 @@ def password_validator_msg():
def validate_port_or_colon_separated_port_range(port_range):
"""accepts a port number or a single-colon separated range"""
"""Accepts a port number or a single-colon separated range."""
if port_range.count(':') > 1:
raise ValidationError(_("One colon allowed in port range"))
ports = port_range.split(':')

View File

@ -37,8 +37,7 @@ class APIView(generic.TemplateView):
caught.
"""
def get_data(self, request, context, *args, **kwargs):
"""
This method should handle any necessary API calls, update the
"""This method should handle any necessary API calls, update the
context object, and return the context object at the end.
"""
raise NotImplementedError("You must define a get_data method "

View File

@ -76,8 +76,7 @@ class ActionMetaclass(forms.forms.DeclarativeFieldsMetaclass):
class Action(forms.Form):
"""
An ``Action`` represents an atomic logical interaction you can have with
"""An ``Action`` represents an atomic logical interaction you can have with
the system. This is easier to understand with a conceptual example: in the
context of a "launch instance" workflow, actions would include "naming
the instance", "selecting an image", and ultimately "launching the
@ -166,14 +165,11 @@ class Action(forms.Form):
return safe(text)
def add_error(self, message):
"""
Adds an error to the Action's Step based on API issues.
"""
"""Adds an error to the Action's Step based on API issues."""
self._get_errors()[NON_FIELD_ERRORS] = self.error_class([message])
def handle(self, request, context):
"""
Handles any requisite processing for this action. The method should
"""Handles any requisite processing for this action. The method should
return either ``None`` or a dictionary of data to be passed to
:meth:`~horizon.workflows.Step.contribute`.
@ -183,8 +179,7 @@ class Action(forms.Form):
class MembershipAction(Action):
"""
An action that allows a user to add/remove members from a group.
"""An action that allows a user to add/remove members from a group.
Extend the Action class with additional helper method for membership
management.
@ -197,8 +192,7 @@ class MembershipAction(Action):
class Step(object):
"""
A step is a wrapper around an action which defines its context in a
"""A step is a wrapper around an action which defines its context in a
workflow. It knows about details such as:
* The workflow's context data (data passed from step to step).
@ -380,9 +374,8 @@ class Step(object):
return self._action
def prepare_action_context(self, request, context):
"""
Allows for customization of how the workflow context is passed to the
action; this is the reverse of what "contribute" does to make the
"""Allows for customization of how the workflow context is passed to
the action; this is the reverse of what "contribute" does to make the
action outputs sane for the workflow. Changes to the context are not
saved globally here. They are localized to the action.
@ -412,8 +405,7 @@ class Step(object):
return True
def contribute(self, data, context):
"""
Adds the data listed in ``contributes`` to the workflow's shared
"""Adds the data listed in ``contributes`` to the workflow's shared
context. By default, the context is simply updated with all the data
returned by the action.
@ -441,15 +433,11 @@ class Step(object):
return safe(text)
def add_error(self, message):
"""
Adds an error to the Step based on API issues.
"""
"""Adds an error to the Step based on API issues."""
self.action.add_error(message)
def has_required_fields(self):
"""
Returns True if action contains any required fields
"""
"""Returns True if action contains any required fields."""
for key in self.contributes:
field = self.action.fields.get(key, None)
if (field and field.required):
@ -503,8 +491,7 @@ class UpdateMembersStep(Step):
class Workflow(html.HTMLElement):
"""
A Workflow is a collection of Steps. Its interface is very
"""A Workflow is a collection of Steps. Its interface is very
straightforward, but it is responsible for handling some very
important tasks such as:
@ -705,8 +692,7 @@ class Workflow(html.HTMLElement):
return steps
def get_entry_point(self):
"""
Returns the slug of the step which the workflow should begin on.
"""Returns the slug of the step which the workflow should begin on.
This method takes into account both already-available data and errors
within the steps.
@ -750,8 +736,7 @@ class Workflow(html.HTMLElement):
@classmethod
def unregister(cls, step_class):
"""
Unregisters a :class:`~horizon.workflows.Step` from the workflow.
"""Unregisters a :class:`~horizon.workflows.Step` from the workflow.
"""
try:
cls._cls_registry.remove(step_class)
@ -760,15 +745,13 @@ class Workflow(html.HTMLElement):
return cls._unregister(step_class)
def validate(self, context):
"""
Hook for custom context data validation. Should return a boolean
"""Hook for custom context data validation. Should return a boolean
value or raise :class:`~horizon.exceptions.WorkflowValidationError`.
"""
return True
def is_valid(self):
"""
Verified that all required data is present in the context and
"""Verified that all required data is present in the context and
calls the ``validate`` method to allow for finer-grained checks
on the context data.
"""
@ -790,8 +773,7 @@ class Workflow(html.HTMLElement):
return self.validate(self.context)
def finalize(self):
"""
Finalizes a workflow by running through all the actions in order
"""Finalizes a workflow by running through all the actions in order
and calling their ``handle`` methods. Returns ``True`` on full success,
or ``False`` for a partial success, e.g. there were non-critical
errors. (If it failed completely the function wouldn't return.)
@ -814,15 +796,13 @@ class Workflow(html.HTMLElement):
return not partial
def handle(self, request, context):
"""
Handles any final processing for this workflow. Should return a boolean
value indicating success.
"""Handles any final processing for this workflow. Should return a
boolean value indicating success.
"""
return True
def get_success_url(self):
"""
Returns a URL to redirect the user to upon completion. By default it
"""Returns a URL to redirect the user to upon completion. By default it
will attempt to parse a ``success_url`` attribute on the workflow,
which can take the form of a reversible URL pattern name, or a
standard HTTP URL.
@ -833,8 +813,7 @@ class Workflow(html.HTMLElement):
return self.success_url
def format_status_message(self, message):
"""
Hook to allow customization of the message returned to the user
"""Hook to allow customization of the message returned to the user
upon successful or unsuccessful completion of the workflow.
By default it simply inserts the workflow's name into the message
@ -867,8 +846,7 @@ class Workflow(html.HTMLElement):
return self.request.get_full_path().partition('?')[0]
def add_error_to_step(self, message, slug):
"""
Adds an error to the workflow's Step with the
"""Adds an error to the workflow's Step with the
specifed slug based on API issues. This is useful
when you wish for API errors to appear as errors on
the form rather than using the messages framework.

View File

@ -27,8 +27,7 @@ from horizon import messages
class WorkflowView(generic.TemplateView):
"""
A generic class-based view which handles the intricacies of workflow
"""A generic class-based view which handles the intricacies of workflow
processing with minimal user configuration.
.. attribute:: workflow_class
@ -65,8 +64,7 @@ class WorkflowView(generic.TemplateView):
"on %s." % self.__class__.__name__)
def get_initial(self):
"""
Returns initial data for the workflow. Defaults to using the GET
"""Returns initial data for the workflow. Defaults to using the GET
parameters to allow pre-seeding of the workflow context values.
"""
return copy.copy(self.request.GET)
@ -81,8 +79,7 @@ class WorkflowView(generic.TemplateView):
return workflow
def get_context_data(self, **kwargs):
"""
Returns the template context, including the workflow class.
"""Returns the template context, including the workflow class.
This method should be overridden in subclasses to provide additional
context data to the template.

View File

@ -67,7 +67,7 @@ class APIVersionManager(object):
class APIResourceWrapper(object):
""" Simple wrapper for api objects
"""Simple wrapper for api objects.
Define _attrs on the child class and pass in the
api object as the only argument to the constructor
@ -146,8 +146,7 @@ class Quota(object):
class QuotaSet(Sequence):
"""
Wrapper for client QuotaSet objects which turns the individual quotas
"""Wrapper for client QuotaSet objects which turns the individual quotas
into Quota objects for easier handling/iteration.
`QuotaSet` objects support a mix of `list` and `dict` methods; you can use
@ -177,8 +176,9 @@ class QuotaSet(Sequence):
return self.items[index]
def __add__(self, other):
'''Merge another QuotaSet into this one. Existing quotas are
not overriden.'''
"""Merge another QuotaSet into this one. Existing quotas are
not overriden.
"""
if not isinstance(other, QuotaSet):
msg = "Can only add QuotaSet to QuotaSet, " \
"but received %s instead" % type(other)

View File

@ -25,8 +25,7 @@ LOG = logging.getLogger(__name__)
def is_iterable(var):
""" Return True if the given is list or tuple.
"""
"""Return True if the given is list or tuple."""
return (isinstance(var, (list, tuple)) or
issubclass(var.__class__, (list, tuple)))
@ -71,15 +70,13 @@ def make_query(user_id=None, tenant_id=None, resource_id=None,
class Meter(base.APIResourceWrapper):
""" Represents one Ceilometer meter.
"""
"""Represents one Ceilometer meter."""
_attrs = ['name', 'type', 'unit', 'resource_id', 'user_id',
'project_id']
class Resource(base.APIResourceWrapper):
""" Represents one Ceilometer resource.
"""
"""Represents one Ceilometer resource."""
_attrs = ['resource_id', 'source', 'user_id', 'project_id', 'metadata',
'links']
@ -194,8 +191,7 @@ class ResourceAggregate(Resource):
class Sample(base.APIResourceWrapper):
""" Represents one Ceilometer sample.
"""
"""Represents one Ceilometer sample."""
_attrs = ['counter_name', 'user_id', 'resource_id', 'timestamp',
'resource_metadata', 'source', 'counter_unit', 'counter_volume',
@ -215,8 +211,7 @@ class Sample(base.APIResourceWrapper):
class Statistic(base.APIResourceWrapper):
""" Represents one Ceilometer statistic.
"""
"""Represents one Ceilometer statistic."""
_attrs = ['period', 'period_start', 'period_end',
'count', 'min', 'max', 'sum', 'avg',
@ -317,8 +312,7 @@ class GlobalObjectStoreUsage(base.APIResourceWrapper):
def ceilometerclient(request):
""" Initialization of Ceilometer client.
"""
"""Initialization of Ceilometer client."""
endpoint = base.url_for(request, 'metering')
insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
@ -475,7 +469,7 @@ class CeilometerUsage(object):
self._users[u.id] = u
def get_tenant(self, tenant_id):
""" Returns tenant fetched form API
"""Returns tenant fetched form API.
Caching the result, so it doesn't contact API twice with the
same query
@ -536,8 +530,7 @@ class CeilometerUsage(object):
def filter_resources(resource):
"""Method for filtering resources by theirs links.rel attr.
The links.rel attributes contains all meters the resource
have.
The links.rel attributes contains all meters the resource have.
"""
for link in resource.links:
if link['rel'] in used_cls.meters:
@ -567,8 +560,7 @@ class CeilometerUsage(object):
def global_disk_usage(self, query=None, with_statistics=False,
additional_query=None):
""" Wrapper for specific call of global_data_get.
"""
"""Wrapper for specific call of global_data_get."""
return self.global_data_get(used_cls=GlobalDiskUsage,
query=query,

View File

@ -68,8 +68,7 @@ def cinderclient(request):
def volume_list(request, search_opts=None):
"""
To see all volumes in the cloud as an admin you can pass in a special
"""To see all volumes in the cloud as an admin you can pass in a special
search option: {'all_tenants': 1}
"""
c_client = cinderclient(request)
@ -181,8 +180,7 @@ def list_extensions(request):
@memoized
def extension_supported(request, extension_name):
"""
This method will determine if Cinder supports a given extension name.
"""This method will determine if Cinder supports a given extension name.
"""
extensions = list_extensions(request)
for extension in extensions:

View File

@ -24,7 +24,7 @@ neutronclient = neutron.neutronclient
class Rule(neutron.NeutronAPIDictWrapper):
"""Wrapper for neutron firewall rule"""
"""Wrapper for neutron firewall rule."""
def get_dict(self):
rule_dict = self._apidict
@ -33,7 +33,7 @@ class Rule(neutron.NeutronAPIDictWrapper):
class Policy(neutron.NeutronAPIDictWrapper):
"""Wrapper for neutron firewall policy"""
"""Wrapper for neutron firewall policy."""
def get_dict(self):
policy_dict = self._apidict
@ -42,7 +42,7 @@ class Policy(neutron.NeutronAPIDictWrapper):
class Firewall(neutron.NeutronAPIDictWrapper):
"""Wrapper for neutron firewall"""
"""Wrapper for neutron firewall."""
def get_dict(self):
firewall_dict = self._apidict

View File

@ -51,8 +51,7 @@ def image_delete(request, image_id):
def image_get(request, image_id):
"""
Returns an Image object populated with metadata for image
"""Returns an Image object populated with metadata for image
with supplied identifier.
"""
return glanceclient(request).images.get(image_id)

View File

@ -216,8 +216,7 @@ def tenant_create(request, name, description=None, enabled=None, domain=None):
def get_default_domain(request):
"""
Gets the default domain object to use when creating Identity object.
"""Gets the default domain object to use when creating Identity object.
Returns the domain context if is set, otherwise return the domain
of the logon user.
"""
@ -556,8 +555,7 @@ def remove_group_roles(request, group, domain=None, project=None):
def get_default_role(request):
"""
Gets the default role object from Keystone and saves it as a global
"""Gets the default role object from Keystone and saves it as a global
since this is configured in settings and should not change from request
to request. Supports lookup by name or id.
"""

View File

@ -22,14 +22,14 @@ neutronclient = neutron.neutronclient
class Vip(neutron.NeutronAPIDictWrapper):
"""Wrapper for neutron load balancer vip"""
"""Wrapper for neutron load balancer vip."""
def __init__(self, apiresource):
super(Vip, self).__init__(apiresource)
class Pool(neutron.NeutronAPIDictWrapper):
"""Wrapper for neutron load balancer pool"""
"""Wrapper for neutron load balancer pool."""
def __init__(self, apiresource):
if 'provider' not in apiresource:
@ -75,7 +75,7 @@ class Pool(neutron.NeutronAPIDictWrapper):
class Member(neutron.NeutronAPIDictWrapper):
"""Wrapper for neutron load balancer member"""
"""Wrapper for neutron load balancer member."""
def __init__(self, apiresource):
super(Member, self).__init__(apiresource)
@ -104,14 +104,14 @@ class Member(neutron.NeutronAPIDictWrapper):
class PoolStats(neutron.NeutronAPIDictWrapper):
"""Wrapper for neutron load balancer pool stats"""
"""Wrapper for neutron load balancer pool stats."""
def __init__(self, apiresource):
super(PoolStats, self).__init__(apiresource)
class PoolMonitor(neutron.NeutronAPIDictWrapper):
"""Wrapper for neutron load balancer pool health monitor"""
"""Wrapper for neutron load balancer pool health monitor."""
def __init__(self, apiresource):
super(PoolMonitor, self).__init__(apiresource)

View File

@ -62,7 +62,7 @@ class NeutronAPIDictWrapper(base.APIDictWrapper):
class Agent(NeutronAPIDictWrapper):
"""Wrapper for neutron agents"""
"""Wrapper for neutron agents."""
def __init__(self, apiresource):
apiresource['admin_state'] = \
@ -71,7 +71,7 @@ class Agent(NeutronAPIDictWrapper):
class Network(NeutronAPIDictWrapper):
"""Wrapper for neutron Networks"""
"""Wrapper for neutron Networks."""
def __init__(self, apiresource):
apiresource['admin_state'] = \
@ -84,7 +84,7 @@ class Network(NeutronAPIDictWrapper):
class Subnet(NeutronAPIDictWrapper):
"""Wrapper for neutron subnets"""
"""Wrapper for neutron subnets."""
def __init__(self, apiresource):
apiresource['ipver_str'] = get_ipver_str(apiresource['ip_version'])
@ -92,7 +92,7 @@ class Subnet(NeutronAPIDictWrapper):
class Port(NeutronAPIDictWrapper):
"""Wrapper for neutron ports"""
"""Wrapper for neutron ports."""
def __init__(self, apiresource):
apiresource['admin_state'] = \
@ -110,7 +110,7 @@ class Profile(NeutronAPIDictWrapper):
class Router(NeutronAPIDictWrapper):
"""Wrapper for neutron routers"""
"""Wrapper for neutron routers."""
def __init__(self, apiresource):
#apiresource['admin_state'] = \
@ -412,7 +412,7 @@ class FloatingIpManager(network_base.FloatingIpManager):
def get_ipver_str(ip_version):
"""Convert an ip version number to a human-friendly string"""
"""Convert an ip version number to a human-friendly string."""
return IP_VERSION_DICT.get(ip_version, '')
@ -476,8 +476,7 @@ def network_get(request, network_id, expand_subnet=True, **params):
def network_create(request, **kwargs):
"""
Create a subnet on a specified network.
"""Create a subnet on a specified network.
:param request: request context
:param tenant_id: (optional) tenant id of the network created
:param name: (optional) name of the network created
@ -519,8 +518,7 @@ def subnet_get(request, subnet_id, **params):
def subnet_create(request, network_id, cidr, ip_version, **kwargs):
"""
Create a subnet on a specified network.
"""Create a subnet on a specified network.
:param request: request context
:param network_id: network id a subnet is created on
:param cidr: subnet IP address range
@ -567,8 +565,7 @@ def port_get(request, port_id, **params):
def port_create(request, network_id, **kwargs):
"""
Create a port on a specified network.
"""Create a port on a specified network.
:param request: request context
:param network_id: network id a subnet is created on
:param device_id: (optional) device id attached to the port

View File

@ -686,8 +686,7 @@ def list_extensions(request):
@memoized
def extension_supported(extension_name, request):
"""
this method will determine if nova supports a given extension name.
"""this method will determine if nova supports a given extension name.
example values for the extension_name include AdminActions, ConsoleOutput,
etc.
"""

View File

@ -30,7 +30,7 @@ except ImportError:
class TokenAuth(object):
"""Simple Token Authentication handler for trove api"""
"""Simple Token Authentication handler for trove api."""
def __init__(self, client, auth_strategy, auth_url, username, password,
tenant, region, service_type, service_name, service_url):

View File

@ -98,7 +98,7 @@ class DomainFilterAction(tables.FilterAction):
return multidomain_support
def filter(self, table, domains, filter_string):
""" Naive case-insensitive search """
"""Naive case-insensitive search."""
q = filter_string.lower()
def comp(domain):

View File

@ -85,7 +85,7 @@ class ManageUsersLink(tables.LinkAction):
class GroupFilterAction(tables.FilterAction):
def filter(self, table, groups, filter_string):
""" Naive case-insensitive search """
"""Naive case-insensitive search."""
q = filter_string.lower()
def comp(group):
@ -112,7 +112,7 @@ class GroupsTable(tables.DataTable):
class UserFilterAction(tables.FilterAction):
def filter(self, table, users, filter_string):
""" Naive case-insensitive search """
"""Naive case-insensitive search."""
q = filter_string.lower()
return [user for user in users
if q in user.name.lower()

View File

@ -84,7 +84,7 @@ class GlobalDiskUsageTab(tabs.TableTab):
preload = False
def get_global_disk_usage_data(self):
""" Disk usage table data aggregated by project """
"""Disk usage table data aggregated by project."""
request = self.tab_group.request
return list_of_resource_aggregates(request,
ceilometer.GlobalDiskUsage.meters)

View File

@ -57,7 +57,7 @@ class DeleteRolesAction(tables.DeleteAction):
class RoleFilterAction(tables.FilterAction):
def filter(self, table, roles, filter_string):
""" Naive case-insensitive search """
"""Naive case-insensitive search."""
q = filter_string.lower()
return [role for role in roles
if q in role.name.lower()]

View File

@ -115,7 +115,7 @@ class DeleteUsersAction(tables.DeleteAction):
class UserFilterAction(tables.FilterAction):
def filter(self, table, users, filter_string):
""" Naive case-insensitive search """
"""Naive case-insensitive search."""
q = filter_string.lower()
return [user for user in users
if q in user.name.lower()

View File

@ -47,8 +47,7 @@ class DeleteContainer(tables.DeleteAction):
api.swift.swift_delete_container(request, obj_id)
def get_success_url(self, request=None):
"""
Returns the URL to redirect to after a successful action.
"""Returns the URL to redirect to after a successful action.
"""
current_container = self.table.kwargs.get("container_name", None)

View File

@ -65,8 +65,7 @@ class SetInstanceDetails(workflows.Step):
class AddDatabasesAction(workflows.Action):
"""
Initialize the database with users/databases. This tab will honor
"""Initialize the database with users/databases. This tab will honor
the settings which should be a list of permissions required:
* TROVE_ADD_USER_PERMS = []

View File

@ -44,8 +44,7 @@ IMAGES_INDEX_URL = reverse('horizon:project:images_and_snapshots:index')
class CreateImageFormTests(test.TestCase):
def test_no_location_or_file(self):
"""
The form will not be valid if both copy_from and image_file are not
"""The form will not be valid if both copy_from and image_file are not
provided.
"""
post = {
@ -62,8 +61,7 @@ class CreateImageFormTests(test.TestCase):
@override_settings(HORIZON_IMAGES_ALLOW_UPLOAD=False)
def test_image_upload_disabled(self):
"""
If HORIZON_IMAGES_ALLOW_UPLOAD is false, the image_file field widget
"""If HORIZON_IMAGES_ALLOW_UPLOAD is false, the image_file field widget
will be a HiddenInput widget instead of a FileInput widget.
"""
form = forms.CreateImageForm({})

View File

@ -18,8 +18,7 @@ from openstack_dashboard.api import glance
def get_available_images(request, project_id=None, images_cache=None):
"""
Returns a list of images that are public or owned by the given
"""Returns a list of images that are public or owned by the given
project_id. If project_id is not specified, only public images
are returned.

View File

@ -217,7 +217,8 @@ class SetInstanceDetailsAction(workflows.Action):
"""By default, returns the available flavors, sorted by RAM
usage (ascending).
Override these behaviours with a CREATE_INSTANCE_FLAVOR_SORT dict
in local_settings.py."""
in local_settings.py.
"""
try:
flavors = api.nova.flavor_list(request)
flavor_sort = getattr(settings, 'CREATE_INSTANCE_FLAVOR_SORT', {})

View File

@ -368,7 +368,7 @@ class CreateNetwork(workflows.Workflow):
return False
def _delete_network(self, request, network):
"""Delete the created network when subnet creation failed"""
"""Delete the created network when subnet creation failed."""
try:
api.neutron.network_delete(request, network.id)
msg = _('Delete the created network "%s" '

View File

@ -31,8 +31,7 @@ LOG = logging.getLogger(__name__)
class RuleCIDRField(fields.IPField):
"""
Extends IPField to allow ('any','external') keywords and requires CIDR
"""Extends IPField to allow ('any','external') keywords and requires CIDR
"""
def __init__(self, *args, **kwargs):
kwargs['mask'] = True

View File

@ -29,9 +29,7 @@ LOG = logging.getLogger(__name__)
def exception_to_validation_msg(e):
'''
Extracts a validation message to display to the user.
'''
"""Extracts a validation message to display to the user."""
try:
error = json.loads(str(e))
# NOTE(jianingy): if no message exists, we just return 'None'

View File

@ -140,9 +140,7 @@ def get_resource_status(status):
def get_resource_image(status, type):
'''
Sets the image url and in_progress action sw based on status.
'''
"""Sets the image url and in_progress action sw based on status."""
resource_type = get_resource_type(type)
resource_status = get_resource_status(status)
resource_state = resource_type + "_" + resource_status

View File

@ -132,8 +132,9 @@ def get_attachment_name(request, attachment):
class AttachmentColumn(tables.Column):
"""
Customized column class that does complex processing on the attachments
"""Customized column class.
So it that does complex processing on the attachments
for a volume instance.
"""
def get_raw_data(self, volume):
@ -230,8 +231,7 @@ class DetachVolume(tables.BatchAction):
class AttachedInstanceColumn(tables.Column):
"""
Customized column class that does complex processing on the attachments
"""Customized column class that does complex processing on the attachments
for a volume instance.
"""
def get_raw_data(self, attachment):

View File

@ -60,7 +60,8 @@ def reset():
def check(actions, request, target={}):
"""
"""Check user permission.
Check if the user has permission to the action according
to policy setting.

View File

@ -27,7 +27,7 @@ from openstack_dashboard.test import helpers as test
class APIResource(api_base.APIResourceWrapper):
""" Simple APIResource for testing """
"""Simple APIResource for testing."""
_attrs = ['foo', 'bar', 'baz']
@staticmethod
@ -44,7 +44,7 @@ class APIResource(api_base.APIResourceWrapper):
class APIDict(api_base.APIDictWrapper):
""" Simple APIDict for testing """
"""Simple APIDict for testing."""
_attrs = ['foo', 'bar', 'baz']
@staticmethod
@ -116,7 +116,7 @@ class APIDictWrapperTests(test.TestCase):
class ApiHelperTests(test.TestCase):
""" Tests for functions that don't use one of the api objects """
"""Tests for functions that don't use one of the api objects."""
def test_url_for(self):
url = api_base.url_for(self.request, 'image')

View File

@ -50,8 +50,7 @@ class RoleAPITests(test.APITestCase):
self.roles = self.roles.list()
def test_remove_tenant_user(self):
"""
Tests api.keystone.remove_tenant_user
"""Tests api.keystone.remove_tenant_user
Verifies that remove_tenant_user is called with the right arguments
after iterating the user's roles.

View File

@ -108,8 +108,7 @@ class RequestFactoryWithMessages(RequestFactory):
@unittest.skipIf(os.environ.get('SKIP_UNITTESTS', False),
"The SKIP_UNITTESTS env variable is set.")
class TestCase(horizon_helpers.TestCase):
"""
Specialized base test case class for Horizon which gives access to
"""Specialized base test case class for Horizon which gives access to
numerous additional features:
* A full suite of test data through various attached objects and
@ -180,8 +179,7 @@ class TestCase(horizon_helpers.TestCase):
utils.get_user = get_user
def assertRedirectsNoFollow(self, response, expected_url):
"""
Asserts that the given response issued a 302 redirect without
"""Asserts that the given response issued a 302 redirect without
processing the view which is redirected to.
"""
assert (response.status_code / 100 == 3), \
@ -191,8 +189,7 @@ class TestCase(horizon_helpers.TestCase):
self.assertEqual(response.status_code, 302)
def assertNoFormErrors(self, response, context_name="form"):
"""
Asserts that the response either does not contain a form in its
"""Asserts that the response either does not contain a form in its
context, or that if it does, that form has no errors.
"""
context = getattr(response, "context", {})
@ -204,8 +201,7 @@ class TestCase(horizon_helpers.TestCase):
def assertFormErrors(self, response, count=0, message=None,
context_name="form"):
"""
Asserts that the response does contain a form in its
"""Asserts that the response does contain a form in its
context, and that form has errors, if count were given,
it must match the exact numbers of errors
"""
@ -226,8 +222,7 @@ class TestCase(horizon_helpers.TestCase):
class BaseAdminViewTests(TestCase):
"""
A ``TestCase`` subclass which sets an active user with the "admin" role
"""A ``TestCase`` subclass which sets an active user with the "admin" role
for testing admin-only views and functionality.
"""
def setActiveUser(self, *args, **kwargs):
@ -248,8 +243,7 @@ class BaseAdminViewTests(TestCase):
class APITestCase(TestCase):
"""
The ``APITestCase`` class is for use with tests which deal with the
"""The ``APITestCase`` class is for use with tests which deal with the
underlying clients rather than stubbing out the
openstack_dashboard.api.* methods.
"""
@ -258,8 +252,7 @@ class APITestCase(TestCase):
utils.patch_middleware_get_user()
def fake_keystoneclient(request, admin=False):
"""
Wrapper function which returns the stub keystoneclient. Only
"""Wrapper function which returns the stub keystoneclient. Only
necessary because the function takes too many arguments to
conveniently be a lambda.
"""
@ -414,8 +407,7 @@ class SeleniumTestCase(horizon_helpers.SeleniumTestCase):
class SeleniumAdminTestCase(SeleniumTestCase):
"""
A ``TestCase`` subclass which sets an active user with the "admin" role
"""A ``TestCase`` subclass which sets an active user with the "admin" role
for testing admin-only views and functionality.
"""
def setActiveUser(self, *args, **kwargs):

View File

@ -53,8 +53,7 @@ def load_test_data(load_onto=None):
class TestData(object):
"""
Holder object for test data. Any functions passed to the init method
"""Holder object for test data. Any functions passed to the init method
will be called with the ``TestData`` object as their only argument. They
can then load data onto the object as desired.
@ -103,8 +102,7 @@ class TestDataContainer(object):
return self._objects
def filter(self, filtered=None, **kwargs):
"""
Returns objects in this container whose attributes match the given
"""Returns objects in this container whose attributes match the given
keyword arguments.
"""
if filtered is None:
@ -121,8 +119,7 @@ class TestDataContainer(object):
return self.filter(filtered=filter(get_match, filtered), **kwargs)
def get(self, **kwargs):
"""
Returns the single object in this container whose attributes match
"""Returns the single object in this container whose attributes match
the given keyword arguments. An error will be raised if the arguments
provided don't return exactly one match.
"""

View File

@ -23,7 +23,7 @@ from openstack_dashboard.test import helpers as test
class ErrorPageTests(test.TestCase):
""" Tests for error pages """
"""Tests for error pages."""
urls = 'openstack_dashboard.test.error_pages_urls'
def test_500_error(self):

View File

@ -25,7 +25,7 @@ class FakeUser(object):
class TemplateRenderTest(test.TestCase):
""" Tests for templates render """
"""Tests for templates render."""
def test_openrc_html_escape(self):
context = {

View File

@ -275,8 +275,7 @@ class ProjectUsage(BaseUsage):
class CsvDataMixin(object):
"""
CSV data Mixin - provides handling for CSV data
"""CSV data Mixin - provides handling for CSV data.
.. attribute:: columns
@ -318,10 +317,7 @@ class CsvDataMixin(object):
class BaseCsvResponse(CsvDataMixin, HttpResponse):
"""
Base CSV response class. Provides handling of CSV data.
"""
"""Base CSV response class. Provides handling of CSV data."""
def __init__(self, request, template, context, content_type, **kwargs):
super(BaseCsvResponse, self).__init__()
@ -358,8 +354,7 @@ if VERSION >= (1, 5, 0):
class BaseCsvStreamingResponse(CsvDataMixin, StreamingHttpResponse):
"""
Base CSV Streaming class. Provides streaming response for CSV data.
"""Base CSV Streaming class. Provides streaming response for CSV data.
"""
def __init__(self, request, template, context, content_type, **kwargs):

View File

@ -34,8 +34,7 @@ builtins = _
exclude = .venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build,panel_template,dash_template,local_settings.py
# E127 continuation line over-indented for visual indent
# E128 continuation line under-indented for visual indent
# H4xx docstrings
# H701 empty localization string
# H702 Formatting operation should be outside of localization method call
# H803 git commit title should not end with period (disabled on purpose, see bug #1236621)
ignore = E127,E128,H4,H701,H702,H803
ignore = E127,E128,H701,H702,H803