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

@ -159,7 +159,7 @@ class Registry(object):
class Panel(HorizonComponent):
""" A base class for defining Horizon dashboard panels.
"""A base class for defining Horizon dashboard panels.
All Horizon dashboard panels should extend from this class. It provides
the appropriate hooks for automatically constructing URLconfs, and
@ -214,7 +214,7 @@ class Panel(HorizonComponent):
return "<Panel: %s>" % self.slug
def get_absolute_url(self):
""" Returns the default URL for this panel.
"""Returns the default URL for this panel.
The default URL is defined as the URL pattern with ``name="index"`` in
the URLconf for this panel.
@ -243,7 +243,7 @@ class Panel(HorizonComponent):
class PanelGroup(object):
""" A container for a set of :class:`~horizon.Panel` classes.
"""A container for a set of :class:`~horizon.Panel` classes.
When iterated, it will yield each of the ``Panel`` instances it
contains.
@ -286,7 +286,7 @@ class PanelGroup(object):
class Dashboard(Registry, HorizonComponent):
""" A base class for defining Horizon dashboards.
"""A base class for defining Horizon dashboards.
All Horizon dashboards should extend from this base class. It provides the
appropriate hooks for automatic discovery of :class:`~horizon.Panel`
@ -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 = []
@ -432,7 +430,7 @@ class Dashboard(Registry, HorizonComponent):
return SortedDict(panel_groups)
def get_absolute_url(self):
""" Returns the default URL for this dashboard.
"""Returns the default URL for this dashboard.
The default URL is defined as the URL pattern with ``name="index"``
in the URLconf for the :class:`~horizon.Panel` specified by
@ -478,7 +476,7 @@ class Dashboard(Registry, HorizonComponent):
return urlpatterns, self.slug, self.slug
def _autodiscover(self):
""" Discovers panels to register from the current dashboard module. """
"""Discovers panels to register from the current dashboard module."""
if getattr(self, "_autodiscover_complete", False):
return
@ -520,7 +518,7 @@ class Dashboard(Registry, HorizonComponent):
@classmethod
def register(cls, panel):
""" Registers a :class:`~horizon.Panel` with this dashboard. """
"""Registers a :class:`~horizon.Panel` with this dashboard."""
panel_class = Horizon.register_panel(cls, panel)
# Support template loading from panel template directories.
panel_mod = import_module(panel.__module__)
@ -533,7 +531,7 @@ class Dashboard(Registry, HorizonComponent):
@classmethod
def unregister(cls, panel):
""" Unregisters a :class:`~horizon.Panel` from this dashboard. """
"""Unregisters a :class:`~horizon.Panel` from this dashboard."""
success = Horizon.unregister_panel(cls, panel)
if success:
# Remove the panel's template directory.
@ -578,7 +576,7 @@ class LazyURLPattern(SimpleLazyObject):
class Site(Registry, HorizonComponent):
""" The overarching class which encompasses all dashboards and panels. """
"""The overarching class which encompasses all dashboards and panels."""
# Required for registry
_registerable_class = Dashboard
@ -604,11 +602,11 @@ class Site(Registry, HorizonComponent):
return self._conf['default_dashboard']
def register(self, dashboard):
""" Registers a :class:`~horizon.Dashboard` with Horizon."""
"""Registers a :class:`~horizon.Dashboard` with Horizon."""
return self._register(dashboard)
def unregister(self, dashboard):
""" Unregisters a :class:`~horizon.Dashboard` from Horizon. """
"""Unregisters a :class:`~horizon.Dashboard` from Horizon."""
return self._unregister(dashboard)
def registered(self, dashboard):
@ -626,11 +624,11 @@ class Site(Registry, HorizonComponent):
return dash_instance._unregister(panel)
def get_dashboard(self, dashboard):
""" Returns the specified :class:`~horizon.Dashboard` instance. """
"""Returns the specified :class:`~horizon.Dashboard` instance."""
return self._registered(dashboard)
def get_dashboards(self):
""" Returns an ordered tuple of :class:`~horizon.Dashboard` modules.
"""Returns an ordered tuple of :class:`~horizon.Dashboard` modules.
Orders dashboards according to the ``"dashboards"`` key in
``HORIZON_CONFIG`` or else returns all registered dashboards
@ -658,7 +656,7 @@ class Site(Registry, HorizonComponent):
return dashboards
def get_default_dashboard(self):
""" Returns the default :class:`~horizon.Dashboard` instance.
"""Returns the default :class:`~horizon.Dashboard` instance.
If ``"default_dashboard"`` is specified in ``HORIZON_CONFIG``
then that dashboard will be returned. If not, the first dashboard
@ -672,7 +670,7 @@ class Site(Registry, HorizonComponent):
raise NotRegistered("No dashboard modules have been registered.")
def get_user_home(self, user):
""" Returns the default URL for a particular user.
"""Returns the default URL for a particular user.
This method can be used to customize where a user is sent when
they log in, etc. By default it returns the value of
@ -710,7 +708,7 @@ class Site(Registry, HorizonComponent):
return self.get_absolute_url()
def get_absolute_url(self):
""" Returns the default URL for Horizon's URLconf.
"""Returns the default URL for Horizon's URLconf.
The default URL is determined by calling
:meth:`~horizon.Dashboard.get_absolute_url`
@ -721,7 +719,7 @@ class Site(Registry, HorizonComponent):
@property
def _lazy_urls(self):
""" Lazy loading for URL patterns.
"""Lazy loading for URL patterns.
This method avoids problems associated with attempting to evaluate
the the URLconf before the settings module has been loaded.
@ -732,7 +730,7 @@ class Site(Registry, HorizonComponent):
return LazyURLPattern(url_patterns), self.namespace, self.slug
def _urls(self):
""" Constructs the URLconf for Horizon from registered Dashboards. """
"""Constructs the URLconf for Horizon from registered Dashboards."""
urlpatterns = self._get_default_urlpatterns()
self._autodiscover()
@ -764,7 +762,7 @@ class Site(Registry, HorizonComponent):
return urlpatterns, self.namespace, self.slug
def _autodiscover(self):
""" Discovers modules to register from ``settings.INSTALLED_APPS``.
"""Discovers modules to register from ``settings.INSTALLED_APPS``.
This makes sure that the appropriate modules get imported to register
themselves with Horizon.
@ -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

