Enable H202, H402, H404 rules

* H202 assertRaises Exception too broad
* H402 one line docstring needs punctuation
* H404 multi line docstring should start without a leading new line

Change-Id: I2f662b8b97d14daa501620c8237bf93bd2251243
This commit is contained in:
Ekaterina Fedorova 2014-08-25 16:39:03 +04:00 committed by Ekaterina Chernova
parent 864df5b69d
commit d6a3a2b2e6
22 changed files with 118 additions and 181 deletions

View File

@ -41,7 +41,7 @@ class VersionNegotiationFilter(wsgi.Middleware):
super(VersionNegotiationFilter, self).__init__(app)
def process_request(self, req):
"""Try to find a version first in the accept header, then the URL"""
"""Try to find a version first in the accept header, then the URL."""
msg = _("Determining version of request: %(method)s %(path)s"
" Accept: %(accept)s")
args = {'method': req.method, 'path': req.path, 'accept': req.accept}
@ -64,13 +64,12 @@ class VersionNegotiationFilter(wsgi.Middleware):
return None
def _match_version_string(self, subject):
"""
Given a string, tries to match a major and/or
minor version number.
"""Given a string, tries to match a major and/or
minor version number.
:param subject: The string to check
:returns version found in the subject
:raises ValueError if no acceptable version could be found
:param subject: The string to check
:returns version found in the subject
:raises ValueError if no acceptable version could be found
"""
if subject in ('v1',):
major_version = 1
@ -79,9 +78,8 @@ class VersionNegotiationFilter(wsgi.Middleware):
return major_version
def _pop_path_info(self, req):
"""
'Pops' off the next segment of PATH_INFO, returns the popped
segment. Do NOT push it onto SCRIPT_NAME.
"""'Pops' off the next segment of PATH_INFO, returns the popped
segment. Do NOT push it onto SCRIPT_NAME.
"""
path = req.path_info
if not path:

View File

@ -75,12 +75,11 @@ def _get_filters(query_params):
def _validate_body(body):
"""
Check multipart/form-data has two parts: text (which is json string and
should parsed into dictionary in serializer) and file, which stores as
cgi.FieldStorage instance. Also validate file size doesn't exceed
the limit: seek to the end of the file, get the position of EOF and
reset the file position to the beginning
"""Check multipart/form-data has two parts: text (which is json string and
should parsed into dictionary in serializer) and file, which stores as
cgi.FieldStorage instance. Also validate file size doesn't exceed
the limit: seek to the end of the file, get the position of EOF and
reset the file position to the beginning
"""
def check_file_size(f):
mb_limit = CONF.packages_opts.package_size_limit
@ -116,13 +115,10 @@ def _validate_body(body):
class Controller(object):
"""
WSGI controller for application catalog resource in Murano v1 API
"""
"""WSGI controller for application catalog resource in Murano v1 API."""
def update(self, req, body, package_id):
"""
List of allowed changes:
"""List of allowed changes:
{ "op": "add", "path": "/tags", "value": [ "foo", "bar" ] }
{ "op": "add", "path": "/categories", "value": [ "foo", "bar" ] }
{ "op": "remove", "path": "/tags" }
@ -184,9 +180,8 @@ class Controller(object):
return result
def upload(self, req, body=None):
"""
Upload new file archive for the new package
together with package metadata
"""Upload new file archive for the new package
together with package metadata.
"""
policy.check("upload_package", req.context)

View File

