Enable hacking/flake8 rules

This commit enables and fixes previously disabled E and F rules:

* E111 indentation is not a multiple of four
* E113 unexpected indentation
* E265 block comment should start with '# '
* H236 Python 3.x incompatible __metaclass__, use six.add_metaclass()
* H238 old style class declaration, use new style (inherit from `object`)
* H405 multi line docstring summary not separated with an empty line
* H701 Empty localization string

Change-Id: Ie0af0d450f81cb5bf274192e6fdce3e41ccb7f88
Closes-Bug: #1478002
This commit is contained in:
Kirill Zaitsev 2015-07-24 17:54:22 +03:00
parent 80c54a6580
commit f847c50466
24 changed files with 131 additions and 99 deletions

View File

@ -76,7 +76,7 @@ def handled_exceptions(request):
def _get_endpoint(request):
#prefer location specified in settings for dev purposes
# prefer location specified in settings for dev purposes
endpoint = getattr(settings, 'MURANO_API_URL', None)
if not endpoint:

View File

@ -133,7 +133,9 @@ def create_quick_environment(request):
def update_latest_apps(func):
"""Adds package id to a session queue with Applications which were
"""Update 'app_id's in session
Adds package id to a session queue with Applications which were
recently added to an environment or to the Catalog itself. Thus it is
used as decorator for views adding application to an environment or
uploading new package definition to a catalog.
@ -170,7 +172,9 @@ def clean_latest_apps(request):
def clear_forms_data(func):
"""Clears user's session from a data for a specific application. It
"""Removes form data from session
Clears user's session from a data for a specific application. It
guarantees that previous additions of that application won't interfere
with the next ones. Should be used as a decorator for entry points for
adding an application in an environment.
@ -239,7 +243,9 @@ def get_supplier_image(request, app_id):
class LazyWizard(wizard_views.SessionWizardView):
"""The class which defers evaluation of form_list and condition_dict
"""Lazy version of SessionWizardView
The class which defers evaluation of form_list and condition_dict
until view method is called. So, each time we load a page with a dynamic
UI form, it will have markup/logic from the newest YAML-file definition.
"""
@ -431,7 +437,9 @@ class IndexView(list_view.ListView):
return datum.id
def get_marker(self, index=-1):
"""Returns the identifier for the object indexed by ``index`` in the
"""Get the pagination marker
Returns the identifier for the object indexed by ``index`` in the
current data set for APIs that use marker/limit-based paging.
"""
data = self.object_list

View File

@ -57,7 +57,7 @@ class CategoriesTable(tables.DataTable):
package_count = tables.Column('package_count',
verbose_name=_('Package Count'))
class Meta:
class Meta(object):
name = 'categories'
verbose_name = _('Application Categories')
table_actions = (AddCategory,)

View File