@ -41,7 +41,7 @@ class Breadcrumb(html.HTMLElement):
return self._subfolders
def render(self):
""" Renders the table using the template from the table options. """
"""Renders the table using the template from the table options."""
breadcrumb_template = template.loader.get_template(self.template)
extra_context = {"breadcrumb": self}
context = template.RequestContext(self.request, extra_context)

View File

@ -25,7 +25,7 @@ from horizon import conf
def horizon(request):
""" The main Horizon context processor. Required for Horizon to function.
"""The main Horizon context processor. Required for Horizon to function.
It adds the Horizon config to the context as well as setting the names
``True`` and ``False`` in the context to their boolean equivalents

View File

@ -28,7 +28,7 @@ from django.utils.translation import ugettext_lazy as _ # noqa
def _current_component(view_func, dashboard=None, panel=None):
""" Sets the currently-active dashboard and/or panel on the request. """
"""Sets the currently-active dashboard and/or panel on the request."""
@functools.wraps(view_func, assigned=available_attrs(view_func))
def dec(request, *args, **kwargs):
if dashboard:
@ -40,7 +40,7 @@ def _current_component(view_func, dashboard=None, panel=None):
def require_auth(view_func):
""" Performs user authentication check.
"""Performs user authentication check.
Similar to Django's `login_required` decorator, except that this throws
:exc:`~horizon.exceptions.NotAuthenticated` exception if the user is not
@ -57,7 +57,7 @@ def require_auth(view_func):
def require_perms(view_func, required):
""" Enforces permission-based access controls.
"""Enforces permission-based access controls.
:param list required: A tuple of permission names, all of which the request
user must possess in order access the decorated view.

View File