@ -87,9 +87,7 @@ def _do_import_package(_dir, categories, update=False):
# TODO(ruhe): proper error handling
def do_import_package():
"""
Import Murano package from local directory.
"""
"""Import Murano package from local directory."""
_do_import_package(
CONF.command.directory,
CONF.command.categories,

View File

@ -220,9 +220,7 @@ def parse_args(args=None, usage=None, default_config_files=None):
def setup_logging():
"""
Sets up the logging options for a log with supplied name
"""
"""Sets up the logging options for a log with supplied name."""
if CONF.log_config:
# Use a logging configuration file for all settings...
@ -265,9 +263,8 @@ def setup_logging():
def _get_deployment_flavor():
"""
Retrieve the paste_deploy.flavor config item, formatted appropriately
for appending to the application name.
"""Retrieve the paste_deploy.flavor config item, formatted appropriately
for appending to the application name.
"""
flavor = CONF.paste_deploy.flavor
return '' if not flavor else ('-' + flavor)
@ -286,9 +283,8 @@ def _get_paste_config_path():
def _get_deployment_config_file():
"""
Retrieve the deployment_config_file config item, formatted as an
absolute pathname.
"""Retrieve the deployment_config_file config item, formatted as an
absolute pathname.
"""
path = CONF.paste_deploy.config_file
if not path:
@ -300,8 +296,7 @@ def _get_deployment_config_file():
def load_paste_app(app_name=None):
"""
Builds and returns a WSGI app from a paste config file.
"""Builds and returns a WSGI app from a paste config file.
We assume the last config file specified in the supplied ConfigOpts
object is the paste config file.

View File

@ -17,13 +17,12 @@ import types
class TokenSanitizer():
"""
Helper class for cleaning some object from different passwords/tokens.
"""Helper class for cleaning some object from different passwords/tokens.
Simply searches attribute with `look a like` name as one of
the token and replace it value with message.
"""
def __init__(self, tokens=('token', 'pass'), message='*** SANITIZED ***'):
"""
"""Init method of TokenSanitizer.
:param tokens: iterable with tokens
:param message: string by which each token going to be replaced
"""
@ -32,16 +31,12 @@ class TokenSanitizer():
@property
def tokens(self):
"""
Iterable with tokens that should be sanitized
"""
"""Iterable with tokens that should be sanitized."""
return self._tokens
@property
def message(self):
"""
String by which each token going to be replaced
"""
"""String by which each token going to be replaced."""
return self._message
def _contains_token(self, value):
@ -51,8 +46,7 @@ class TokenSanitizer():
return False
def sanitize(self, obj):
"""
Replaces each token found in object by message
"""Replaces each token found in object by message.
:param obj: types.DictType, types.ListType, types.Tuple, object
:return: Sanitized object
"""

View File

@ -32,8 +32,7 @@ class TraverseHelper(object):
@staticmethod
def get(path, source):
"""
Provides the ability to traverse a data source made up of any
"""Provides the ability to traverse a data source made up of any
combination of lists and dicts. Has simple rules for selecting item of
the list:
@ -81,8 +80,7 @@ class TraverseHelper(object):
@staticmethod
def update(path, value, source):
"""
Updates value selected with specified path.
"""Updates value selected with specified path.
Warning: Root object could not be updated
@ -97,8 +95,7 @@ class TraverseHelper(object):
@staticmethod
def insert(path, value, source):
"""
Inserts new item to selected list.
"""Inserts new item to selected list.
:param path: string with path to desired value
:param value: value
@ -109,8 +106,7 @@ class TraverseHelper(object):
@staticmethod
def extend(path, value, source):
"""
Extend list by appending elements from the iterable.
"""Extend list by appending elements from the iterable.
:param path: string with path to desired value
:param value: value
@ -121,8 +117,7 @@ class TraverseHelper(object):
@staticmethod
def remove(path, source):
"""
Removes selected item from source.
"""Removes selected item from source.
:param path: string with path to desired value
:param source: python object (list or dict)
@ -145,8 +140,7 @@ class TraverseHelper(object):
def is_different(obj1, obj2):
"""
Stripped-down version of deep.diff comparator
"""Stripped-down version of deep.diff comparator
Compares arbitrary nested objects, handles circular links, but doesn't
point to the first difference as deep.diff does.

View File

@ -14,8 +14,7 @@
class RequestContext(object):
"""
Stores information about the security context under which the user
"""Stores information about the security context under which the user
accesses the system, as well as additional request information.
TODO: (sjmc7) - extend openstack.common.context

View File

@ -77,10 +77,9 @@ def _authorize_package(package, context, allow_public=False):
def package_get(package_id_or_name, context):
"""
Return package details
:param package_id: ID or name of a package, string
:returns: detailed information about package, dict
"""Return package details
:param package_id: ID or name of a package, string
:returns: detailed information about package, dict
"""
session = db_session.get_session()
package = _package_get(package_id_or_name, session)
@ -89,10 +88,11 @@ def package_get(package_id_or_name, context):
def _get_categories(category_names, session=None):
"""
Return existing category objects or raise an exception
:param category_names: name of categories to associate with package, list
:returns: list of Category objects to associate with package, list
"""Return existing category objects or raise an exception.
:param category_names: name of categories
to associate with package, list
:returns: list of Category objects to associate with package, list
"""
if session is None:
session = db_session.get_session()
@ -111,10 +111,9 @@ def _get_categories(category_names, session=None):
def _get_tags(tag_names, session=None):
"""
Return existing tags object or create new ones
:param tag_names: name of tags to associate with package, list
:returns: list of Tag objects to associate with package, list
"""Return existing tags object or create new ones
:param tag_names: name of tags to associate with package, list
:returns: list of Tag objects to associate with package, list
"""
if session is None:
session = db_session.get_session()
@ -204,10 +203,9 @@ def _do_remove(package, change):
def package_update(pkg_id_or_name, changes, context):
"""
Update package information
:param changes: parameters to update
:returns: detailed information about new package, dict
"""Update package information
:param changes: parameters to update
:returns: detailed information about new package, dict
"""
operation_methods = {'add': _do_add,
@ -225,8 +223,7 @@ def package_update(pkg_id_or_name, changes, context):
def package_search(filters, context, limit=None):
"""
Search packages with different filters
"""Search packages with different filters
* Admin is allowed to browse all the packages
* Regular user is allowed to browse all packages belongs to user tenant
and all other packages marked is_public.
@ -328,10 +325,9 @@ def package_search(filters, context, limit=None):
def package_upload(values, tenant_id):
"""
Upload a package with new application
:param values: parameters describing the new package
:returns: detailed information about new package, dict
"""Upload a package with new application
:param values: parameters describing the new package
:returns: detailed information about new package, dict
"""
session = db_session.get_session()
package = models.Package()
@ -353,7 +349,7 @@ def package_upload(values, tenant_id):
def package_delete(package_id_or_name, context):
"""Delete a package by name or by ID"""
"""Delete a package by name or by ID."""
session = db_session.get_session()
with session.begin():

View File

@ -54,7 +54,7 @@ Base = declarative.declarative_base(cls=_MuranoBase)
class Environment(Base, TimestampMixin):
"""Represents a Environment in the metadata-store"""
"""Represents a Environment in the metadata-store."""
__tablename__ = 'environment'
id = sa.Column(sa.String(255),
@ -204,9 +204,7 @@ class Instance(Base):
class Package(Base, TimestampMixin):
"""
Represents a meta information about application package.
"""
"""Represents a meta information about application package."""
__tablename__ = 'package'
id = sa.Column(sa.String(36),
@ -258,9 +256,7 @@ class Package(Base, TimestampMixin):
class Category(Base, TimestampMixin):
"""
Represents an application categories in the datastore.
"""
"""Represents an application categories in the datastore."""
__tablename__ = 'category'
id = sa.Column(sa.String(36),
@ -270,9 +266,7 @@ class Category(Base, TimestampMixin):
class Tag(Base, TimestampMixin):
"""
Represents tags in the datastore.
"""
"""Represents tags in the datastore."""
__tablename__ = 'tag'
id = sa.Column(sa.String(36),
@ -282,9 +276,7 @@ class Tag(Base, TimestampMixin):
class Class(Base, TimestampMixin):
"""
Represents a class definition in the datastore.
"""
"""Represents a class definition in the datastore."""
__tablename__ = 'class_definition'
id = sa.Column(sa.String(36),
@ -295,9 +287,7 @@ class Class(Base, TimestampMixin):
def register_models(engine):
"""
Creates database tables for all models with the given engine
"""
"""Creates database tables for all models with the given engine."""
models = (Environment, Status, Session, Task,
ApiStats, Package, Category, Class, Instance)
for model in models:
@ -305,9 +295,7 @@ def register_models(engine):
def unregister_models(engine):
"""
Drops database tables for all models with the given engine
"""
"""Drops database tables for all models with the given engine."""
models = (Environment, Status, Session, Task,
ApiStats, Package, Category, Class)
for model in models:

View File

@ -22,8 +22,7 @@ from murano.openstack.common import timeutils
class CoreServices(object):
@staticmethod
def get_service_status(environment_id, service_id):
"""
Service can have one of three distinguished statuses:
"""Service can have one of three distinguished statuses:
- Deploying: if environment has status deploying and there is at least
one orchestration engine report for this service;

View File

@ -43,10 +43,9 @@ DEFAULT_NETWORKS = {
class EnvironmentServices(object):
@staticmethod
def get_environments_by(filters):
"""
Returns list of environments
:param filters: property filters
:return: Returns list of environments
"""Returns list of environments
:param filters: property filters
:return: Returns list of environments
"""
unit = db_session.get_session()
environments = unit.query(models.Environment). \
@ -59,8 +58,7 @@ class EnvironmentServices(object):
@staticmethod
def get_status(environment_id):
"""
Environment can have one of the following statuses:
"""Environment can have one of the following statuses:
- deploying: there is ongoing deployment for environment
- deleting: environment is currently being deleted
@ -95,11 +93,11 @@ class EnvironmentServices(object):
@staticmethod
def create(environment_params, tenant_id):
#tagging environment by tenant_id for later checks
"""
Creates environment with specified params, in particular - name
:param environment_params: Dict, e.g. {'name': 'env-name'}
:param tenant_id: Tenant Id
:return: Created Environment
"""Creates environment with specified params, in particular - name
:param environment_params: Dict, e.g. {'name': 'env-name'}
:param tenant_id: Tenant Id
:return: Created Environment
"""
objects = {'?': {
@ -131,11 +129,10 @@ class EnvironmentServices(object):
@staticmethod
def delete(environment_id, session_id):
"""
Deletes environment and notify orchestration engine about deletion
"""Deletes environment and notify orchestration engine about deletion
:param environment_id: Environment that is going to be deleted
:param token: OpenStack auth token
:param environment_id: Environment that is going to be deleted
:param token: OpenStack auth token
"""
env_description = EnvironmentServices.get_environment_description(
@ -155,16 +152,17 @@ class EnvironmentServices(object):
@staticmethod
def get_environment_description(environment_id, session_id=None,
inner=True):
"""
Returns environment description for specified environment. If session
is specified and not in deploying state function returns modified
environment description, otherwise returns actual environment desc.
"""Returns environment description for specified environment.
:param environment_id: Environment Id
:param session_id: Session Id
:param inner: return contents of environment rather than whole
Object Model structure
:return: Environment Description Object
If session is specified and not in deploying state function
returns modified environment description,
otherwise returns actual environment desc.
:param environment_id: Environment Id
:param session_id: Session Id
:param inner: return contents of environment rather than whole
Object Model structure
:return: Environment Description Object
"""
unit = db_session.get_session()
@ -192,13 +190,12 @@ class EnvironmentServices(object):
@staticmethod
def save_environment_description(session_id, environment, inner=True):
"""
Saves environment description to specified session
"""Saves environment description to specified session.
:param session_id: Session Id
:param environment: Environment Description
:param inner: save modifications to only content of environment
rather than whole Object Model structure
:param session_id: Session Id
:param environment: Environment Description
:param inner: save modifications to only content of environment
rather than whole Object Model structure
"""
unit = db_session.get_session()
session = unit.query(models.Session).get(session_id)

View File

@ -35,8 +35,7 @@ SessionState = collections.namedtuple('SessionState', [
class SessionServices(object):
@staticmethod
def get_sessions(environment_id, state=None):
"""
Get list of sessions for specified environment
"""Get list of sessions for specified environment.
:param environment_id: Environment Id
:param state: glazierapi.db.services.environments.EnvironmentStatus
@ -62,8 +61,7 @@ class SessionServices(object):
@staticmethod
def create(environment_id, user_id):
"""
Creates session object for specific environment for specified user.
"""Creates session object for specific environment for specified user.
:param environment_id: Environment Id
:param user_id: User Id
@ -89,8 +87,7 @@ class SessionServices(object):
@staticmethod
def validate(session):
"""
Session is valid only if no other session for same
"""Session is valid only if no other session for same.
environment was already deployed on in deploying state,
:param session: Session for validation
@ -117,8 +114,7 @@ class SessionServices(object):
@staticmethod
def deploy(session, environment, unit, token):
"""
Prepares environment for deployment and send deployment command to
"""Prepares environment for deployment and send deployment command to
orchestration engine
:param session: session that is going to be deployed

View File

@ -78,7 +78,7 @@ class Agent(murano_object.MuranoObject):
"by the server configuration")
def _send(self, template, wait_results):
"""Send a message over the MQ interface"""
"""Send a message over the MQ interface."""
msg_id = template.get('ID', uuid.uuid4().hex)
if wait_results:
event = eventlet.event.Event()

View File

@ -79,8 +79,7 @@ class NetworkExplorer(murano_object.MuranoObject):
# noinspection PyPep8Naming
def getAvailableCidr(self, routerId, netId):
"""
Uses hash of network IDs to minimize the collisions:
"""Uses hash of network IDs to minimize the collisions:
different nets will attempt to pick different cidrs out of available
range.
If the cidr is taken will pick another one

View File

@ -79,8 +79,7 @@ class ActionServices(object):
@staticmethod
def find_action(model, action_id):
"""
Traverses object model looking for an object definition
"""Traverses object model looking for an object definition
containing specified action
:param model: object model

View File

@ -97,9 +97,7 @@ class MuranoApiTestCase(base.MuranoWithDBTestCase, FakeLogMixin):
class ControllerTest(object):
"""
Common utilities for testing API Controllers.
"""
"""Common utilities for testing API Controllers."""
def __init__(self, *args, **kwargs):
super(ControllerTest, self).__init__(*args, **kwargs)

View File

@ -32,7 +32,7 @@ class TestActionsApi(tb.ControllerTest, tb.MuranoApiTestCase):
self.controller = actions.Controller()
def test_execute_action(self, mock_policy_check):
"""Test that action execution results in the correct rpc call"""
"""Test that action execution results in the correct rpc call."""
self._set_policy_rules(
{'execute_action': '@'}
)

View File

@ -28,7 +28,7 @@ class TestEnvironmentApi(tb.ControllerTest, tb.MuranoApiTestCase):
self.controller = environments.Controller()
def test_list_empty_environments(self):
"""Check that with no environments an empty list is returned"""
"""Check that with no environments an empty list is returned."""
self._set_policy_rules(
{'list_environments': '@'}
)
@ -39,7 +39,7 @@ class TestEnvironmentApi(tb.ControllerTest, tb.MuranoApiTestCase):
self.assertEqual({'environments': []}, json.loads(result.body))
def test_create_environment(self):
"""Create an environment, test environment.show()"""
"""Create an environment, test environment.show()."""
self._set_policy_rules(
{'list_environments': '@',
'create_environment': '@',
@ -90,7 +90,7 @@ class TestEnvironmentApi(tb.ControllerTest, tb.MuranoApiTestCase):
self.assertEqual(3, mock_uuid.call_count)
def test_missing_environment(self):
"""Check that a missing environment results in an HTTPNotFound"""
"""Check that a missing environment results in an HTTPNotFound."""
self._set_policy_rules(
{'show_environment': '@'}
)
@ -102,7 +102,7 @@ class TestEnvironmentApi(tb.ControllerTest, tb.MuranoApiTestCase):
self.assertEqual(404, result.status_code)
def test_update_environment(self):
"""Check that environment rename works"""
"""Check that environment rename works."""
self._set_policy_rules(
{'show_environment': '@',
'update_environment': '@'}
@ -159,7 +159,7 @@ class TestEnvironmentApi(tb.ControllerTest, tb.MuranoApiTestCase):
self.assertEqual(expected, json.loads(result.body))
def test_delete_environment(self):
"""Test that environment deletion results in the correct rpc call"""
"""Test that environment deletion results in the correct rpc call."""
self._set_policy_rules(
{'delete_environment': '@'}
)

View File

@ -20,7 +20,7 @@ from murano.tests.unit import base
class TestModels(base.MuranoWithDBTestCase):
def test_missing_blob(self):
"""Fake a package with NULL supplier JSON blob to test bug 1342306"""
"""Fake a package with NULL supplier JSON blob to test bug 1342306."""
con = session.get_session().connection()
con.execute("INSERT INTO package(id, fully_qualified_name, "
"owner_id, name, description, created, updated, type, "

View File

@ -38,13 +38,12 @@ class TestResultsSerializer(test_case.DslTestCase):
self._runner = self.new_runner(self._root_class)
def _test_data_in_section(self, name, serialized):
"""
Test that a section of Object Model has expected structure and
property values that are equal to those originally loaded
(e.g. that Model -> Load -> Serialize = Model)
"""Test that a section of Object Model has expected structure and
property values that are equal to those originally loaded
(e.g. that Model -> Load -> Serialize = Model)
:param name: section name
:param serialized: serialized Object Model
:param name: section name
:param serialized: serialized Object Model
"""
self.assertEqual(self._root_class.id,
@ -63,8 +62,7 @@ class TestResultsSerializer(test_case.DslTestCase):
'sampleClass']['stringProperty'])
def test_results_serialize(self):
"""
Test that serialized Object Model has both Objects and ObjectsCopy
"""Test that serialized Object Model has both Objects and ObjectsCopy
sections and they both contain the same property values and object
headers. Note, that Objects section may contain additional designer
metadata and information on available actions that is not needed in
@ -79,8 +77,7 @@ class TestResultsSerializer(test_case.DslTestCase):
self._test_data_in_section('ObjectsCopy', serialized)
def test_actions(self):
"""
Test that information on actions that can be invoked on each MuranoPL
"""Test that information on actions can be invoked on each MuranoPL
object are persisted into object header ('?' key) during serialization
of Objects section of Object Model
@ -96,8 +93,7 @@ class TestResultsSerializer(test_case.DslTestCase):
matchers.StartsWith('test'))
def test_attribute_serialization(self):
"""
Test that attributes produced by MuranoPL code are persisted in
"""Test that attributes produced by MuranoPL code are persisted in
dedicated section of Object Model. Attributes are values that are
stored in special key-value storage that is private to each class.
Classes can store state data there. Attributes are persisted across
@ -116,8 +112,7 @@ class TestResultsSerializer(test_case.DslTestCase):
serialized['Attributes'][0])
def test_attribute_deserialization(self):
"""
Test that attributes that are put into Attributes section of
"""Test that attributes that are put into Attributes section of
Object Model become available to appropriate MuranoPL classes
"""

View File

@ -32,7 +32,7 @@ class TestHeatStack(base.MuranoTestCase):
@mock.patch('heatclient.client.Client')
def test_push_adds_version(self, mock_heat_client):
"""Assert that if heat_template_version is omitted, it's added"""
"""Assert that if heat_template_version is omitted, it's added."""
# Note that the 'with x as y, a as b:' syntax was introduced in
# python 2.7, and contextlib.nested was deprecated in py2.7
with mock.patch(MOD_NAME + '.HeatStack._get_status') as status_get:
@ -66,7 +66,7 @@ class TestHeatStack(base.MuranoTestCase):
@mock.patch('heatclient.client.Client')
def test_description_is_optional(self, mock_heat_client):
"""Assert that if heat_template_version is omitted, it's added"""
"""Assert that if heat_template_version is omitted, it's added."""
# Note that the 'with x as y, a as b:' syntax was introduced in
# python 2.7, and contextlib.nested was deprecated in py2.7
with mock.patch(MOD_NAME + '.HeatStack._get_status') as status_get:
@ -98,7 +98,7 @@ class TestHeatStack(base.MuranoTestCase):
self.assertTrue(hs._applied)
def test_update_wrong_template_version(self):
"""Template version other than expected should cause error"""
"""Template version other than expected should cause error."""
hs = heat_stack.HeatStack(self.mock_murano_obj,
None, None, None)

View File

@ -36,13 +36,10 @@ deps = flake8
commands = flake8
[flake8]
# H202 assertRaises Exception too broad
# H402 one line docstring needs punctuation
# H404 multi line docstring should start without a leading new line
# H501 Do not use locals() for string formatting
# H702 Argument to _ must be just a string
# H902 Use the 'not in' operator for collection membership evaluation
ignore = H202,H402,H404,H501,H702,H902
ignore =H501,H702,H902
show-source = true
builtins = _
exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,tools