Use a common requirements file
We can use newer setuptools and pbr to use environment markers in our requirements files which allows us to select deps if the environment matches. With this we restrict the email dep to python < 3.0 which is the only dep we have that doesn't work across python 2 and 3. Note that this also updates the pbr machinery to pull in this new feature support. Part of this update requires updating hacking to avoid conflicting pbr requirements. This in turn has created some churn in the format of the code but should largely be a noop. Change-Id: I0be5dd8a6b33a51329077b5a5f4c7f5576829956
This commit is contained in:
parent
8ea0c1e4eb
commit
1a0ce47f8f
@ -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
|
@ -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
|
||||
|
13
setup.py
13
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)
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -14,7 +14,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
class MasterBranchHelper:
|
||||
class MasterBranchHelper(object):
|
||||
name = "master"
|
||||
project_id = None
|
||||
expired = False
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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.
|
||||
"""
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,4 @@
|
||||
hacking>=0.5.6,<0.8
|
||||
hacking>=0.11.0,<0.12
|
||||
|
||||
coverage>=3.6
|
||||
discover
|
||||
|
17
tox.ini
17
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
|
||||
|
Loading…
Reference in New Issue
Block a user