@ -36,15 +36,14 @@ LOG = logging.getLogger(__name__)
class HorizonReporterFilter(SafeExceptionReporterFilter):
""" Error report filter that's always active, even in DEBUG mode. """
"""Error report filter that's always active, even in DEBUG mode."""
def is_active(self, request):
return True
# 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
@ -93,13 +92,12 @@ class HorizonReporterFilter(SafeExceptionReporterFilter):
class HorizonException(Exception):
""" Base exception class for distinguishing our own exception classes. """
"""Base exception class for distinguishing our own exception classes."""
pass
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
@ -134,19 +131,18 @@ class NotAuthenticated(HorizonException):
class NotFound(HorizonException):
""" Generic error to replace all "Not Found"-type API errors. """
"""Generic error to replace all "Not Found"-type API errors."""
status_code = 404
class RecoverableError(HorizonException):
""" Generic error to replace any "Recoverable"-type API errors. """
"""Generic error to replace any "Recoverable"-type API errors."""
status_code = 100 # HTTP status code "Continue"
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):
@ -173,21 +168,19 @@ class AlreadyExists(HorizonException):
class WorkflowError(HorizonException):
""" Exception to be raised when something goes wrong in a workflow. """
"""Exception to be raised when something goes wrong in a workflow."""
pass
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.
"""
@ -218,7 +210,7 @@ def check_message(keywords, message):
def handle(request, message=None, redirect=None, ignore=False,
escalate=False, log_level=None, force_log=None):
""" Centralized error handling for Horizon.
"""Centralized error handling for Horizon.
Because Horizon consumes so many different APIs with completely
different ``Exception`` types, it's necessary to have a centralized

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.
@ -49,7 +47,7 @@ class SelfHandlingForm(SelfHandlingMixin, forms.Form):
class DateForm(forms.Form):
""" A simple form for selecting a range of time. """
"""A simple form for selecting a range of time."""
start = forms.DateField(input_formats=("%Y-%m-%d",))
end = forms.DateField(input_formats=("%Y-%m-%d",))

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``
@ -67,5 +65,5 @@ class DynamicChoiceField(fields.ChoiceField):
class DynamicTypedChoiceField(DynamicChoiceField, fields.TypedChoiceField):
""" Simple mix of ``DynamicChoiceField`` and ``TypedChoiceField``. """
"""Simple mix of ``DynamicChoiceField`` and ``TypedChoiceField``."""
pass

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

@ -43,12 +43,12 @@ LOG = logging.getLogger(__name__)
class HorizonMiddleware(object):
""" The main Horizon middleware class. Required for use of Horizon. """
"""The main Horizon middleware class. Required for use of Horizon."""
logout_reason = None
def process_request(self, request):
""" Adds data necessary for Horizon to function to the request. """
"""Adds data necessary for Horizon to function to the request."""
# Activate timezone handling
tz = request.session.get('django_timezone')
if tz:
@ -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

@ -39,7 +39,7 @@ STRING_SEPARATOR = "__"
class BaseAction(html.HTMLElement):
""" Common base class for all ``Action`` classes. """
"""Common base class for all ``Action`` classes."""
table = None
handles_multiple = False
requires_input = False
@ -51,8 +51,8 @@ class BaseAction(html.HTMLElement):
self.datum = datum
def data_type_matched(self, datum):
""" Method to see if the action is allowed for a certain type of data.
Only affects mixed data type tables.
"""Method to see if the action is allowed for a certain type of data.
Only affects mixed data type tables.
"""
if datum:
action_data_types = getattr(self, "allowed_data_types", [])
@ -66,7 +66,7 @@ class BaseAction(html.HTMLElement):
return True
def get_policy_target(self, request, datum):
""" Provide the target for a policy request.
"""Provide the target for a policy request.
This method is meant to be overridden to return target details when
one of the policy checks requires them. E.g., {"user_id": datum.id}
@ -74,7 +74,7 @@ class BaseAction(html.HTMLElement):
return {}
def allowed(self, request, datum):
""" Determine whether this action is allowed for the current request.
"""Determine whether this action is allowed for the current request.
This method is meant to be overridden with more specific checks.
"""
@ -90,7 +90,7 @@ class BaseAction(html.HTMLElement):
return self.allowed(request, datum)
def update(self, request, datum):
""" Allows per-action customization based on current conditions.
"""Allows per-action customization based on current conditions.
This is particularly useful when you wish to create a "toggle"
action that will be rendered differently based on the value of an
@ -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:
@ -126,7 +124,7 @@ class BaseAction(html.HTMLElement):
class Action(BaseAction):
""" Represents an action which can be taken on this table's data.
"""Represents an action which can be taken on this table's data.
.. attribute:: name
@ -265,7 +263,7 @@ class Action(BaseAction):
self.multiple = new.instancemethod(multiple, self)
def get_param_name(self):
""" Returns the full POST parameter name for this action.
"""Returns the full POST parameter name for this action.
Defaults to
``{{ table.name }}__{{ action.name }}``.
@ -274,7 +272,7 @@ class Action(BaseAction):
class LinkAction(BaseAction):
""" A table action which is simply a link rather than a form POST.
"""A table action which is simply a link rather than a form POST.
.. attribute:: name
@ -319,7 +317,7 @@ class LinkAction(BaseAction):
self.attrs.update(attrs)
def get_link_url(self, datum=None):
""" Returns the final URL based on the value of ``url``.
"""Returns the final URL based on the value of ``url``.
If ``url`` is callable it will call the function.
If not, it will then try to call ``reverse`` on ``url``.
@ -346,7 +344,7 @@ class LinkAction(BaseAction):
class FilterAction(BaseAction):
""" A base class representing a filter action for a table.
"""A base class representing a filter action for a table.
.. attribute:: name
@ -389,7 +387,7 @@ class FilterAction(BaseAction):
self.param_name = param_name or 'q'
def get_param_name(self):
""" Returns the full query parameter name for this action.
"""Returns the full query parameter name for this action.
Defaults to
``{{ table.name }}__{{ action.name }}__{{ action.param_name }}``.
@ -424,7 +422,7 @@ class FilterAction(BaseAction):
return filtered_data
def filter(self, table, data, filter_string):
""" Provides the actual filtering logic.
"""Provides the actual filtering logic.
This method must be overridden by subclasses and return
the filtered data.
@ -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
@ -480,9 +477,9 @@ class FixedFilterAction(FilterAction):
class BatchAction(Action):
""" A table action which takes batch action on one or more
objects. This action should not require user input on a
per-object basis.
"""A table action which takes batch action on one or more
objects. This action should not require user input on a
per-object basis.
.. attribute:: name
@ -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

@ -49,7 +49,7 @@ STRING_SEPARATOR = "__"
class Column(html.HTMLElement):
""" A class which represents a single column in a :class:`.DataTable`.
"""A class which represents a single column in a :class:`.DataTable`.
.. attribute:: transform
@ -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`
@ -329,7 +328,7 @@ class Column(html.HTMLElement):
return self.table._data_cache[self][datum_id]
def get_link_url(self, datum):
""" Returns the final value for the column's ``link`` property.
"""Returns the final value for the column's ``link`` property.
If ``allowed_data_types`` of this column is not empty and the datum
has an assigned type, check if the datum's type is in the
@ -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:
@ -376,7 +374,7 @@ class Column(html.HTMLElement):
class Row(html.HTMLElement):
""" Represents a row in the table.
"""Represents a row in the table.
When iterated, the ``Row`` instance will yield each of its cells.
@ -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.
@ -526,7 +523,7 @@ class Row(html.HTMLElement):
{"row": self})
def get_cells(self):
""" Returns the bound cells for this row in order. """
"""Returns the bound cells for this row in order."""
return self.cells.values()
def get_ajax_update_url(self):
@ -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"
@ -546,7 +542,7 @@ class Row(html.HTMLElement):
class Cell(html.HTMLElement):
""" Represents a single cell in the table. """
"""Represents a single cell in the table."""
def __init__(self, datum, data, column, row, attrs=None, classes=None):
self.classes = classes or getattr(self, "classes", [])
super(Cell, self).__init__()
@ -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
@ -602,7 +597,7 @@ class Cell(html.HTMLElement):
@property
def status(self):
""" Gets the status for the column based on the cell's data. """
"""Gets the status for the column based on the cell's data."""
# Deal with status column mechanics based in this cell's data
if hasattr(self, '_status'):
return self._status
@ -619,7 +614,7 @@ class Cell(html.HTMLElement):
return self._status
def get_status_class(self, status):
""" Returns a css class name determined by the status value. """
"""Returns a css class name determined by the status value."""
if status is True:
return "status_up"
elif status is False:
@ -628,7 +623,7 @@ class Cell(html.HTMLElement):
return "status_unknown"
def get_default_classes(self):
""" Returns a flattened string of the cell's CSS classes. """
"""Returns a flattened string of the cell's CSS classes."""
if not self.url:
self.column.classes = [cls for cls in self.column.classes
if cls != "anchor"]
@ -640,7 +635,7 @@ class Cell(html.HTMLElement):
class DataTableOptions(object):
""" Contains options for :class:`.DataTable` objects.
"""Contains options for :class:`.DataTable` objects.
.. attribute:: name
@ -823,7 +818,7 @@ class DataTableOptions(object):
class DataTableMetaclass(type):
""" Metaclass to add options to DataTable class and collect columns. """
"""Metaclass to add options to DataTable class and collect columns."""
def __new__(mcs, name, bases, attrs):
# Process options from Meta
class_name = name
@ -896,7 +891,7 @@ class DataTableMetaclass(type):
class DataTable(object):
""" A class which defines a table with all data and associated actions.
"""A class which defines a table with all data and associated actions.
.. attribute:: name
@ -1017,14 +1012,14 @@ class DataTable(object):
return False
def render(self):
""" Renders the table using the template from the table options. """
"""Renders the table using the template from the table options."""
table_template = template.loader.get_template(self._meta.template)
extra_context = {self._meta.context_var_name: self}
context = template.RequestContext(self.request, extra_context)
return table_template.render(context)
def get_absolute_url(self):
""" Returns the canonical URL for this table.
"""Returns the canonical URL for this table.
This is used for the POST action attribute on the form element
wrapping the table. In many cases it is also useful for redirecting
@ -1037,12 +1032,11 @@ class DataTable(object):
return self.request.get_full_path().partition('?')[0]
def get_empty_message(self):
""" Returns the message to be displayed when there is no data. """
"""Returns the message to be displayed when there is no data."""
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.
@ -1092,14 +1084,14 @@ class DataTable(object):
return self.has_actions
def get_table_actions(self):
""" Returns a list of the action instances for this table. """
"""Returns a list of the action instances for this table."""
bound_actions = [self.base_actions[action.name] for
action in self._meta.table_actions]
return [action for action in bound_actions if
self._filter_action(action, self.request)]
def get_row_actions(self, datum):
""" Returns a list of the action instances for a specific row. """
"""Returns a list of the action instances for a specific row."""
bound_actions = []
for action in self._meta.row_actions:
# Copy to allow modifying properties per row
@ -1120,7 +1112,7 @@ class DataTable(object):
return bound_actions
def render_table_actions(self):
""" Renders the actions specified in ``Meta.table_actions``. """
"""Renders the actions specified in ``Meta.table_actions``."""
template_path = self._meta.table_actions_template
table_actions_template = template.loader.get_template(template_path)
bound_actions = self.get_table_actions()
@ -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.
@ -1200,7 +1190,7 @@ class DataTable(object):
@classmethod
def check_handler(cls, request):
""" Determine whether the request should be handled by this table. """
"""Determine whether the request should be handled by this table."""
if request.method == "POST" and "action" in request.POST:
table, action, obj_id = cls.parse_action(request.POST["action"])
elif "table" in request.GET and "action" in request.GET:
@ -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)
@ -1262,13 +1250,13 @@ class DataTable(object):
return None
def sanitize_id(self, obj_id):
""" Override to modify an incoming obj_id to match existing
"""Override to modify an incoming obj_id to match existing
API data types or modify the format.
"""
return obj_id
def get_object_id(self, datum):
""" Returns the identifier for the object this row will represent.
"""Returns the identifier for the object this row will represent.
By default this returns an ``id`` attribute on the given object,
but this can be overridden to return other values.
@ -1281,7 +1269,7 @@ class DataTable(object):
return datum.id
def get_object_display(self, datum):
""" Returns a display name that identifies this object.
"""Returns a display name that identifies this object.
By default, this returns a ``name`` attribute from the given object,
but this can be overriden to return other values.
@ -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,19 +1288,17 @@ 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]))
def get_pagination_string(self):
""" Returns the query parameter string to paginate this table. """
"""Returns the query parameter string to paginate this table."""
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.
"""
@ -1352,11 +1336,11 @@ class DataTable(object):
return "status_unknown"
def get_columns(self):
""" Returns this table's columns including auto-generated ones."""
"""Returns this table's columns including auto-generated ones."""
return self.columns.values()
def get_rows(self):
""" Return the row data for this table broken out by columns. """
"""Return the row data for this table broken out by columns."""
rows = []
try:
for datum in self.filtered_data:

View File

@ -22,7 +22,7 @@ from horizon.templatetags.horizon import has_permissions # noqa
class MultiTableMixin(object):
""" A generic mixin which provides methods for handling DataTables. """
"""A generic mixin which provides methods for handling DataTables."""
data_method_pattern = "get_%s_data"
def __init__(self, *args, **kwargs):
@ -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``
@ -164,7 +163,7 @@ class MultiTableView(MultiTableMixin, generic.TemplateView):
class DataTableView(MultiTableView):
""" A class-based generic view to handle basic DataTable processing.
"""A class-based generic view to handle basic DataTable processing.
Three steps are required to use this view: set the ``table_class``
attribute with the desired :class:`~horizon.tables.DataTable` class;
@ -211,7 +210,7 @@ class DataTableView(MultiTableView):
class MixedDataTableView(DataTableView):
""" A class-based generic view to handle DataTable with mixed data
"""A class-based generic view to handle DataTable with mixed data
types.
Basic usage is the same as DataTableView.

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.
"""
@ -169,15 +163,15 @@ class TabGroup(html.HTMLElement):
return marked_active
def render(self):
""" Renders the HTML output for this tab group. """
"""Renders the HTML output for this tab group."""
return render_to_string(self.template_name, {"tab_group": self})
def get_tabs(self):
""" Returns a list of the allowed tabs for this tab group. """
"""Returns a list of the allowed tabs for this tab group."""
return filter(lambda tab: tab._allowed, self._tabs.values())
def get_tab(self, tab_name, allow_disabled=False):
""" Returns a specific tab from this tab group.
"""Returns a specific tab from this tab group.
If the tab is not allowed or not enabled this method returns ``None``.
@ -193,7 +187,7 @@ class TabGroup(html.HTMLElement):
return filter(lambda t: self.get_tab(t.slug), self._tabs.values())
def get_selected_tab(self):
""" Returns the tab specific by the GET request parameter.
"""Returns the tab specific by the GET request parameter.
In the event that there is no GET request parameter, the value
of the query parameter is invalid, or the tab is not allowed/enabled,
@ -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
@ -265,7 +258,7 @@ class Tab(html.HTMLElement):
return "<%s: %s>" % (self.__class__.__name__, self.slug)
def is_active(self):
""" Method to access whether or not this tab is the active tab. """
"""Method to access whether or not this tab is the active tab."""
if self._active is None:
self.tab_group._set_active_tab()
return self._active
@ -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.
@ -39,13 +39,13 @@ class TabView(generic.TemplateView):
"on %s." % self.__class__.__name__)
def get_tabs(self, request, **kwargs):
""" Returns the initialized tab group for this view. """
"""Returns the initialized tab group for this view."""
if self._tab_group is None:
self._tab_group = self.tab_group_class(request, **kwargs)
return self._tab_group
def get_context_data(self, **kwargs):
""" Adds the ``tab_group`` variable to the context data. """
"""Adds the ``tab_group`` variable to the context data."""
context = super(TabView, self).get_context_data(**kwargs)
try:
tab_group = self.get_tabs(self.request, **kwargs)
@ -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.
@ -105,14 +103,13 @@ class TabbedTableView(tables.MultiTableMixin, TabView):
'tab': tab}
def get_tables(self):
""" A no-op on this class. Tables are handled at the tab level. """
"""A no-op on this class. Tables are handled at the tab level."""
# Override the base class implementation so that the MultiTableMixin
# doesn't freak out. We do the processing at the TableTab level.
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()))
@ -45,7 +44,7 @@ def has_permissions_on_list(components, user):
@register.inclusion_tag('horizon/_nav_list.html', takes_context=True)
def horizon_main_nav(context):
""" Generates top-level dashboard navigation entries. """
"""Generates top-level dashboard navigation entries."""
if 'request' not in context:
return {}
current_dashboard = context['request'].horizon.get('dashboard', None)
@ -63,7 +62,7 @@ def horizon_main_nav(context):
@register.inclusion_tag('horizon/_subnav_list.html', takes_context=True)
def horizon_dashboard_nav(context):
""" Generates sub-navigation entries for the current dashboard. """
"""Generates sub-navigation entries for the current dashboard."""
if 'request' not in context:
return {}
dashboard = context['request'].horizon['dashboard']
@ -97,7 +96,7 @@ def quota(val, units=None):
class JSTemplateNode(template.Node):
""" Helper node for the ``jstemplate`` template tag. """
"""Helper node for the ``jstemplate`` template tag."""
def __init__(self, nodelist):
self.nodelist = nodelist
@ -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

@ -73,8 +73,9 @@ 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. """
"""Takes a size value in mb, and prints returns the data in a
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()
@ -116,7 +115,7 @@ class BaseHorizonTests(test.TestCase):
class HorizonTests(BaseHorizonTests):
def test_registry(self):
""" Verify registration and autodiscovery work correctly.
"""Verify registration and autodiscovery work correctly.
Please note that this implicitly tests that autodiscovery works
by virtue of the fact that the dashboards listed in
@ -210,12 +209,12 @@ class HorizonTests(BaseHorizonTests):
reversed(urlpatterns)
def test_horizon_test_isolation_1(self):
""" Isolation Test Part 1: sets a value. """
"""Isolation Test Part 1: sets a value."""
cats = horizon.get_dashboard("cats")
cats.evil = True
def test_horizon_test_isolation_2(self):
""" Isolation Test Part 2: The value set in part 1 should be gone. """
"""Isolation Test Part 2: The value set in part 1 should be gone."""
cats = horizon.get_dashboard("cats")
self.assertFalse(hasattr(cats, "evil"))
@ -299,7 +298,7 @@ class HorizonTests(BaseHorizonTests):
class CustomPanelTests(BaseHorizonTests):
""" Test customization of dashboards and panels
"""Test customization of dashboards and panels
using 'customization_module' to HORIZON_CONFIG.
"""
@ -334,7 +333,7 @@ class CustomPanelTests(BaseHorizonTests):
class CustomPermissionsTests(BaseHorizonTests):
""" Test customization of permissions on panels
"""Test customization of permissions on panels
using 'customization_module' to HORIZON_CONFIG.
"""

View File

@ -190,7 +190,7 @@ class NoActionsTable(tables.DataTable):
class DataTableTests(test.TestCase):
def test_table_instantiation(self):
""" Tests everything that happens when the table is instantiated. """
"""Tests everything that happens when the table is instantiated."""
self.table = MyTable(self.request, TEST_DATA)
# Properties defined on the table
self.assertEqual(self.table.data, TEST_DATA)

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

@ -16,28 +16,25 @@ from django.forms.util import flatatt # noqa
class HTMLElement(object):
""" A generic base class that gracefully handles html-style attributes. """
"""A generic base class that gracefully handles html-style attributes."""
def __init__(self):
self.attrs = getattr(self, "attrs", {})
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

@ -22,12 +22,12 @@ from horizon import exceptions
def user_home(request):
""" Reversible named view to direct a user to the appropriate homepage. """
"""Reversible named view to direct a user to the appropriate homepage."""
return shortcuts.redirect(horizon.get_user_home(request.user))
class APIView(generic.TemplateView):
""" A quick class-based view for putting API data into a template.
"""A quick class-based view for putting API data into a template.
Subclasses must define one method, ``get_data``, and a template name
via the ``template_name`` attribute on the class.
@ -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
@ -154,7 +153,7 @@ class Action(forms.Form):
bound_field.choices = meth(request, context)
def get_help_text(self, extra_context=None):
""" Returns the help text for this step. """
"""Returns the help text for this step."""
text = ""
extra_context = extra_context or {}
if self.help_text_template:
@ -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.
@ -391,7 +384,7 @@ class Step(object):
return context
def get_id(self):
""" Returns the ID for this step. Suitable for use in HTML markup. """
"""Returns the ID for this step. Suitable for use in HTML markup."""
return "%s__%s" % (self.workflow.slug, self.slug)
def _verify_contributions(self, context):
@ -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.
@ -427,7 +419,7 @@ class Step(object):
return context
def render(self):
""" Renders the step. """
"""Renders the step."""
step_template = template.loader.get_template(self.template_name)
extra_context = {"form": self.action,
"step": self}
@ -435,21 +427,17 @@ class Step(object):
return step_template.render(context)
def get_help_text(self):
""" Returns the help text for this step. """
"""Returns the help text for this step."""
text = linebreaks(force_unicode(self.help_text))
text += self.action.get_help_text()
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:
@ -665,7 +652,7 @@ class Workflow(html.HTMLElement):
return self._ordered_steps
def get_step(self, slug):
""" Returns the instantiated step matching the given slug. """
"""Returns the instantiated step matching the given slug."""
for step in self.steps:
if step.slug == slug:
return step
@ -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.
@ -736,7 +722,7 @@ class Workflow(html.HTMLElement):
@classmethod
def register(cls, step_class):
""" Registers a :class:`~horizon.workflows.Step` with the workflow. """
"""Registers a :class:`~horizon.workflows.Step` with the workflow."""
if not inspect.isclass(step_class):
raise ValueError('Only classes may be registered.')
elif not issubclass(step_class, cls._registerable_class):
@ -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
@ -846,7 +825,7 @@ class Workflow(html.HTMLElement):
return message
def render(self):
""" Renders the workflow. """
"""Renders the workflow."""
workflow_template = template.loader.get_template(self.template_name)
extra_context = {"workflow": self}
if self.request.is_ajax():
@ -855,7 +834,7 @@ class Workflow(html.HTMLElement):
return workflow_template.render(context)
def get_absolute_url(self):
""" Returns the canonical URL for this workflow.
"""Returns the canonical URL for this workflow.
This is used for the POST action attribute on the form element
wrapping the workflow.
@ -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,14 +64,13 @@ 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)
def get_workflow(self):
""" Returns the instanciated workflow class. """
"""Returns the instanciated workflow class."""
extra_context = self.get_initial()
entry_point = self.request.GET.get("step", None)
workflow = self.workflow_class(self.request,
@ -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.
@ -99,7 +96,7 @@ class WorkflowView(generic.TemplateView):
return context
def get_template_names(self):
""" Returns the template name to use for this request. """
"""Returns the template name to use for this request."""
if self.request.is_ajax():
template = self.ajax_template_name
else:
@ -122,13 +119,13 @@ class WorkflowView(generic.TemplateView):
workflow.add_error_to_step(error_msg, step)
def get(self, request, *args, **kwargs):
""" Handler for HTTP GET requests. """
"""Handler for HTTP GET requests."""
context = self.get_context_data(**kwargs)
self.set_workflow_step_errors(context)
return self.render_to_response(context)
def post(self, request, *args, **kwargs):
""" Handler for HTTP POST requests. """
"""Handler for HTTP POST requests."""
context = self.get_context_data(**kwargs)
workflow = context[self.context_object_name]
if workflow.is_valid():

View File

@ -34,7 +34,7 @@ LOG = logging.getLogger(__name__)
class APIVersionManager(object):
""" Object to store and manage API versioning data and utility methods. """
"""Object to store and manage API versioning data and utility methods."""
SETTINGS_KEY = "OPENSTACK_API_VERSIONS"
@ -67,10 +67,10 @@ 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
Define _attrs on the child class and pass in the
api object as the only argument to the constructor
"""
_attrs = []
@ -97,14 +97,14 @@ class APIResourceWrapper(object):
class APIDictWrapper(object):
""" Simple wrapper for api dictionaries
"""Simple wrapper for api dictionaries
Some api calls return dictionaries. This class provides identical
behavior as APIResourceWrapper, except that it will also behave as a
dictionary, in addition to attribute accesses.
Some api calls return dictionaries. This class provides identical
behavior as APIResourceWrapper, except that it will also behave as a
dictionary, in addition to attribute accesses.
Attribute access is the preferred method of access, to be
consistent with api resource objects from novaclient.
Attribute access is the preferred method of access, to be
consistent with api resource objects from novaclient.
"""
def __init__(self, apidict):
self._apidict = apidict
@ -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)))
@ -34,7 +33,7 @@ def is_iterable(var):
def make_query(user_id=None, tenant_id=None, resource_id=None,
user_ids=None, tenant_ids=None, resource_ids=None):
""" Returns query built form given parameters.
"""Returns query built form given parameters.
This query can be then used for querying resources, meters and
statistics.
@ -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']
@ -140,7 +137,7 @@ class Resource(base.APIResourceWrapper):
class ResourceAggregate(Resource):
""" Represents aggregate of more resources together.
"""Represents aggregate of more resources together.
Aggregate of resources can be obtain by specifing
multiple ids in one parameter or by not specifying
@ -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',
@ -224,11 +219,11 @@ class Statistic(base.APIResourceWrapper):
class GlobalDiskUsage(base.APIResourceWrapper):
""" Represents collection of resources with statistic of defined meters.
"""Represents collection of resources with statistic of defined meters.
Resources are filtered either by given default query or by
meters in python. It's preferred to use default_query as it is more
effective.
Resources are filtered either by given default query or by
meters in python. It's preferred to use default_query as it is more
effective.
"""
_attrs = ["id", "tenant", "user", "resource", "disk_read_bytes",
@ -247,11 +242,11 @@ class GlobalDiskUsage(base.APIResourceWrapper):
class GlobalNetworkTrafficUsage(base.APIResourceWrapper):
""" Represents collection of resources with statistic of defined meters.
"""Represents collection of resources with statistic of defined meters.
Resources are filtered either by given default query or by
meters in python. It's preferred to use default_query as it is more
effective.
Resources are filtered either by given default query or by
meters in python. It's preferred to use default_query as it is more
effective.
"""
_attrs = ["id", "tenant", "user", "resource", "network_incoming_bytes",
@ -270,11 +265,11 @@ class GlobalNetworkTrafficUsage(base.APIResourceWrapper):
class GlobalNetworkUsage(base.APIResourceWrapper):
""" Represents collection of resources with statistic of defined meters.
"""Represents collection of resources with statistic of defined meters.
Resources are filtered either by given default query or by
meters in python. It's preferred to use default_query as it is more
effective.
Resources are filtered either by given default query or by
meters in python. It's preferred to use default_query as it is more
effective.
"""
_attrs = ["id", "tenant", "user", "resource", "network", "network_create",
@ -294,11 +289,11 @@ class GlobalNetworkUsage(base.APIResourceWrapper):
class GlobalObjectStoreUsage(base.APIResourceWrapper):
""" Represents collection of resources with statistic of defined meters.
"""Represents collection of resources with statistic of defined meters.
Resources are filtered either by given default query or by
meters in python. It's preferred to use default_query as it is more
effective.
Resources are filtered either by given default query or by
meters in python. It's preferred to use default_query as it is more
effective.
"""
_attrs = ["id", "tenant", "user", "resource", "storage_objects",
@ -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)
@ -359,8 +353,8 @@ def statistic_list(request, meter_name, query=None, period=None):
class ThreadedUpdateResourceWithStatistics(threading.Thread):
""" Multithread wrapper for update_with_statistics method of
resource_usage.
"""Multithread wrapper for update_with_statistics method of
resource_usage.
A join logic is placed in process_list class method. All resources
will have its statistics attribute filled in separate threads.
@ -426,7 +420,7 @@ class ThreadedUpdateResourceWithStatistics(threading.Thread):
class CeilometerUsage(object):
""" Represents wrapper of any Ceilometer queries.
"""Represents wrapper of any Ceilometer queries.
One instance of this class should be shared between resources
as this class provides a place where users and tenants are
@ -448,7 +442,7 @@ class CeilometerUsage(object):
self._tenants = {}
def get_user(self, user_id):
""" Returns user fetched form API
"""Returns user fetched form API
Caching the result, so it doesn't contact API twice with the
same query
@ -462,7 +456,7 @@ class CeilometerUsage(object):
return user
def preload_all_users(self):
""" Preloads all users into dictionary.
"""Preloads all users into dictionary.
It's more effective to preload all users, rather the fetching many
users by separate API get calls.
@ -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
@ -489,7 +483,7 @@ class CeilometerUsage(object):
return tenant
def preload_all_tenants(self):
""" Preloads all teannts into dictionary.
"""Preloads all teannts into dictionary.
It's more effective to preload all tenants, rather the fetching many
tenants by separate API get calls.
@ -504,7 +498,7 @@ class CeilometerUsage(object):
def global_data_get(self, used_cls=None, query=None,
with_statistics=False, additional_query=None,
with_users_and_tenants=True):
""" Obtaining a resources for table view.
"""Obtaining a resources for table view.
It obtains resources with statistics data according to declaration
in used_cls class.
@ -534,10 +528,9 @@ class CeilometerUsage(object):
filter_func = None
def filter_resources(resource):
""" Method for filtering resources by theirs links.rel attr.
"""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,
@ -577,7 +569,7 @@ class CeilometerUsage(object):
def global_network_traffic_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=GlobalNetworkTrafficUsage,
@ -587,7 +579,7 @@ class CeilometerUsage(object):
def global_network_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=GlobalNetworkUsage,
@ -597,7 +589,7 @@ class CeilometerUsage(object):
def global_object_store_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.
"""
# TODO(lsmola) This call uses all tenants now. When ajax pagination
# is added, it needs to obtain only paginated tenants.
@ -609,7 +601,7 @@ class CeilometerUsage(object):
additional_query=additional_query)
def query_from_object_id(self, object_id):
""" Obtaining a query from resource id.
"""Obtaining a query from resource id.
Query can be then used to identify a resource in resources or meters
API calls. ID is being built in the Resource initializer, or returned
@ -625,7 +617,7 @@ class CeilometerUsage(object):
def update_with_statistics(self, resource, meter_names=None, period=None,
stats_attr=None, additional_query=None):
""" Adding statistical data into one Resource or ResourceAggregate.
"""Adding statistical data into one Resource or ResourceAggregate.
It adds each statistic of each meter_names into the resource
attributes. Attribute name is the meter name with replaced '.' to '_'.
@ -684,7 +676,7 @@ class CeilometerUsage(object):
def resources(self, query=None, filter_func=None,
with_users_and_tenants=False):
""" Obtaining resources with the query or filter_func.
"""Obtaining resources with the query or filter_func.
Obtains resources and also fetch tenants and users associated
with those resources if with_users_and_tenants flag is true.
@ -712,7 +704,7 @@ class CeilometerUsage(object):
period=None, filter_func=None,
stats_attr=None, additional_query=None,
with_users_and_tenants=False):
""" Obtaining resources with statistics data inside.
"""Obtaining resources with statistics data inside.
:Parameters:
- `query`: Query for fetching the Ceilometer Resources.
@ -745,7 +737,7 @@ class CeilometerUsage(object):
return resources
def resource_aggregates(self, queries=None):
""" Obtaining resource aggregates with queries.
"""Obtaining resource aggregates with queries.
Representing a resource aggregate by query is a most general way
how to obtain a resource aggregates.
@ -764,7 +756,7 @@ class CeilometerUsage(object):
def resource_aggregates_with_statistics(self, queries=None,
meter_names=None, period=None, filter_func=None, stats_attr=None,
additional_query=None):
""" Obtaining resource aggregates with statistics data inside.
"""Obtaining resource aggregates with statistics data inside.
:Parameters:
- `queries`: Dictionary of named queries that defines a bulk of

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