@ -33,7 +33,9 @@ def ensure_python_obj(obj):
class Bunch(object):
"""Bunch is a container that provides both dictionary-like and
"""Bunch dict/object-like container.
Bunch container provides both dictionary-like and
object-like attribute access.
"""
def __init__(self, **kwargs):

View File

@ -34,7 +34,7 @@ class ManagePanels(horizon.PanelGroup):
class Murano(horizon.Dashboard):
name = _(getattr(settings, 'MURANO_DASHBOARD_NAME', "Murano"))
name = getattr(settings, 'MURANO_DASHBOARD_NAME', _("Murano"))
slug = "murano"
panels = (DeployPanels, ManagePanels)
default_panel = "environments"

View File

@ -45,7 +45,9 @@ LOG = logging.getLogger(__name__)
def with_request(func):
"""The decorator is meant to be used together with `UpdatableFieldsForm':
"""Injects request into func
The decorator is meant to be used together with `UpdatableFieldsForm':
apply it to the `update' method of fields inside that form.
"""
def update(self, initial, request=None, **kwargs):
@ -70,7 +72,7 @@ def with_request(func):
def make_yaql_validator(validator_property):
"""Field-level validator uses field's value as its '$' root object."""
expr = validator_property['expr'].spec
message = _(validator_property.get('message', ''))
message = validator_property.get('message', '')
def validator_func(value):
context = yaql.create_context()
@ -229,7 +231,7 @@ class PasswordField(CharField):
self.label, defaultfilters.pluralize(2)))
class PasswordInput(forms.PasswordInput):
class Media:
class Media(object):
js = ('muranodashboard/js/passwordfield.js',)
def __init__(self, label, *args, **kwargs):
@ -470,7 +472,7 @@ class ClusterIPField(CharField):
msg = "Could not found fixed ips for ip %s" % (ip,)
LOG.error(msg)
exceptions.handle(
request, _(msg),
request, msg,
ignore=True)
else:
if ip_info.hostname:
@ -530,9 +532,9 @@ class ClusterIPField(CharField):
class DatabaseListField(CharField):
validate_mssql_identifier = django_validator.RegexValidator(
re.compile(r'^[a-zA-z_][a-zA-Z0-9_$#@]*$'),
_((u'First symbol should be latin letter or underscore. Subsequent ' +
u'symbols can be latin letter, numeric, underscore, at sign, ' +
u'number sign or dollar sign')))
_(u'First symbol should be latin letter or underscore. Subsequent '
u'symbols can be latin letter, numeric, underscore, at sign, '
u'number sign or dollar sign'))
default_error_messages = {'invalid': validate_mssql_identifier.message}
@ -562,7 +564,7 @@ def make_select_cls(fqns):
attrs['class'] += ' murano_add_select'
super(Widget, self).__init__(attrs=attrs, **kwargs)
class Media:
class Media(object):
js = ('muranodashboard/js/add-select.js',)
class DynamicSelect(hz_forms.DynamicChoiceField, CustomPropertiesField):
@ -571,7 +573,7 @@ def make_select_cls(fqns):
def __init__(self, empty_value_message=None, *args, **kwargs):
super(DynamicSelect, self).__init__(*args, **kwargs)
if empty_value_message is not None:
self.empty_value_message = _(empty_value_message)
self.empty_value_message = empty_value_message
else:
self.empty_value_message = _('Select Application')

View File

@ -73,7 +73,7 @@ def _collect_fields(field_specs, form_name, service):
del kwargs['widget_media']
class Widget(widget):
class Media:
class Media(object):
js = media.get('js', ())
css = media.get('css', {})
widget = Widget
@ -103,7 +103,7 @@ def _collect_fields(field_specs, form_name, service):
elif isinstance(spec, types.ListType):
return key, [parse_spec(_spec, keys)[1] for _spec in spec]
elif isinstance(spec, basestring) and helpers.is_localizable(keys):
return key, _(spec)
return key, spec
else:
if key == 'hidden':
if spec:
@ -141,7 +141,9 @@ class DynamicFormMetaclass(forms.forms.DeclarativeFieldsMetaclass):
class UpdatableFieldsForm(forms.Form):
"""This class is supposed to be a base for forms belonging to a FormWizard
"""Dynamic updatable form
This class is supposed to be a base for forms belonging to a FormWizard
descendant, or be used as a mixin for workflows.Action class.
In first case the `request' used in `update' method is provided in
@ -208,7 +210,8 @@ class ServiceConfigurationForm(UpdatableFieldsForm):
for validator in self.validators:
expr = validator['expr']
if not expr.evaluate(data=all_data, context=self.context):
error_messages.append(_(validator.get('message', '')))
error_messages.append(validator.get('message',
_('Validation Error occurred')))
if error_messages:
raise forms.ValidationError(error_messages)

View File

@ -118,8 +118,7 @@ def insert_hidden_ids(application):
def int2base(x, base):
"""Converts decimal integers into another number base
from base-2 to base-36.
"""Converts decimal integers to another number base from base-2 to base-36
:param x: decimal integer
:param base: number base, max value is 36

View File

