diff --git a/requirements-py3.txt b/requirements-py3.txt deleted file mode 100644 index 5c54fa88..00000000 --- a/requirements-py3.txt +++ /dev/null @@ -1,29 +0,0 @@ -pbr>=0.6,!=0.7,<1.0 -jsonschema>=2.0.0,<3.0.0 -argparse -alembic>=0.4.1 -Babel>=1.3 -iso8601>=0.1.9 -oauthlib>=0.6 -oslo.config>=1.11.0 -oslo.context>=0.2.0 -oslo.utils>=1.4.0 -pecan>=0.4.5 -oslo.db>=1.8.0 -oslo.log>=1.0.0 -pika>=0.9.14 -python-openid -PyYAML>=3.1.0 -requests>=1.1 -six>=1.7.0 -SQLAlchemy>=0.9.7,<=0.9.99 -WSME>=0.6 -sqlalchemy-migrate>=0.9.1,!=0.9.2 -SQLAlchemy-FullText-Search -eventlet>=0.13.0 -stevedore>=1.3.0 -tzlocal>=1.1.2 -Jinja2>=2.7.3 -PyMySQL>=0.6.2,!=0.6.4 -apscheduler>=3.0.1 -python_dateutil>=2.4.0 diff --git a/requirements.txt b/requirements.txt index c12b1686..a65174cb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -pbr>=0.6,!=0.7,<1.0 +pbr>=1.6 jsonschema>=2.0.0,<3.0.0 alembic>=0.4.1 Babel>=1.3 @@ -22,7 +22,7 @@ SQLAlchemy-FullText-Search>=0.2.3 eventlet>=0.13.0 stevedore>=1.3.0 tzlocal>=1.1.2 -email>=4.0.2 +email>=4.0.2;python_version<'3.0' Jinja2>=2.7.3 PyMySQL>=0.6.2,!=0.6.4 apscheduler>=3.0.1,<3.1.0 diff --git a/setup.py b/setup.py index 70c2b3f3..2f8bfd2e 100755 --- a/setup.py +++ b/setup.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,9 +13,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT +# This file was pulled from the openstack global requirements repo. import setuptools +# In python < 2.7.4, a lazy loading of package `pbr` will break +# setuptools if some other modules registered functions in `atexit`. +# solution from: http://bugs.python.org/issue15881#msg170215 +try: + import multiprocessing # noqa +except ImportError: + pass + setuptools.setup( - setup_requires=['pbr'], + setup_requires=['pbr>=1.8'], pbr=True) diff --git a/storyboard/api/auth/openid_client.py b/storyboard/api/auth/openid_client.py index f5917364..61bcfa44 100644 --- a/storyboard/api/auth/openid_client.py +++ b/storyboard/api/auth/openid_client.py @@ -138,7 +138,7 @@ class OpenIdClient(object): for token in verify_data_tokens) if (verify_response.status_code / 100 != 2 - or verify_dict['is_valid'] != 'true'): + or verify_dict['is_valid'] != 'true'): raise AccessDenied(redirect_uri=redirect_uri, message=e_msg.OPEN_ID_TOKEN_INVALID) diff --git a/storyboard/api/v1/stories.py b/storyboard/api/v1/stories.py index 14b0e885..18aa59d0 100644 --- a/storyboard/api/v1/stories.py +++ b/storyboard/api/v1/stories.py @@ -200,7 +200,7 @@ class StoriesController(rest.RestController): if not stories_api.story_can_create_story(story.story_type_id): abort(400, _("Can't create story of this type.")) - if not "tags" in story_dict or not story_dict["tags"]: + if "tags" not in story_dict or not story_dict["tags"]: story_dict["tags"] = [] # We can't set due dates when creating stories at the moment. diff --git a/storyboard/common/event_resolvers.py b/storyboard/common/event_resolvers.py index 6c84b10d..344b369e 100644 --- a/storyboard/common/event_resolvers.py +++ b/storyboard/common/event_resolvers.py @@ -70,7 +70,7 @@ def task_details_changed(event): def task_deleted(event): - #NOTE: There is nothing to resolve, as the task title is already stored in + # NOTE: There is nothing to resolve, as the task title is already stored in # the info. There is no way to store an id because the task is hard deleted # at the moment we would query it. return event diff --git a/storyboard/common/master_branch_helper.py b/storyboard/common/master_branch_helper.py index b04dec6d..f6c87fd8 100644 --- a/storyboard/common/master_branch_helper.py +++ b/storyboard/common/master_branch_helper.py @@ -14,7 +14,7 @@ # limitations under the License. -class MasterBranchHelper: +class MasterBranchHelper(object): name = "master" project_id = None expired = False diff --git a/storyboard/db/api/boards.py b/storyboard/db/api/boards.py index ad8ed1e6..a4e36fcb 100644 --- a/storyboard/db/api/boards.py +++ b/storyboard/db/api/boards.py @@ -216,8 +216,8 @@ def get_card(board, item_type, item_id, archived=False): for lane in board.lanes: for card in lane.worklist.items: if (card.item_type == item_type and - card.item_id == item_id and - card.archived == archived): + card.item_id == item_id and + card.archived == archived): return card diff --git a/storyboard/db/models.py b/storyboard/db/models.py index 018a0e0f..3be05d58 100644 --- a/storyboard/db/models.py +++ b/storyboard/db/models.py @@ -63,7 +63,7 @@ def table_args(): MYSQL_MEDIUM_TEXT = UnicodeText().with_variant(MEDIUMTEXT(), 'mysql') -class CommonLength: +class CommonLength(object): top_large_length = 255 top_middle_length = 100 top_short_length = 50 diff --git a/storyboard/plugin/email/smtp_client.py b/storyboard/plugin/email/smtp_client.py index a75c0484..cc2fccb0 100644 --- a/storyboard/plugin/email/smtp_client.py +++ b/storyboard/plugin/email/smtp_client.py @@ -33,19 +33,19 @@ class get_smtp_client(object): # SSL or not SSL? if not email_config.smtp_ssl_certfile \ or not email_config.smtp_ssl_keyfile: - self.s = smtplib.SMTP(host=email_config.smtp_host, - port=email_config.smtp_port, - local_hostname= - email_config.smtp_local_hostname, - timeout=email_config.smtp_timeout) + self.s = smtplib.SMTP( + host=email_config.smtp_host, + port=email_config.smtp_port, + local_hostname=email_config.smtp_local_hostname, + timeout=email_config.smtp_timeout) else: - self.s = smtplib.SMTP_SSL(host=email_config.smtp_host, - port=email_config.smtp_port, - keyfile=email_config.smtp_ssl_keyfile, - certfile=email_config.smtp_ssl_certfile, - local_hostname= - email_config.smtp_local_hostname, - timeout=email_config.smtp_timeout) + self.s = smtplib.SMTP_SSL( + host=email_config.smtp_host, + port=email_config.smtp_port, + keyfile=email_config.smtp_ssl_keyfile, + certfile=email_config.smtp_ssl_certfile, + local_hostname=email_config.smtp_local_hostname, + timeout=email_config.smtp_timeout) # Do we need to log in? if email_config.smtp_user and email_config.smtp_password: diff --git a/storyboard/plugin/event_worker.py b/storyboard/plugin/event_worker.py index 3c4290b1..2b472634 100644 --- a/storyboard/plugin/event_worker.py +++ b/storyboard/plugin/event_worker.py @@ -70,7 +70,7 @@ def terminate(sig, frame): signal.default_int_handler() -class DaemonManager(): +class DaemonManager(object): """A Daemon manager to handle multiple subprocesses. """ def __init__(self, child_process_count, daemon_method): @@ -134,7 +134,7 @@ class DaemonManager(): self._procs.append(process) -class PerpetualTimer(): +class PerpetualTimer(object): """A timer wrapper class that repeats itself. """ diff --git a/storyboard/tests/api/auth/test_oauth.py b/storyboard/tests/api/auth/test_oauth.py index 581048f2..4a764f99 100644 --- a/storyboard/tests/api/auth/test_oauth.py +++ b/storyboard/tests/api/auth/test_oauth.py @@ -391,11 +391,11 @@ class TestOAuthAuthorizeReturn(BaseOAuthTest): with base.HybridSessionManager(): token = auth_api.authorization_code_get(parameters['code']) + redirect_uri = self.valid_params['sb_redirect_uri'] # Validate the redirect response self.assertValidRedirect(response=response, expected_status_code=302, - redirect_uri= - self.valid_params['sb_redirect_uri'], + redirect_uri=redirect_uri, state=token.state, code=token.code) @@ -413,11 +413,11 @@ class TestOAuthAuthorizeReturn(BaseOAuthTest): state=random_state, **self.valid_params) + redirect_uri = self.valid_params['sb_redirect_uri'] # Validate the redirect response self.assertValidRedirect(response=response, expected_status_code=302, - redirect_uri= - self.valid_params['sb_redirect_uri'], + redirect_uri=redirect_uri, error='access_denied', error_description=e_msg.OPEN_ID_TOKEN_INVALID) @@ -438,11 +438,11 @@ class TestOAuthAuthorizeReturn(BaseOAuthTest): state=random_state, **invalid_params) + redirect_uri = self.valid_params['sb_redirect_uri'] # Validate the redirect response self.assertValidRedirect(response=response, expected_status_code=302, - redirect_uri= - self.valid_params['sb_redirect_uri'], + redirect_uri=redirect_uri, error='invalid_request', error_description=e_msg.INVALID_NO_NAME) @@ -463,11 +463,11 @@ class TestOAuthAuthorizeReturn(BaseOAuthTest): state=random_state, **invalid_params) + redirect_uri = self.valid_params['sb_redirect_uri'] # Validate the redirect response self.assertValidRedirect(response=response, expected_status_code=302, - redirect_uri= - self.valid_params['sb_redirect_uri'], + redirect_uri=redirect_uri, error='invalid_request', error_description=e_msg.INVALID_NO_EMAIL) @@ -522,14 +522,14 @@ class TestOAuthAccessToken(BaseOAuthTest): 'code': 'test_valid_code' }) + content_type = 'application/x-www-form-urlencoded' # POST with content: application/x-www-form-urlencoded response = self.app.post('/v1/openid/token', params={ 'code': authorization_code.code, 'grant_type': 'authorization_code' }, - content_type= - 'application/x-www-form-urlencoded', + content_type=content_type, expect_errors=True) # Assert that this is a successful response @@ -602,13 +602,13 @@ class TestOAuthAccessToken(BaseOAuthTest): 'expires_in': 300 }) + content_type = 'application/x-www-form-urlencoded' response = self.app.post('/v1/openid/token', params={ 'code': authorization_code.code, 'grant_type': 'authorization_code' }, - content_type= - 'application/x-www-form-urlencoded', + content_type=content_type, expect_errors=True) # Assert that this is a valid call. @@ -649,14 +649,14 @@ class TestOAuthAccessToken(BaseOAuthTest): 'created_at': expired }) + content_type = 'application/x-www-form-urlencoded' # POST with content: application/x-www-form-urlencoded response = self.app.post('/v1/openid/token', params={ 'code': authorization_code.code, 'grant_type': 'authorization_code' }, - content_type= - 'application/x-www-form-urlencoded', + content_type=content_type, expect_errors=True) # Assert that this is a valid call. @@ -682,14 +682,14 @@ class TestOAuthAccessToken(BaseOAuthTest): 'expires_in': 300 }) + content_type = 'application/x-www-form-urlencoded' # POST with content: application/x-www-form-urlencoded response = self.app.post('/v1/openid/token', params={ 'code': authorization_code.code, 'grant_type': 'invalid_grant_type' }, - content_type= - 'application/x-www-form-urlencoded', + content_type=content_type, expect_errors=True) # Assert that this is a successful response @@ -704,14 +704,14 @@ class TestOAuthAccessToken(BaseOAuthTest): appropriate error response. """ + content_type = 'application/x-www-form-urlencoded' # POST with content: application/x-www-form-urlencoded response = self.app.post('/v1/openid/token', params={ 'code': 'invalid_access_token', 'grant_type': 'invalid_grant_type' }, - content_type= - 'application/x-www-form-urlencoded', + content_type=content_type, expect_errors=True) # Assert that this is a successful response @@ -734,14 +734,14 @@ class TestOAuthAccessToken(BaseOAuthTest): 'code': 'test_valid_code' }) + content_type = 'application/x-www-form-urlencoded' # Generate an auth and a refresh token. resp_1 = self.app.post('/v1/openid/token', params={ 'code': authorization_code.code, 'grant_type': 'authorization_code' }, - content_type= - 'application/x-www-form-urlencoded', + content_type=content_type, expect_errors=True) # Assert that this is a successful response @@ -762,15 +762,14 @@ class TestOAuthAccessToken(BaseOAuthTest): self.assertIsNotNone(refresh_token) + content_type = 'application/x-www-form-urlencoded' # Issue a refresh token request. - resp_2 = self.app.post('/v1/openid/token', params={ 'refresh_token': t1['refresh_token'], 'grant_type': 'refresh_token' }, - content_type= - 'application/x-www-form-urlencoded', + content_type=content_type, expect_errors=True) # Assert that the response is good. @@ -832,14 +831,14 @@ class TestOAuthAccessToken(BaseOAuthTest): into a valid access token. """ + content_type = 'application/x-www-form-urlencoded' # Generate an auth and a refresh token. resp_1 = self.app.post('/v1/openid/token', params={ 'refresh_token': 'invalid_refresh_token', 'grant_type': 'refresh_token' }, - content_type= - 'application/x-www-form-urlencoded', + content_type=content_type, expect_errors=True) # Assert that this is a correct response diff --git a/storyboard/tests/notifications/test_notification_hook.py b/storyboard/tests/notifications/test_notification_hook.py index 981c5a1c..a5c99c1c 100644 --- a/storyboard/tests/notifications/test_notification_hook.py +++ b/storyboard/tests/notifications/test_notification_hook.py @@ -12,7 +12,8 @@ # implied. See the License for the specific language governing permissions and # limitations under the License. -from mock import patch, Mock +from mock import Mock +from mock import patch from storyboard.api.v1.v1_controller import V1Controller from storyboard.api.v1.wmodels import Task as TaskWmodel import storyboard.common.hook_priorities as priority diff --git a/test-requirements.txt b/test-requirements.txt index 857c4185..5037f2a3 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,4 +1,4 @@ -hacking>=0.5.6,<0.8 +hacking>=0.11.0,<0.12 coverage>=3.6 discover diff --git a/tox.ini b/tox.ini index 5e116541..eed9f67b 100644 --- a/tox.ini +++ b/tox.ini @@ -25,21 +25,20 @@ commands = rm -rf doc/source/apidoc doc/source/api python setup.py build_sphinx -[testenv:py34] -deps = -r{toxinidir}/requirements-py3.txt - -r{toxinidir}/test-requirements.txt - -[testenv:py35] -deps = -r{toxinidir}/requirements-py3.txt - -r{toxinidir}/test-requirements.txt - [testenv:cover] commands = python setup.py testr --coverage --testr-args='{posargs}' [flake8] # E125 and E128 are ignored on purpose, they are invalid pep8 # H803 is ignored on purpose - gating on periods in commit messages -ignore = E125,E128,H803 +# The following rules should either be addressed or determined to be +# skippable long term. +# H405 is ignored to make switch to newer hacking easier +# H234 is ignored to make switch to newer hacking easier +# H233 is ignored to make switch to newer hacking easier +# E265 is ignored to make switch to newer hacking easier +# H236 is ignored to make switch to newer hacking easier +ignore = E125,E128,H803,H405,H234,H233,E265,H236 builtins = _ show-source = True exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build