@ -74,7 +74,7 @@ except ImportError:
class Service(base.APIDictWrapper):
""" Wrapper for a dict based on the service data from keystone. """
"""Wrapper for a dict based on the service data from keystone."""
_attrs = ['id', 'type', 'name']
def __init__(self, service, region, *args, **kwargs):
@ -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.
"""
@ -482,7 +481,7 @@ def role_delete(request, role_id):
def role_list(request):
""" Returns a global list of available roles. """
"""Returns a global list of available roles."""
return keystoneclient(request, admin=True).roles.list()
@ -496,7 +495,7 @@ def roles_for_user(request, user, project):
def add_tenant_user_role(request, project=None, user=None, role=None,
group=None, domain=None):
""" Adds a role for a user on a tenant. """
"""Adds a role for a user on a tenant."""
manager = keystoneclient(request, admin=True).roles
if VERSIONS.active < 3:
return manager.add_user_role(user, role, project)
@ -507,7 +506,7 @@ def add_tenant_user_role(request, project=None, user=None, role=None,
def remove_tenant_user_role(request, project=None, user=None, role=None,
group=None, domain=None):
""" Removes a given single role for a user from a tenant. """
"""Removes a given single role for a user from a tenant."""
manager = keystoneclient(request, admin=True).roles
if VERSIONS.active < 3:
return manager.remove_user_role(user, role, project)
@ -517,7 +516,7 @@ def remove_tenant_user_role(request, project=None, user=None, role=None,
def remove_tenant_user(request, project=None, user=None, domain=None):
""" Removes all roles from a user on a tenant, removing them from it. """
"""Removes all roles from a user on a tenant, removing them from it."""
client = keystoneclient(request, admin=True)
roles = client.roles.roles_for_user(user, project)
for role in roles:
@ -531,22 +530,22 @@ def roles_for_group(request, group, domain=None, project=None):
def add_group_role(request, role, group, domain=None, project=None):
""" Adds a role for a group on a domain or project ."""
"""Adds a role for a group on a domain or project."""
manager = keystoneclient(request, admin=True).roles
return manager.grant(role=role, group=group, domain=domain,
project=project)
def remove_group_role(request, role, group, domain=None, project=None):
""" Removes a given single role for a group from a domain or project. """
"""Removes a given single role for a group from a domain or project."""
manager = keystoneclient(request, admin=True).roles
return manager.revoke(role=role, group=group, project=project,
domain=domain)
def remove_group_roles(request, group, domain=None, project=None):
""" Removes all roles from a group on a domain or project,
removing them from it.
"""Removes all roles from a group on a domain or project,
removing them from it.
"""
client = keystoneclient(request, admin=True)
roles = client.roles.list(group=group, domain=domain, project=project)
@ -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