@ -19,6 +19,7 @@ import yaql
from django.utils.encoding import force_text
from django.utils.translation import ugettext_lazy as _
import six
from muranodashboard.api import packages as pkg_api
from muranodashboard.catalog import forms as catalog_forms
@ -42,7 +43,9 @@ _apps = {}
class Service(object):
"""Class for keeping service persistent data, the most important are two:
"""Murano Service representation object
Class for keeping service persistent data, the most important are two:
``self.forms`` list of service's steps (as Django form classes) and
``self.cleaned_data`` dictionary of data from service validated steps.
@ -85,9 +88,8 @@ class Service(object):
def _add_form(self, _name, _specs, _validators, _verbose_name=None):
import muranodashboard.dynamic_ui.forms as forms
class Form(forms.ServiceConfigurationForm):
__metaclass__ = forms.DynamicFormMetaclass
class Form(six.with_metaclass(forms.DynamicFormMetaclass,
forms.ServiceConfigurationForm)):
service = self
name = _name
verbose_name = _verbose_name
@ -111,9 +113,7 @@ class Service(object):
return helpers.evaluate(self.application, self.context)
def get_data(self, form_name, expr, data=None):
"""First try to get value from cleaned data, if none
found, use raw data.
"""
"""Try to get value from cleaned data, if none found, use raw data."""
if data:
self.update_cleaned_data(data, form_name=form_name)
data = self.cleaned_data

View File

@ -36,8 +36,10 @@ _random_string_counter = None
@yaql.context.EvalArg('pattern', types.StringTypes)
@yaql.context.EvalArg('number', types.IntType)
def _generate_hostname(pattern, number):
"""Replace '#' char in pattern with supplied number, if no pattern is
supplied generate short and unique name for the host.
"""Generates hostname based on pattern
Replaces '#' char in pattern with supplied number, if no pattern is
supplied generates short and unique name for the host.
:param pattern: hostname pattern
:param number: number to replace with in pattern

View File

@ -53,14 +53,16 @@ def create_session(request, environment_id):
class Session(object):
@staticmethod
def get_or_create(request, environment_id):
"""Gets id from already opened session for specified environment,
"""Get an open session id
Gets id from already opened session for specified environment,
otherwise opens new session and returns it's id
:param request:
:param environment_id:
:return: Session Id
"""
#We store opened sessions for each environment in dictionary per user
# We store opened sessions for each environment in dictionary per user
sessions = request.session.get('sessions', {})
if environment_id in sessions:
@ -71,7 +73,9 @@ class Session(object):
@staticmethod
def get_or_create_or_delete(request, environment_id):
"""Gets id from session in open state for specified environment,
"""Get an open session id
Gets id from session in open state for specified environment,
if state is deployed - this session will be deleted and new
would be created. If there are no any sessions new would be created.
Returns if of chosen or created session.
@ -111,14 +115,16 @@ class Session(object):
@staticmethod
def get(request, environment_id):
"""Gets id from already opened session for specified environment,
"""Get an open session id
Gets id from already opened session for specified environment,
otherwise returns None
:param request:
:param environment_id:
:return: Session Id
"""
#We store opened sessions for each environment in dictionary per user
# We store opened sessions for each environment in dictionary per user
sessions = request.session.get('sessions', {})
session_id = sessions.get(environment_id, '')
if session_id:
@ -156,7 +162,7 @@ def environments_list(request):
def environment_create(request, parameters):
#name is required param
# name is required param
body = {'name': parameters['name']}
if 'defaultNetworks' in parameters:
body['defaultNetworks'] = parameters['defaultNetworks']

View File