@ -166,7 +166,7 @@ class SecurityGroup(base.APIResourceWrapper):
class SecurityGroupRule(base.APIResourceWrapper):
""" Wrapper for individual rules in a SecurityGroup. """
"""Wrapper for individual rules in a SecurityGroup."""
_attrs = ['id', 'ip_protocol', 'from_port', 'to_port', 'ip_range', 'group']
def __unicode__(self):
@ -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

@ -75,7 +75,7 @@ class PseudoFolder(base.APIDictWrapper):
def _objectify(items, container_name):
""" Splits a listing of objects into their appropriate wrapper classes. """
"""Splits a listing of objects into their appropriate wrapper classes."""
objects = []
# Deal with objects and object pseudo-folders first, save subdirs for later

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

@ -25,7 +25,7 @@ from django.conf import settings # noqa
def openstack(request):
""" Context processor necessary for OpenStack Dashboard functionality.
"""Context processor necessary for OpenStack Dashboard functionality.
The following variables are added to the request context:

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

@ -72,7 +72,7 @@ class ModifyAccess(tables.LinkAction):
class FlavorFilterAction(tables.FilterAction):
def filter(self, table, flavors, filter_string):
""" Really naive case-insensitive search. """
"""Really naive case-insensitive search."""
q = filter_string.lower()
def comp(flavor):

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

@ -68,5 +68,5 @@ class UpdateView(views.UpdateView):
class DetailView(views.DetailView):
""" Admin placeholder for image detail view. """
"""Admin placeholder for image detail view."""
pass

View File

@ -60,7 +60,7 @@ class AdminUpdateRow(project_tables.UpdateRow):
class AdminInstanceFilterAction(tables.FilterAction):
def filter(self, table, instances, filter_string):
""" Naive case-insensitive search. """
"""Naive case-insensitive search."""
q = filter_string.lower()
return [instance for instance in instances
if q in instance.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)
@ -214,7 +214,7 @@ class GlobalStatsTab(tabs.Tab):
meter_titles[name] = hint
class MetersWrap(object):
""" A quick wrapper for meter and associated titles. """
"""A quick wrapper for meter and associated titles."""
def __init__(self, meter, meter_titles):
self.name = meter
self.title = meter_titles.get(meter, "")

View File

@ -174,7 +174,7 @@ class SamplesView(TemplateView):
query = []
def filter_by_meter_name(resource):
""" Function for filtering of the list of resources.
"""Function for filtering of the list of resources.
Will pick the right resources according to currently selected
meter.

View File

@ -109,7 +109,7 @@ class DeleteTenantsAction(tables.DeleteAction):
class TenantFilterAction(tables.FilterAction):
def filter(self, table, tenants, filter_string):
""" Really naive case-insensitive search. """
"""Really naive case-insensitive search."""
# FIXME(gabriel): This should be smarter. Written for demo purposes.
q = filter_string.lower()

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