@ -18,7 +18,7 @@ import tempfile
from django.conf import settings
#---- Metadata Consts ----#
# ---- Metadata Consts ---- #
CHUNK_SIZE = 1 << 20 # 1MB
ARCHIVE_PKG_NAME = 'archive.tar.gz'
CACHE_DIR = getattr(settings, 'METADATA_CACHE_DIR',
@ -29,7 +29,7 @@ CACHE_REFRESH_SECONDS_INTERVAL = 5
DASHBOARD_ATTRS_KEY = '_26411a1861294160833743e45d0eaad9'
#---- Forms Consts ----#
# ---- Forms Consts ---- #
STATUS_ID_READY = 'ready'
STATUS_ID_PENDING = 'pending'
STATUS_ID_DEPLOYING = 'deploying'

View File

@ -117,9 +117,11 @@ class AbandonEnvironment(tables.DeleteAction):
redirect_url = "horizon:project:murano:environments"
def allowed(self, request, environment):
"""'Abandon Environment' button is hidden in several cases:
* environment is new
* app added to env, but not deploy is not started
"""Limit when 'Abandon Environment' button is shown
'Abandon Environment' button is hidden in several cases:
* environment is new
* app added to env, but not deploy is not started
"""
status = getattr(environment, 'status', None)
if status in [consts.STATUS_ID_NEW, consts.STATUS_ID_PENDING]:
@ -170,11 +172,13 @@ class DeployEnvironment(tables.BatchAction):
classes = ('btn-launch',)
def allowed(self, request, environment):
"""'Deploy environment' is not shown in several cases:
* when deploy is already in progress
* delete is in progress
* no new services added to the environment (after env creation
or successful deploy or delete failure)
"""Limit when 'Deploy Environment' button is shown
'Deploy environment' is not shown in several cases:
* when deploy is already in progress
* delete is in progress
* no new services added to the environment (after env creation
or successful deploy or delete failure)
"""
status = getattr(environment, 'status', None)
if (status != consts.STATUS_ID_DEPLOY_FAILURE
@ -201,11 +205,13 @@ class DeployThisEnvironment(tables.Action):
classes = ('btn-launch',)
def allowed(self, request, service):
"""'Deploy environment' is not shown in several cases:
* when deploy is already in progress
* delete is in progress
* env was just created and no apps added
* previous deployment finished successfully
"""Limit when 'Deploy Environment' button is shown
'Deploy environment' is not shown in several cases:
* when deploy is already in progress
* delete is in progress
* env was just created and no apps added
* previous deployment finished successfully
"""
status, version = _get_environment_status_and_version(request,
self.table)
@ -294,7 +300,7 @@ class EnvironmentsTable(tables.DataTable):
status_choices=consts.STATUS_CHOICES,
display_choices=consts.STATUS_DISPLAY_CHOICES)
class Meta:
class Meta(object):
name = 'murano'
verbose_name = _('Environments')
template = 'environments/_data_table.html'
@ -389,7 +395,7 @@ class ServicesTable(tables.DataTable):
actions.extend(sorted(app_actions, key=lambda x: x.name))
return actions
class Meta:
class Meta(object):
name = 'services'
verbose_name = _('Component List')
template = 'services/_data_table.html'
@ -427,7 +433,7 @@ class DeploymentsTable(tables.DataTable):
status=True,
display_choices=consts.DEPLOYMENT_STATUS_DISPLAY_CHOICES)
class Meta:
class Meta(object):
name = 'deployments'
verbose_name = _('Deployments')
template = 'common/_data_table.html'
@ -444,7 +450,7 @@ class EnvConfigTable(tables.DataTable):
def get_object_id(self, datum):
return datum['?']['id']
class Meta:
class Meta(object):
name = 'environment_configuration'
verbose_name = _('Deployed Components')
template = 'common/_data_table.html'

View File

@ -100,8 +100,8 @@ class OverviewTab(tabs.Tab):
if hasattr(service_data, 'floatingip'):
detail_info['Floating IP'] = service_data.floatingip
#TODO(efedorova): Need to determine Instance subclass
# after it would be possible
# TODO(efedorova): Need to determine Instance subclass
# after it would be possible
if hasattr(service_data,
'instance') and service_data['instance'] is not None:
instance, stack = get_instance_and_stack(

View File

@ -54,7 +54,7 @@ class MarkedImagesTable(tables.DataTable):
type = tables.Column('type', verbose_name=_('Type'))
title = tables.Column('title', verbose_name=_('Title'))
class Meta:
class Meta(object):
name = 'marked_images'
verbose_name = _('Marked Images')
template = 'common/_data_table.html'

View File

@ -178,11 +178,11 @@ class ModifyPackageForm(PackageParamsMixin, horizon_forms.SelfHandlingForm):
self.fields['categories'].initial = dict(
(key, True) for key in package.categories)
except (exc.HTTPException, Exception):
msg = 'Unable to get list of categories'
msg = _('Unable to get list of categories')
LOG.exception(msg)
redirect = reverse('horizon:murano:packages:index')
exceptions.handle(request,
_(msg),
msg,
redirect=redirect)
def handle(self, request, data):
@ -217,7 +217,7 @@ class ModifyPackageForm(PackageParamsMixin, horizon_forms.SelfHandlingForm):
LOG.exception(msg)
redirect = reverse('horizon:murano:packages:index')
exceptions.handle(request,
_(msg),
msg,
redirect=redirect)
@ -225,7 +225,7 @@ class SelectCategories(forms.Form):
categories = forms.MultipleChoiceField(
label=_('Application Category'),
choices=[('', 'No categories available')],
choices=[('', _('No categories available'))],
required=False)
def __init__(self, *args, **kwargs):
@ -238,9 +238,9 @@ class SelectCategories(forms.Form):
self.fields['categories'].choices = [(c, c)
for c in categories]
except (exc.HTTPException, Exception):
msg = 'Unable to get list of categories'
msg = _('Unable to get list of categories')
LOG.exception(msg)
redirect = reverse('horizon:murano:packages:index')
exceptions.handle(request,
_(msg),
msg,
redirect=redirect)

View File

@ -186,7 +186,7 @@ class PackageDefinitionsTable(tables.DataTable):
PackageDefinitionsTable, self).get_prev_pagination_string()
return pagination_string + "&sort_dir=desc"
class Meta:
class Meta(object):
name = 'packages'
prev_pagination_param = 'marker'
verbose_name = _('Package Definitions')

View File

@ -50,8 +50,10 @@ BUNDLE_FORMS = [('upload', forms.ImportBundleForm), ]
def is_app(wizard):
"""Return true if uploading package is an application.
In that case, category selection from need to be shown.
"""Check if we're uploading an application
Return true if uploading package is an application.
In that case, category selection from need to be shown.
"""
step_data = wizard.storage.get_step_data('upload')
if step_data:

View File

@ -27,8 +27,7 @@ from muranodashboard.tests.functional import utils
class TestSuiteSmoke(base.UITestCase):
"""This class keeps smoke tests which check operability of all main panels
"""
"""This class keeps smoke tests which check operability of main panels"""
def test_smoke_environments_panel(self):
self.go_to_submenu('Environments')
self.check_panel_is_present('Environments')
@ -157,7 +156,9 @@ class TestSuiteImage(base.ImageTestCase):
class TestSuiteFields(base.FieldsTestCase):
def test_check_domain_name_field_validation(self):
"""Test checks that validation of domain name field work
"""Check domain name validation
Test checks that validation of domain name field work
and appropriate error message is appeared after entering
incorrect domain name
@ -231,8 +232,7 @@ class TestSuiteFields(base.FieldsTestCase):
'they are used to delimit the components of domain style names')
def test_check_app_name_validation(self):
"""Test checks validation of field that usually define
application name
"""Test checks validation of field that usually define application name
Scenario:
1. Navigate to Application Catalog > Applications
@ -257,7 +257,9 @@ class TestSuiteFields(base.FieldsTestCase):
self.wait_element_is_clickable(by.By.XPATH, c.ButtonSubmit)
def test_check_required_field(self):
"""Test checks that fields with parameter 'required=True' in yaml form
"""Test required fields
Test checks that fields with parameter 'required=True' in yaml form
are truly required and can't be omitted
Scenario:
@ -333,7 +335,9 @@ class TestSuiteApplications(base.ApplicationTestCase):
self.check_element_on_page(by.By.NAME, "0-name")
def test_check_ability_create_two_dependent_apps(self):
"""Test checks that using one creation form it is possible to
"""Test using two dependent apps
Test checks that using one creation form it is possible to
add to related apps in the one environment
Scenario:
@ -398,7 +402,9 @@ class TestSuiteApplications(base.ApplicationTestCase):
c.App.format('MockApp'))
def test_filter_by_category(self):
"""Test checks ability to filter applications by category
"""Test filtering by category
Test checks ability to filter applications by category
in Application Catalog page
Scenario:
@ -539,7 +545,8 @@ class TestSuiteApplications(base.ApplicationTestCase):
"//*[contains(text(), 'Completed')]")
def test_check_info_about_app(self):
"""Test checks that information about app is available and tr
"""Test checks that information about app is available
Scenario:
1. Navigate to 'Application Catalog > Applications' panel
2. Choose some application and click on 'More info'
@ -557,8 +564,7 @@ class TestSuiteApplications(base.ApplicationTestCase):
self.driver.find_element_by_class_name('app_license')
def test_check_topology_page(self):
"""Test checks that topology tab is available
and topology page displays correctly
"""Test checks that topology tab is available displays correctly
Scenario:
1. Navigate Applications and click MockApp 'Quick Deploy'
@ -578,8 +584,7 @@ class TestSuiteApplications(base.ApplicationTestCase):
self.check_element_on_page(by.By.TAG_NAME, 'image')
def test_check_deployment_history(self):
"""Test checks that deployment history tab is available
and deployment logs are present and correctly
"""Test checks that deployment history tab is available logs are ok
Scenario:
1. Navigate Applications and click MockApp 'Quick Deploy'
@ -741,8 +746,8 @@ class TestSuitePackages(base.PackageTestCase):
def test_upload_package(self):
"""Test package uploading via Package Definitions view.
Skip category selection step.
Skips category selection step.
"""
self.navigate_to('Manage')
self.go_to_submenu('Package Definitions')