@ -36,7 +36,7 @@ class DeleteVolumeType(tables.DeleteAction):
class VolumesFilterAction(tables.FilterAction):
def filter(self, table, volumes, filter_string):
""" Naive case-insensitive search. """
"""Naive case-insensitive search."""
q = filter_string.lower()
return [volume for volume in volumes
if q in volume.display_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

@ -61,7 +61,7 @@ class ContainerView(browsers.ResourceBrowserView):
@cached_property
def objects(self):
""" Returns a list of objects given the subfolder's path.
"""Returns a list of objects given the subfolder's path.
The path is from the kwargs of the request.
"""
@ -93,13 +93,13 @@ class ContainerView(browsers.ResourceBrowserView):
return getattr(item, "content_type", None) == content_type
def get_objects_data(self):
""" Returns a list of objects within the current folder. """
"""Returns a list of objects within the current folder."""
filtered_objects = [item for item in self.objects
if not self.is_subdir(item)]
return filtered_objects
def get_subfolders_data(self):
""" Returns a list of subfolders within the current folder. """
"""Returns a list of subfolders within the current folder."""
filtered_objects = [item for item in self.objects
if self.is_subdir(item)]
return filtered_objects

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

@ -548,7 +548,7 @@ TASK_DISPLAY_CHOICES = (
class InstancesFilterAction(tables.FilterAction):
def filter(self, table, instances, filter_string):
""" Naive case-insensitive search. """
"""Naive case-insensitive search."""
q = filter_string.lower()
return [instance for instance in instances
if q in instance.name.lower()]

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):
@ -184,7 +185,7 @@ class VolumesTableBase(tables.DataTable):
class VolumesFilterAction(tables.FilterAction):
def filter(self, table, volumes, filter_string):
""" Naive case-insensitive search. """
"""Naive case-insensitive search."""
q = filter_string.lower()
return [volume for volume in volumes
if q in volume.display_name.lower()]
@ -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

@ -46,7 +46,7 @@ def get_tenant_choices(request):
class CreateNetworkProfile(forms.SelfHandlingForm):
""" Create Network Profile form."""
"""Create Network Profile form."""
name = forms.CharField(max_length=255,
label=_("Name"),
@ -115,7 +115,7 @@ class CreateNetworkProfile(forms.SelfHandlingForm):
class UpdateNetworkProfile(forms.SelfHandlingForm):
""" Update Network Profile form."""
"""Update Network Profile form."""
profile_id = forms.CharField(label=_("ID"),
widget=forms.HiddenInput())

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.
@ -79,7 +78,7 @@ class TestData(object):
class TestDataContainer(object):
""" A container for test data objects.
"""A container for test data objects.
The behavior of this class is meant to mimic a "manager" class, which
has convenient shortcuts for common actions like "list", "filter", "get",
@ -89,7 +88,7 @@ class TestDataContainer(object):
self._objects = []
def add(self, *args):
""" Add a new object to this container.
"""Add a new object to this container.
Generally this method should only be used during data loading, since
adding data during a test can affect the results of other tests.
@ -99,12 +98,11 @@ class TestDataContainer(object):
self._objects.append(obj)
def list(self):
""" Returns a list of all objects in this container. """
"""Returns a list of all objects in this container."""
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.
"""
@ -135,7 +132,7 @@ class TestDataContainer(object):
return matches.pop()
def first(self):
""" Returns the first object from this container. """
"""Returns the first object from this container."""
return self._objects[0]
def count(self):

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

@ -60,7 +60,7 @@ QUOTA_FIELDS = NOVA_QUOTA_FIELDS + CINDER_QUOTA_FIELDS + NEUTRON_QUOTA_FIELDS
class QuotaUsage(dict):
""" Tracks quota limit, used, and available for a given set of quotas."""
"""Tracks quota limit, used, and available for a given set of quotas."""
def __init__(self):
self.usages = defaultdict(dict)
@ -77,7 +77,7 @@ class QuotaUsage(dict):
return repr(dict(self.usages))
def add_quota(self, quota):
""" Adds an internal tracking reference for the given quota. """
"""Adds an internal tracking reference for the given quota."""
if quota.limit is None or quota.limit == -1:
# Handle "unlimited" quotas.
self.usages[quota.name]['quota'] = float("inf")
@ -86,7 +86,7 @@ class QuotaUsage(dict):
self.usages[quota.name]['quota'] = int(quota.limit)
def tally(self, name, value):
""" Adds to the "used" metric for the given quota. """
"""Adds to the "used" metric for the given quota."""
value = value or 0 # Protection against None.
# Start at 0 if this is the first value.
if 'used' not in self.usages[name]:
@ -96,7 +96,7 @@ class QuotaUsage(dict):
self.update_available(name)
def update_available(self, name):
""" Updates the "available" metric for the given quota. """
"""Updates the "available" metric for the given quota."""
available = self.usages[name]['quota'] - self.usages[name]['used']
if available < 0:
available = 0

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