View File

@ -41,7 +41,9 @@ def upload_app_package(client, app_name, data):
def compose_package(app_name, manifest, package_dir,
require=None, archive_dir=None):
"""Composes package `app_name` with `manifest` file as a template for the
"""Composes a murano package
Composes package `app_name` with `manifest` file as a template for the
manifest and files from `package_dir`.
Includes `require` section if any in the manifest file.
Puts the resulting .zip file into `acrhive_dir` if present or in the

View File

@ -21,7 +21,7 @@ class TestFlavorField(helpers.APITestCase):
"""Set up the Flavor Class and novaclient."""
super(TestFlavorField, self).setUp()
class FlavorFlave:
class FlavorFlave(object):
def __init__(self, name, vcpus, disk, ram):
self.name = name
self.vcpus = vcpus

View File

@ -24,7 +24,9 @@ class TestService(testtools.TestCase):
self.application = {'?': {'type': 'test.App'}}
def test_service_field_hidden_false(self):
"""When Service class instantiated with some field having `hidden`
"""Test that service field is hidden
When Service class instantiated with some field having `hidden`
attribute set to `false` - the generated form field should have
widget different from `HiddenInput`.
@ -45,8 +47,9 @@ class TestService(testtools.TestCase):
self.assertNotIsInstance(field.widget, forms.HiddenInput)
def test_service_field_hidden_true(self):
"""`hidden: true` in UI definition results to HiddenInput in Django
form.
"""Test hidden widget
`hidden: true` in UI definition results to HiddenInput in Django form.
"""
ui = [{
'appConfiguration': {'fields': [{'hidden': True, 'type': 'string',

View File

@ -11,10 +11,9 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import horizon
def get_user_home(user):
#if user.is_superuser:
# return horizon.get_dashboard('admin').get_absolute_url()
return horizon.get_dashboard('murano').get_absolute_url()

11
tox.ini
View File

@ -44,15 +44,8 @@ commands = nodeenv -p
downloadcache = ~/cache/pip
[flake8]
# H104 File contains nothing but comments
# E111 indentation is not a multiple of four
# E113 unexpected indentation
# H236 Python 3.x incompatible __metaclass__, use six.add_metaclass()
# H238 old style class declaration, use new style (inherit from `object`)
# E265 block comment should start with '# '
# H405 multi line docstring summary not separated with an empty line
# H701 Empty localization string
ignore = H104,E111,E113,H236,H238,E265,H405,H701
# H104 File contains nothing but comments
ignore = H104
show-source = true
builtins = _
exclude=.build,.venv,.git,.tox,dist,doc,*lib/python*,*egg,tools,horizon,settings.py,*/local/*