Enable flake8 checks

This commit enables new flake8 checks:
* E265  block comment should start with '# '
* H405  multi line docstring summary not separated with an empty line
* E123  closing bracket does not match indentation of opening bracket's line
* H238  old style class declaration, use new style (inherit from `object`)
* E128  continuation line under-indented for visual indent
and makes related changes in the code.

Change-Id: Ie993afc930f6b74d7a990bcaa9fc0e9f5ba1585c
This commit is contained in:
Darja Shakhray 2015-07-20 17:29:49 +03:00
parent d9d586942b
commit ec0f2dfd85
30 changed files with 118 additions and 163 deletions

View File

@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
#NOTE(bcwaldon): this try/except block is needed to run setup.py due to # NOTE(bcwaldon): this try/except block is needed to run setup.py due to
# its need to import local code before installing required dependencies # its need to import local code before installing required dependencies
try: try:
import glanceclient.client import glanceclient.client

View File

@ -218,6 +218,7 @@ class HTTPClient(_BaseHTTPClient):
def _request(self, method, url, **kwargs): def _request(self, method, url, **kwargs):
"""Send an http request with the specified characteristics. """Send an http request with the specified characteristics.
Wrapper around httplib.HTTP(S)Connection.request to handle tasks such Wrapper around httplib.HTTP(S)Connection.request to handle tasks such
as setting headers and error handling. as setting headers and error handling.
""" """

View File

@ -58,6 +58,7 @@ from glanceclient import exc
def verify_callback(host=None): def verify_callback(host=None):
""" """
We use a partial around the 'real' verify_callback function We use a partial around the 'real' verify_callback function
so that we can stash the host value without holding a so that we can stash the host value without holding a
reference on the VerifiedHTTPSConnection. reference on the VerifiedHTTPSConnection.
@ -71,8 +72,7 @@ def verify_callback(host=None):
def do_verify_callback(connection, x509, errnum, def do_verify_callback(connection, x509, errnum,
depth, preverify_ok, host=None): depth, preverify_ok, host=None):
""" """Verify the server's SSL certificate.
Verify the server's SSL certificate.
This is a standalone function rather than a method to avoid This is a standalone function rather than a method to avoid
issues around closing sockets if a reference is held on issues around closing sockets if a reference is held on
@ -93,6 +93,7 @@ def do_verify_callback(connection, x509, errnum,
def host_matches_cert(host, x509): def host_matches_cert(host, x509):
""" """
Verify that the x509 certificate we have received Verify that the x509 certificate we have received
from 'host' correctly identifies the server we are from 'host' correctly identifies the server we are
connecting to, ie that the certificate's Common Name connecting to, ie that the certificate's Common Name
@ -140,13 +141,10 @@ def to_bytes(s):
class HTTPSAdapter(adapters.HTTPAdapter): class HTTPSAdapter(adapters.HTTPAdapter):
""" """This adapter will be used just when ssl compression should be disabled.
This adapter will be used just when
ssl compression should be disabled.
The init method overwrites the default The init method overwrites the default https pool by setting
https pool by setting glanceclient's glanceclient's one.
one.
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
classes_by_scheme = poolmanager.pool_classes_by_scheme classes_by_scheme = poolmanager.pool_classes_by_scheme
@ -194,8 +192,9 @@ class HTTPSAdapter(adapters.HTTPAdapter):
class HTTPSConnectionPool(connectionpool.HTTPSConnectionPool): class HTTPSConnectionPool(connectionpool.HTTPSConnectionPool):
""" """
HTTPSConnectionPool will be instantiated when a new HTTPSConnectionPool will be instantiated when a new
connection is requested to the HTTPSAdapter.This connection is requested to the HTTPSAdapter. This
implementation overwrites the _new_conn method and implementation overwrites the _new_conn method and
returns an instances of glanceclient's VerifiedHTTPSConnection returns an instances of glanceclient's VerifiedHTTPSConnection
which handles no compression. which handles no compression.
@ -218,8 +217,7 @@ class HTTPSConnectionPool(connectionpool.HTTPSConnectionPool):
class OpenSSLConnectionDelegator(object): class OpenSSLConnectionDelegator(object):
""" """An OpenSSL.SSL.Connection delegator.
An OpenSSL.SSL.Connection delegator.
Supplies an additional 'makefile' method which httplib requires Supplies an additional 'makefile' method which httplib requires
and is not present in OpenSSL.SSL.Connection. and is not present in OpenSSL.SSL.Connection.
@ -239,6 +237,7 @@ class OpenSSLConnectionDelegator(object):
class VerifiedHTTPSConnection(HTTPSConnection): class VerifiedHTTPSConnection(HTTPSConnection):
""" """
Extended HTTPSConnection which uses the OpenSSL library Extended HTTPSConnection which uses the OpenSSL library
for enhanced SSL support. for enhanced SSL support.
Note: Much of this functionality can eventually be replaced Note: Much of this functionality can eventually be replaced
@ -284,9 +283,7 @@ class VerifiedHTTPSConnection(HTTPSConnection):
raise exc.SSLConfigurationError(str(e)) raise exc.SSLConfigurationError(str(e))
def set_context(self): def set_context(self):
""" """Set up the OpenSSL context."""
Set up the OpenSSL context.
"""
self.context = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD) self.context = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
self.context.set_cipher_list(self.CIPHERS) self.context.set_cipher_list(self.CIPHERS)
@ -333,8 +330,9 @@ class VerifiedHTTPSConnection(HTTPSConnection):
def connect(self): def connect(self):
""" """
Connect to an SSL port using the OpenSSL library and apply
per-connection parameters. Connect to an SSL port using the OpenSSL library
and apply per-connection parameters.
""" """
result = socket.getaddrinfo(self.host, self.port, 0, result = socket.getaddrinfo(self.host, self.port, 0,
socket.SOCK_STREAM) socket.SOCK_STREAM)

View File

@ -20,8 +20,9 @@ import six
class _ProgressBarBase(object): class _ProgressBarBase(object):
""" """
Base abstract class used by specific class wrapper to show a progress bar
when the wrapped object are consumed. Base abstract class used by specific class wrapper to show
a progress bar when the wrapped object are consumed.
:param wrapped: Object to wrap that hold data to be consumed. :param wrapped: Object to wrap that hold data to be consumed.
:param totalsize: The total size of the data in the wrapped object. :param totalsize: The total size of the data in the wrapped object.
@ -51,8 +52,9 @@ class _ProgressBarBase(object):
class VerboseFileWrapper(_ProgressBarBase): class VerboseFileWrapper(_ProgressBarBase):
""" """
A file wrapper that show and advance a progress bar whenever file's read
method is called. A file wrapper that show and advance a progress bar
whenever file's read method is called.
""" """
def read(self, *args, **kwargs): def read(self, *args, **kwargs):
@ -69,9 +71,9 @@ class VerboseFileWrapper(_ProgressBarBase):
class VerboseIteratorWrapper(_ProgressBarBase): class VerboseIteratorWrapper(_ProgressBarBase):
""" """
An iterator wrapper that show and advance a progress bar whenever An iterator wrapper that show and advance a progress bar whenever
data is consumed from the iterator. data is consumed from the iterator.
:note: Use only with iterator that yield strings. :note: Use only with iterator that yield strings.
""" """

View File

@ -215,7 +215,7 @@ def is_authentication_required(f):
def env(*vars, **kwargs): def env(*vars, **kwargs):
"""Search for the first defined of possibly many env vars """Search for the first defined of possibly many env vars.
Returns the first environment variable defined in vars, or Returns the first environment variable defined in vars, or
returns the default defined in kwargs. returns the default defined in kwargs.
@ -241,8 +241,7 @@ def exit(msg='', exit_code=1):
def save_image(data, path): def save_image(data, path):
""" """Save an image to the specified path.
Save an image to the specified path.
:param data: binary data of the image :param data: binary data of the image
:param path: path to save the image to :param path: path to save the image to
@ -276,6 +275,7 @@ def make_size_human_readable(size):
def getsockopt(self, *args, **kwargs): def getsockopt(self, *args, **kwargs):
""" """
A function which allows us to monkey patch eventlet's A function which allows us to monkey patch eventlet's
GreenSocket, adding a required 'getsockopt' method. GreenSocket, adding a required 'getsockopt' method.
TODO: (mclaren) we can remove this once the eventlet fix TODO: (mclaren) we can remove this once the eventlet fix
@ -298,8 +298,7 @@ def exception_to_str(exc):
def get_file_size(file_obj): def get_file_size(file_obj):
""" """Analyze file-like object and attempt to determine its size.
Analyze file-like object and attempt to determine its size.
:param file_obj: file-like object. :param file_obj: file-like object.
:retval The file's size or None if it cannot be determined. :retval The file's size or None if it cannot be determined.
@ -385,8 +384,7 @@ def print_image(image_obj, human_readable=False, max_col_width=None):
def integrity_iter(iter, checksum): def integrity_iter(iter, checksum):
""" """Check image data integrity.
Check image data integrity.
:raises: IOError :raises: IOError
""" """

View File

@ -467,8 +467,7 @@ class Resource(object):
@property @property
def human_id(self): def human_id(self):
"""Human-readable ID which can be used for bash completion. """Human-readable ID which can be used for bash completion."""
"""
if self.HUMAN_ID: if self.HUMAN_ID:
name = getattr(self, self.NAME_ATTR, None) name = getattr(self, self.NAME_ATTR, None)
if name is not None: if name is not None:

View File

@ -368,7 +368,7 @@ class BaseClient(object):
@staticmethod @staticmethod
def get_class(api_name, version, version_map): def get_class(api_name, version, version_map):
"""Returns the client class for the requested API version """Returns the client class for the requested API version.
:param api_name: the name of the API, e.g. 'compute', 'image', etc :param api_name: the name of the API, e.g. 'compute', 'image', etc
:param version: the requested API version :param version: the requested API version

View File

@ -42,8 +42,7 @@ from glanceclient.openstack.common._i18n import _
class ClientException(Exception): class ClientException(Exception):
"""The base exception class for all exceptions this library raises. """The base exception class for all exceptions this library raises."""
"""
pass pass
@ -118,8 +117,7 @@ class AmbiguousEndpoints(EndpointException):
class HttpError(ClientException): class HttpError(ClientException):
"""The base exception class for all HTTP exceptions. """The base exception class for all HTTP exceptions."""
"""
http_status = 0 http_status = 0
message = _("HTTP Error") message = _("HTTP Error")

View File

@ -59,8 +59,7 @@ def assert_has_keys(dct, required=None, optional=None):
class TestResponse(requests.Response): class TestResponse(requests.Response):
"""Wrap requests.Response and provide a convenient initialization. """Wrap requests.Response and provide a convenient initialization."""
"""
def __init__(self, data): def __init__(self, data):
super(TestResponse, self).__init__() super(TestResponse, self).__init__()
@ -99,8 +98,7 @@ class FakeHTTPClient(client.HTTPClient):
super(FakeHTTPClient, self).__init__(*args, **kwargs) super(FakeHTTPClient, self).__init__(*args, **kwargs)
def assert_called(self, method, url, body=None, pos=-1): def assert_called(self, method, url, body=None, pos=-1):
"""Assert than an API method was just called. """Assert than an API method was just called."""
"""
expected = (method, url) expected = (method, url)
called = self.callstack[pos][0:2] called = self.callstack[pos][0:2]
assert self.callstack, \ assert self.callstack, \
@ -115,8 +113,7 @@ class FakeHTTPClient(client.HTTPClient):
(self.callstack[pos][3], body)) (self.callstack[pos][3], body))
def assert_called_anytime(self, method, url, body=None): def assert_called_anytime(self, method, url, body=None):
"""Assert than an API method was called anytime in the test. """Assert than an API method was called anytime in the test."""
"""
expected = (method, url) expected = (method, url)
assert self.callstack, \ assert self.callstack, \

4
glanceclient/shell.py Normal file → Executable file
View File

@ -682,9 +682,7 @@ class OpenStackImagesShell(object):
@utils.arg('command', metavar='<subcommand>', nargs='?', @utils.arg('command', metavar='<subcommand>', nargs='?',
help='Display help for <subcommand>.') help='Display help for <subcommand>.')
def do_help(self, args): def do_help(self, args):
""" """Display help about this program or one of its subcommands."""
Display help about this program or one of its subcommands.
"""
if getattr(args, 'command', None): if getattr(args, 'command', None):
if args.command in self.subcommands: if args.command in self.subcommands:
self.subcommands[args.command].print_help() self.subcommands[args.command].print_help()

View File

@ -17,10 +17,9 @@ from tempest_lib.cli import base
class ClientTestBase(base.ClientTestBase): class ClientTestBase(base.ClientTestBase):
""" """This is a first pass at a simple read only python-glanceclient test.
This is a first pass at a simple read only python-glanceclient test. This
only exercises client commands that are read only.
This only exercises client commands that are read only.
This should test commands: This should test commands:
* as a regular user * as a regular user
* as an admin user * as an admin user

View File

@ -19,8 +19,7 @@ from glanceclient.tests.functional import base
class SimpleReadOnlyGlanceClientTest(base.ClientTestBase): class SimpleReadOnlyGlanceClientTest(base.ClientTestBase):
""" """Read only functional python-glanceclient tests.
read only functional python-glanceclient tests.
This only exercises client commands that are read only. This only exercises client commands that are read only.
""" """

View File

@ -77,7 +77,7 @@ class TestClient(testtools.TestCase):
'X-Identity-Status': 'Confirmed', 'X-Identity-Status': 'Confirmed',
'X-Service-Catalog': 'service_catalog', 'X-Service-Catalog': 'service_catalog',
} }
#with token # with token
kwargs = {'token': u'fake-token', kwargs = {'token': u'fake-token',
'identity_headers': identity_headers} 'identity_headers': identity_headers}
http_client_object = http.HTTPClient(self.endpoint, **kwargs) http_client_object = http.HTTPClient(self.endpoint, **kwargs)
@ -93,7 +93,7 @@ class TestClient(testtools.TestCase):
'X-Identity-Status': 'Confirmed', 'X-Identity-Status': 'Confirmed',
'X-Service-Catalog': 'service_catalog', 'X-Service-Catalog': 'service_catalog',
} }
#without X-Auth-Token in identity headers # without X-Auth-Token in identity headers
kwargs = {'token': u'fake-token', kwargs = {'token': u'fake-token',
'identity_headers': identity_headers} 'identity_headers': identity_headers}
http_client_object = http.HTTPClient(self.endpoint, **kwargs) http_client_object = http.HTTPClient(self.endpoint, **kwargs)
@ -140,9 +140,7 @@ class TestClient(testtools.TestCase):
self.assertEqual(v, headers[k]) self.assertEqual(v, headers[k])
def test_connection_timeout(self): def test_connection_timeout(self):
""" """Should receive an InvalidEndpoint if connection timeout."""
Should receive an InvalidEndpoint if connection timeout.
"""
def cb(request, context): def cb(request, context):
raise requests.exceptions.Timeout raise requests.exceptions.Timeout
@ -155,6 +153,7 @@ class TestClient(testtools.TestCase):
def test_connection_refused(self): def test_connection_refused(self):
""" """
Should receive a CommunicationError if connection refused. Should receive a CommunicationError if connection refused.
And the error should list the host and port that refused the And the error should list the host and port that refused the
connection connection
@ -192,7 +191,7 @@ class TestClient(testtools.TestCase):
self.assertNotIn("none-val", encoded) self.assertNotIn("none-val", encoded)
def test_raw_request(self): def test_raw_request(self):
" Verify the path being used for HTTP requests reflects accurately. " """Verify the path being used for HTTP requests reflects accurately."""
headers = {"Content-Type": "text/plain"} headers = {"Content-Type": "text/plain"}
text = 'Ok' text = 'Ok'
path = '/v1/images/detail' path = '/v1/images/detail'

View File

@ -36,7 +36,7 @@ from glanceclient import exc
from glanceclient import shell as openstack_shell from glanceclient import shell as openstack_shell
from glanceclient.tests import utils as testutils from glanceclient.tests import utils as testutils
#NOTE (esheffield) Used for the schema caching tests # NOTE (esheffield) Used for the schema caching tests
from glanceclient.v2 import schemas as schemas from glanceclient.v2 import schemas as schemas
import json import json
@ -507,7 +507,7 @@ class ShellCacheSchemaTest(testutils.TestCase):
self.shell._get_versioned_client = mocked_get_client self.shell._get_versioned_client = mocked_get_client
def _make_args(self, args): def _make_args(self, args):
class Args(): class Args(object):
def __init__(self, entries): def __init__(self, entries):
self.__dict__.update(entries) self.__dict__.update(entries)

View File

@ -66,7 +66,7 @@ class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
class TestHTTPSVerifyCert(testtools.TestCase): class TestHTTPSVerifyCert(testtools.TestCase):
"""Check 'requests' based ssl verification occurs """Check 'requests' based ssl verification occurs.
The requests library performs SSL certificate validation, The requests library performs SSL certificate validation,
however there is still a need to check that the glance however there is still a need to check that the glance
@ -156,9 +156,7 @@ class TestHTTPSVerifyCert(testtools.TestCase):
class TestVerifiedHTTPSConnection(testtools.TestCase): class TestVerifiedHTTPSConnection(testtools.TestCase):
def test_ssl_init_ok(self): def test_ssl_init_ok(self):
""" """Test VerifiedHTTPSConnection class init."""
Test VerifiedHTTPSConnection class init
"""
key_file = os.path.join(TEST_VAR_DIR, 'privatekey.key') key_file = os.path.join(TEST_VAR_DIR, 'privatekey.key')
cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt') cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt')
cacert = os.path.join(TEST_VAR_DIR, 'ca.crt') cacert = os.path.join(TEST_VAR_DIR, 'ca.crt')
@ -171,9 +169,7 @@ class TestVerifiedHTTPSConnection(testtools.TestCase):
self.fail('Failed to init VerifiedHTTPSConnection.') self.fail('Failed to init VerifiedHTTPSConnection.')
def test_ssl_init_cert_no_key(self): def test_ssl_init_cert_no_key(self):
""" """Test VerifiedHTTPSConnection: absence of SSL key file."""
Test VerifiedHTTPSConnection: absence of SSL key file.
"""
cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt') cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt')
cacert = os.path.join(TEST_VAR_DIR, 'ca.crt') cacert = os.path.join(TEST_VAR_DIR, 'ca.crt')
try: try:
@ -185,9 +181,7 @@ class TestVerifiedHTTPSConnection(testtools.TestCase):
pass pass
def test_ssl_init_key_no_cert(self): def test_ssl_init_key_no_cert(self):
""" """Test VerifiedHTTPSConnection: absence of SSL cert file."""
Test VerifiedHTTPSConnection: absence of SSL cert file.
"""
key_file = os.path.join(TEST_VAR_DIR, 'privatekey.key') key_file = os.path.join(TEST_VAR_DIR, 'privatekey.key')
cacert = os.path.join(TEST_VAR_DIR, 'ca.crt') cacert = os.path.join(TEST_VAR_DIR, 'ca.crt')
try: try:
@ -200,9 +194,7 @@ class TestVerifiedHTTPSConnection(testtools.TestCase):
self.fail('Failed to init VerifiedHTTPSConnection.') self.fail('Failed to init VerifiedHTTPSConnection.')
def test_ssl_init_bad_key(self): def test_ssl_init_bad_key(self):
""" """Test VerifiedHTTPSConnection: bad key."""
Test VerifiedHTTPSConnection: bad key.
"""
cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt') cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt')
cacert = os.path.join(TEST_VAR_DIR, 'ca.crt') cacert = os.path.join(TEST_VAR_DIR, 'ca.crt')
key_file = os.path.join(TEST_VAR_DIR, 'badkey.key') key_file = os.path.join(TEST_VAR_DIR, 'badkey.key')
@ -216,9 +208,7 @@ class TestVerifiedHTTPSConnection(testtools.TestCase):
pass pass
def test_ssl_init_bad_cert(self): def test_ssl_init_bad_cert(self):
""" """Test VerifiedHTTPSConnection: bad cert."""
Test VerifiedHTTPSConnection: bad cert.
"""
cert_file = os.path.join(TEST_VAR_DIR, 'badcert.crt') cert_file = os.path.join(TEST_VAR_DIR, 'badcert.crt')
cacert = os.path.join(TEST_VAR_DIR, 'ca.crt') cacert = os.path.join(TEST_VAR_DIR, 'ca.crt')
try: try:
@ -230,9 +220,7 @@ class TestVerifiedHTTPSConnection(testtools.TestCase):
pass pass
def test_ssl_init_bad_ca(self): def test_ssl_init_bad_ca(self):
""" """Test VerifiedHTTPSConnection: bad CA."""
Test VerifiedHTTPSConnection: bad CA.
"""
cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt') cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt')
cacert = os.path.join(TEST_VAR_DIR, 'badca.crt') cacert = os.path.join(TEST_VAR_DIR, 'badca.crt')
try: try:
@ -244,9 +232,7 @@ class TestVerifiedHTTPSConnection(testtools.TestCase):
pass pass
def test_ssl_cert_cname(self): def test_ssl_cert_cname(self):
""" """Test certificate: CN match."""
Test certificate: CN match
"""
cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt') cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt')
cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert = crypto.load_certificate(crypto.FILETYPE_PEM,
open(cert_file).read()) open(cert_file).read())
@ -259,9 +245,7 @@ class TestVerifiedHTTPSConnection(testtools.TestCase):
self.fail('Unexpected exception.') self.fail('Unexpected exception.')
def test_ssl_cert_cname_wildcard(self): def test_ssl_cert_cname_wildcard(self):
""" """Test certificate: wildcard CN match."""
Test certificate: wildcard CN match
"""
cert_file = os.path.join(TEST_VAR_DIR, 'wildcard-certificate.crt') cert_file = os.path.join(TEST_VAR_DIR, 'wildcard-certificate.crt')
cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert = crypto.load_certificate(crypto.FILETYPE_PEM,
open(cert_file).read()) open(cert_file).read())
@ -274,9 +258,7 @@ class TestVerifiedHTTPSConnection(testtools.TestCase):
self.fail('Unexpected exception.') self.fail('Unexpected exception.')
def test_ssl_cert_subject_alt_name(self): def test_ssl_cert_subject_alt_name(self):
""" """Test certificate: SAN match."""
Test certificate: SAN match
"""
cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt') cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt')
cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert = crypto.load_certificate(crypto.FILETYPE_PEM,
open(cert_file).read()) open(cert_file).read())
@ -295,9 +277,7 @@ class TestVerifiedHTTPSConnection(testtools.TestCase):
self.fail('Unexpected exception.') self.fail('Unexpected exception.')
def test_ssl_cert_subject_alt_name_wildcard(self): def test_ssl_cert_subject_alt_name_wildcard(self):
""" """Test certificate: wildcard SAN match."""
Test certificate: wildcard SAN match
"""
cert_file = os.path.join(TEST_VAR_DIR, 'wildcard-san-certificate.crt') cert_file = os.path.join(TEST_VAR_DIR, 'wildcard-san-certificate.crt')
cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert = crypto.load_certificate(crypto.FILETYPE_PEM,
open(cert_file).read()) open(cert_file).read())
@ -323,9 +303,7 @@ class TestVerifiedHTTPSConnection(testtools.TestCase):
pass pass
def test_ssl_cert_mismatch(self): def test_ssl_cert_mismatch(self):
""" """Test certificate: bogus host."""
Test certificate: bogus host
"""
cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt') cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt')
cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert = crypto.load_certificate(crypto.FILETYPE_PEM,
open(cert_file).read()) open(cert_file).read())
@ -341,9 +319,7 @@ class TestVerifiedHTTPSConnection(testtools.TestCase):
host=conn.host) host=conn.host)
def test_ssl_expired_cert(self): def test_ssl_expired_cert(self):
""" """Test certificate: out of date cert."""
Test certificate: out of date cert
"""
cert_file = os.path.join(TEST_VAR_DIR, 'expired-cert.crt') cert_file = os.path.join(TEST_VAR_DIR, 'expired-cert.crt')
cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert = crypto.load_certificate(crypto.FILETYPE_PEM,
open(cert_file).read()) open(cert_file).read())
@ -360,9 +336,7 @@ class TestVerifiedHTTPSConnection(testtools.TestCase):
host=conn.host) host=conn.host)
def test_ssl_broken_key_file(self): def test_ssl_broken_key_file(self):
""" """Test verify exception is raised."""
Test verify exception is raised.
"""
cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt') cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt')
cacert = os.path.join(TEST_VAR_DIR, 'ca.crt') cacert = os.path.join(TEST_VAR_DIR, 'ca.crt')
key_file = 'fake.key' key_file = 'fake.key'
@ -373,9 +347,7 @@ class TestVerifiedHTTPSConnection(testtools.TestCase):
cert_file=cert_file, cacert=cacert) cert_file=cert_file, cacert=cacert)
def test_ssl_init_ok_with_insecure_true(self): def test_ssl_init_ok_with_insecure_true(self):
""" """Test VerifiedHTTPSConnection class init."""
Test VerifiedHTTPSConnection class init
"""
key_file = os.path.join(TEST_VAR_DIR, 'privatekey.key') key_file = os.path.join(TEST_VAR_DIR, 'privatekey.key')
cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt') cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt')
cacert = os.path.join(TEST_VAR_DIR, 'ca.crt') cacert = os.path.join(TEST_VAR_DIR, 'ca.crt')
@ -389,9 +361,7 @@ class TestVerifiedHTTPSConnection(testtools.TestCase):
self.fail('Failed to init VerifiedHTTPSConnection.') self.fail('Failed to init VerifiedHTTPSConnection.')
def test_ssl_init_ok_with_ssl_compression_false(self): def test_ssl_init_ok_with_ssl_compression_false(self):
""" """Test VerifiedHTTPSConnection class init."""
Test VerifiedHTTPSConnection class init
"""
key_file = os.path.join(TEST_VAR_DIR, 'privatekey.key') key_file = os.path.join(TEST_VAR_DIR, 'privatekey.key')
cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt') cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt')
cacert = os.path.join(TEST_VAR_DIR, 'ca.crt') cacert = os.path.join(TEST_VAR_DIR, 'ca.crt')
@ -405,8 +375,7 @@ class TestVerifiedHTTPSConnection(testtools.TestCase):
self.fail('Failed to init VerifiedHTTPSConnection.') self.fail('Failed to init VerifiedHTTPSConnection.')
def test_ssl_init_non_byte_string(self): def test_ssl_init_non_byte_string(self):
""" """Test VerifiedHTTPSConnection class non byte string.
Test VerifiedHTTPSConnection class non byte string
Reproduces bug #1301849 Reproduces bug #1301849
""" """

View File

@ -55,7 +55,7 @@ class TestUtils(testtools.TestCase):
file_obj.close() file_obj.close()
def test_prettytable(self): def test_prettytable(self):
class Struct: class Struct(object):
def __init__(self, **entries): def __init__(self, **entries):
self.__dict__.update(entries) self.__dict__.update(entries)

View File

@ -236,11 +236,11 @@ class ShellInvalidEndpointandParameterTest(utils.TestCase):
self.gc = self._mock_glance_client() self.gc = self._mock_glance_client()
def _make_args(self, args): def _make_args(self, args):
#NOTE(venkatesh): this conversion from a dict to an object # NOTE(venkatesh): this conversion from a dict to an object
# is required because the test_shell.do_xxx(gc, args) methods # is required because the test_shell.do_xxx(gc, args) methods
# expects the args to be attributes of an object. If passed as # expects the args to be attributes of an object. If passed as
# dict directly, it throws an AttributeError. # dict directly, it throws an AttributeError.
class Args(): class Args(object):
def __init__(self, entries): def __init__(self, entries):
self.__dict__.update(entries) self.__dict__.update(entries)
@ -396,10 +396,12 @@ class ShellInvalidEndpointandParameterTest(utils.TestCase):
class ShellStdinHandlingTests(testtools.TestCase): class ShellStdinHandlingTests(testtools.TestCase):
def _fake_update_func(self, *args, **kwargs): def _fake_update_func(self, *args, **kwargs):
'''Function to replace glanceclient.images.update, """
Function to replace glanceclient.images.update,
to determine the parameters that would be supplied with the update to determine the parameters that would be supplied with the update
request request
''' """
# Store passed in args # Store passed in args
self.collected_args = (args, kwargs) self.collected_args = (args, kwargs)
@ -477,7 +479,9 @@ class ShellStdinHandlingTests(testtools.TestCase):
) )
def test_image_update_closed_stdin(self): def test_image_update_closed_stdin(self):
"""Supply glanceclient with a closed stdin, and perform an image """
Supply glanceclient with a closed stdin, and perform an image
update to an active image. Glanceclient should not attempt to read update to an active image. Glanceclient should not attempt to read
stdin. stdin.
""" """
@ -494,7 +498,9 @@ class ShellStdinHandlingTests(testtools.TestCase):
) )
def test_image_update_opened_stdin(self): def test_image_update_opened_stdin(self):
"""Supply glanceclient with a stdin, and perform an image """
Supply glanceclient with a stdin, and perform an image
update to an active image. Glanceclient should not allow it. update to an active image. Glanceclient should not allow it.
""" """

View File

@ -84,7 +84,7 @@ class TestController(testtools.TestCase):
def test_list_image_members(self): def test_list_image_members(self):
image_id = IMAGE image_id = IMAGE
#NOTE(iccha): cast to list since the controller returns a generator # NOTE(iccha): cast to list since the controller returns a generator
image_members = list(self.controller.list(image_id)) image_members = list(self.controller.list(image_id))
self.assertEqual(IMAGE, image_members[0].image_id) self.assertEqual(IMAGE, image_members[0].image_id)
self.assertEqual(MEMBER, image_members[0].member_id) self.assertEqual(MEMBER, image_members[0].member_id)

View File

@ -30,11 +30,11 @@ class ShellV2Test(testtools.TestCase):
self.gc = self._mock_glance_client() self.gc = self._mock_glance_client()
def _make_args(self, args): def _make_args(self, args):
#NOTE(venkatesh): this conversion from a dict to an object # NOTE(venkatesh): this conversion from a dict to an object
# is required because the test_shell.do_xxx(gc, args) methods # is required because the test_shell.do_xxx(gc, args) methods
# expects the args to be attributes of an object. If passed as # expects the args to be attributes of an object. If passed as
# dict directly, it throws an AttributeError. # dict directly, it throws an AttributeError.
class Args(): class Args(object):
def __init__(self, entries): def __init__(self, entries):
self.__dict__.update(entries) self.__dict__.update(entries)

View File

@ -255,7 +255,7 @@ class TestController(testtools.TestCase):
self.controller = tasks.Controller(self.api, self.schema_api) self.controller = tasks.Controller(self.api, self.schema_api)
def test_list_tasks(self): def test_list_tasks(self):
#NOTE(flwang): cast to list since the controller returns a generator # NOTE(flwang): cast to list since the controller returns a generator
tasks = list(self.controller.list()) tasks = list(self.controller.list())
self.assertEqual(tasks[0].id, _PENDING_ID) self.assertEqual(tasks[0].id, _PENDING_ID)
self.assertEqual(tasks[0].type, 'import') self.assertEqual(tasks[0].type, 'import')
@ -265,7 +265,7 @@ class TestController(testtools.TestCase):
self.assertEqual(tasks[1].status, 'processing') self.assertEqual(tasks[1].status, 'processing')
def test_list_tasks_paginated(self): def test_list_tasks_paginated(self):
#NOTE(flwang): cast to list since the controller returns a generator # NOTE(flwang): cast to list since the controller returns a generator
tasks = list(self.controller.list(page_size=1)) tasks = list(self.controller.list(page_size=1))
self.assertEqual(tasks[0].id, _PENDING_ID) self.assertEqual(tasks[0].id, _PENDING_ID)
self.assertEqual(tasks[0].type, 'import') self.assertEqual(tasks[0].type, 'import')

View File

@ -75,6 +75,7 @@ class RawRequest(object):
def __init__(self, headers, body=None, def __init__(self, headers, body=None,
version=1.0, status=200, reason="Ok"): version=1.0, status=200, reason="Ok"):
""" """
:param headers: dict representing HTTP response headers :param headers: dict representing HTTP response headers
:param body: file-like object :param body: file-like object
:param version: HTTP Version :param version: HTTP Version
@ -101,6 +102,7 @@ class FakeResponse(object):
def __init__(self, headers=None, body=None, def __init__(self, headers=None, body=None,
version=1.0, status_code=200, reason="Ok"): version=1.0, status_code=200, reason="Ok"):
""" """
:param headers: dict representing HTTP response headers :param headers: dict representing HTTP response headers
:param body: file-like object :param body: file-like object
:param version: HTTP Version :param version: HTTP Version
@ -179,6 +181,7 @@ class FakeNoTTYStdout(FakeTTYStdout):
def sort_url_by_query_keys(url): def sort_url_by_query_keys(url):
"""A helper function which sorts the keys of the query string of a url. """A helper function which sorts the keys of the query string of a url.
For example, an input of '/v2/tasks?sort_key=id&sort_dir=asc&limit=10' For example, an input of '/v2/tasks?sort_key=id&sort_dir=asc&limit=10'
returns '/v2/tasks?limit=10&sort_dir=asc&sort_key=id'. This is to returns '/v2/tasks?limit=10&sort_dir=asc&sort_key=id'. This is to
prevent non-deterministic ordering of the query string causing prevent non-deterministic ordering of the query string causing
@ -200,8 +203,7 @@ def sort_url_by_query_keys(url):
def build_call_record(method, url, headers, data): def build_call_record(method, url, headers, data):
"""Key the request body be ordered if it's a dict type. """Key the request body be ordered if it's a dict type."""
"""
if isinstance(data, dict): if isinstance(data, dict):
data = sorted(data.items()) data = sorted(data.items())
if isinstance(data, six.string_types): if isinstance(data, six.string_types):

View File

@ -44,7 +44,7 @@ class ImageMemberManager(base.ManagerWithFind):
if image and member: if image and member:
try: try:
out.append(self.get(image, member)) out.append(self.get(image, member))
#TODO(bcwaldon): narrow this down to 404 # TODO(bcwaldon): narrow this down to 404
except Exception: except Exception:
pass pass
elif image: elif image:
@ -52,7 +52,7 @@ class ImageMemberManager(base.ManagerWithFind):
elif member: elif member:
out.extend(self._list_by_member(member)) out.extend(self._list_by_member(member))
else: else:
#TODO(bcwaldon): figure out what is appropriate to do here as we # TODO(bcwaldon): figure out what is appropriate to do here as we
# are unable to provide the requested response # are unable to provide the requested response
pass pass
return out return out

View File

@ -26,7 +26,7 @@ from glanceclient.openstack.common.apiclient import base
UPDATE_PARAMS = ('name', 'disk_format', 'container_format', 'min_disk', UPDATE_PARAMS = ('name', 'disk_format', 'container_format', 'min_disk',
'min_ram', 'owner', 'size', 'is_public', 'protected', 'min_ram', 'owner', 'size', 'is_public', 'protected',
'location', 'checksum', 'copy_from', 'properties', 'location', 'checksum', 'copy_from', 'properties',
#NOTE(bcwaldon: an attempt to update 'deleted' will be # NOTE(bcwaldon: an attempt to update 'deleted' will be
# ignored, but we need to support it for backwards- # ignored, but we need to support it for backwards-
# compatibility with the legacy client library # compatibility with the legacy client library
'deleted') 'deleted')
@ -289,7 +289,7 @@ class ImageManager(base.ManagerWithFind):
return_request_id.append(resp.headers.get(OS_REQ_ID_HDR, None)) return_request_id.append(resp.headers.get(OS_REQ_ID_HDR, None))
def create(self, **kwargs): def create(self, **kwargs):
"""Create an image """Create an image.
TODO(bcwaldon): document accepted params TODO(bcwaldon): document accepted params
""" """
@ -324,7 +324,7 @@ class ImageManager(base.ManagerWithFind):
return Image(self, self._format_image_meta_for_user(body['image'])) return Image(self, self._format_image_meta_for_user(body['image']))
def update(self, image, **kwargs): def update(self, image, **kwargs):
"""Update an image """Update an image.
TODO(bcwaldon): document accepted params TODO(bcwaldon): document accepted params
""" """

View File

@ -30,8 +30,7 @@ class Controller(object):
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel) return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
def update(self, image_id, tag_value): def update(self, image_id, tag_value):
""" """Update an image with the given tag.
Update an image with the given tag.
:param image_id: image to be updated with the given tag. :param image_id: image to be updated with the given tag.
:param tag_value: value of the tag. :param tag_value: value of the tag.
@ -40,8 +39,7 @@ class Controller(object):
self.http_client.put(url) self.http_client.put(url)
def delete(self, image_id, tag_value): def delete(self, image_id, tag_value):
""" """Delete the tag associated with the given image.
Delete the tag associated with the given image.
:param image_id: Image whose tag to be deleted. :param image_id: Image whose tag to be deleted.
:param tag_value: tag value to be deleted. :param tag_value: tag value to be deleted.

View File

@ -177,14 +177,13 @@ class Controller(object):
def get(self, image_id): def get(self, image_id):
url = '/v2/images/%s' % image_id url = '/v2/images/%s' % image_id
resp, body = self.http_client.get(url) resp, body = self.http_client.get(url)
#NOTE(bcwaldon): remove 'self' for now until we have an elegant # NOTE(bcwaldon): remove 'self' for now until we have an elegant
# way to pass it into the model constructor without conflict # way to pass it into the model constructor without conflict
body.pop('self', None) body.pop('self', None)
return self.model(**body) return self.model(**body)
def data(self, image_id, do_checksum=True): def data(self, image_id, do_checksum=True):
""" """Retrieve data of an image.
Retrieve data of an image.
:param image_id: ID of the image to download. :param image_id: ID of the image to download.
:param do_checksum: Enable/disable checksum validation. :param do_checksum: Enable/disable checksum validation.
@ -200,8 +199,7 @@ class Controller(object):
return utils.IterableWithLength(body, content_length) return utils.IterableWithLength(body, content_length)
def upload(self, image_id, image_data, image_size=None): def upload(self, image_id, image_data, image_size=None):
""" """Upload the data for an image.
Upload the data for an image.
:param image_id: ID of the image to upload data for. :param image_id: ID of the image to upload data for.
:param image_data: File-like object supplying the data to upload. :param image_data: File-like object supplying the data to upload.
@ -233,14 +231,13 @@ class Controller(object):
raise TypeError(utils.exception_to_str(e)) raise TypeError(utils.exception_to_str(e))
resp, body = self.http_client.post(url, data=image) resp, body = self.http_client.post(url, data=image)
#NOTE(esheffield): remove 'self' for now until we have an elegant # NOTE(esheffield): remove 'self' for now until we have an elegant
# way to pass it into the model constructor without conflict # way to pass it into the model constructor without conflict
body.pop('self', None) body.pop('self', None)
return self.model(**body) return self.model(**body)
def update(self, image_id, remove_props=None, **kwargs): def update(self, image_id, remove_props=None, **kwargs):
""" """Update attributes of an image.
Update attributes of an image.
:param image_id: ID of the image to modify. :param image_id: ID of the image to modify.
:param remove_props: List of property names to remove :param remove_props: List of property names to remove
@ -256,7 +253,7 @@ class Controller(object):
if remove_props is not None: if remove_props is not None:
cur_props = image.keys() cur_props = image.keys()
new_props = kwargs.keys() new_props = kwargs.keys()
#NOTE(esheffield): Only remove props that currently exist on the # NOTE(esheffield): Only remove props that currently exist on the
# image and are NOT in the properties being updated / added # image and are NOT in the properties being updated / added
props_to_remove = set(cur_props).intersection( props_to_remove = set(cur_props).intersection(
set(remove_props).difference(new_props)) set(remove_props).difference(new_props))
@ -268,7 +265,7 @@ class Controller(object):
hdrs = {'Content-Type': 'application/openstack-images-v2.1-json-patch'} hdrs = {'Content-Type': 'application/openstack-images-v2.1-json-patch'}
self.http_client.patch(url, headers=hdrs, data=image.patch) self.http_client.patch(url, headers=hdrs, data=image.patch)
#NOTE(bcwaldon): calling image.patch doesn't clear the changes, so # NOTE(bcwaldon): calling image.patch doesn't clear the changes, so
# we need to fetch the image again to get a clean history. This is # we need to fetch the image again to get a clean history. This is
# an obvious optimization for warlock # an obvious optimization for warlock
return self.get(image_id) return self.get(image_id)

View File

@ -89,7 +89,8 @@ class NamespaceController(object):
return self.model(**body) return self.model(**body)
def list(self, **kwargs): def list(self, **kwargs):
"""Retrieve a listing of Namespace objects """Retrieve a listing of Namespace objects.
:param page_size: Number of items to request in each paginated request :param page_size: Number of items to request in each paginated request
:param limit: Use to request a specific page size. Expect a response :param limit: Use to request a specific page size. Expect a response
to a limited request to return between zero and limit to a limited request to return between zero and limit
@ -206,7 +207,7 @@ class ResourceTypeController(object):
self.http_client.delete(url) self.http_client.delete(url)
def list(self): def list(self):
"""Retrieve a listing of available resource types """Retrieve a listing of available resource types.
:returns generator over list of resource_types :returns generator over list of resource_types
""" """
@ -280,7 +281,7 @@ class PropertyController(object):
return self.model(**body) return self.model(**body)
def list(self, namespace, **kwargs): def list(self, namespace, **kwargs):
"""Retrieve a listing of metadata properties """Retrieve a listing of metadata properties.
:returns generator over list of objects :returns generator over list of objects
""" """
@ -365,7 +366,7 @@ class ObjectController(object):
return self.model(**body) return self.model(**body)
def list(self, namespace, **kwargs): def list(self, namespace, **kwargs):
"""Retrieve a listing of metadata objects """Retrieve a listing of metadata objects.
:returns generator over list of objects :returns generator over list of objects
""" """

View File

@ -21,7 +21,7 @@ import warlock.model as warlock
class SchemaBasedModel(warlock.Model): class SchemaBasedModel(warlock.Model):
"""Glance specific subclass of the warlock Model """Glance specific subclass of the warlock Model.
This implementation alters the function of the patch property This implementation alters the function of the patch property
to take into account the schema's core properties. With this version to take into account the schema's core properties. With this version
@ -35,8 +35,8 @@ class SchemaBasedModel(warlock.Model):
tags_patch = [] tags_patch = []
else: else:
tags_patch = [{"path": "/tags", tags_patch = [{"path": "/tags",
"value": self.get('tags'), "value": self.get('tags'),
"op": "replace"}] "op": "replace"}]
patch_string = jsonpatch.make_patch(original, new).to_string() patch_string = jsonpatch.make_patch(original, new).to_string()
patch = json.loads(patch_string) patch = json.loads(patch_string)
@ -69,7 +69,7 @@ class SchemaProperty(object):
def translate_schema_properties(schema_properties): def translate_schema_properties(schema_properties):
"""Parse the properties dictionary of a schema document """Parse the properties dictionary of a schema document.
:returns list of SchemaProperty objects :returns list of SchemaProperty objects
""" """
@ -87,7 +87,9 @@ class Schema(object):
self.properties = translate_schema_properties(raw_properties) self.properties = translate_schema_properties(raw_properties)
def is_core_property(self, property_name): def is_core_property(self, property_name):
"""Checks if a property with a given name is known to the schema, """
Checks if a property with a given name is known to the schema,
i.e. is either a base property or a custom one registered in i.e. is either a base property or a custom one registered in
schema-image.json file schema-image.json file
@ -97,7 +99,7 @@ class Schema(object):
return self._check_property(property_name, True) return self._check_property(property_name, True)
def is_base_property(self, property_name): def is_base_property(self, property_name):
"""Checks if a property with a given name is a base property """Checks if a property with a given name is a base property.
:param property_name: name of the property :param property_name: name of the property
:returns: True if the property is base, False otherwise :returns: True if the property is base, False otherwise

View File

@ -38,7 +38,7 @@ class Controller(object):
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel) return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
def list(self, **kwargs): def list(self, **kwargs):
"""Retrieve a listing of Task objects """Retrieve a listing of Task objects.
:param page_size: Number of tasks to request in each paginated request :param page_size: Number of tasks to request in each paginated request
:returns generator over list of Tasks :returns generator over list of Tasks
@ -87,7 +87,7 @@ class Controller(object):
url = '/v2/tasks?%s' % six.moves.urllib.parse.urlencode(filters) url = '/v2/tasks?%s' % six.moves.urllib.parse.urlencode(filters)
for task in paginate(url): for task in paginate(url):
#NOTE(flwang): remove 'self' for now until we have an elegant # NOTE(flwang): remove 'self' for now until we have an elegant
# way to pass it into the model constructor without conflict # way to pass it into the model constructor without conflict
task.pop('self', None) task.pop('self', None)
yield self.model(**task) yield self.model(**task)
@ -96,7 +96,7 @@ class Controller(object):
"""Get a task based on given task id.""" """Get a task based on given task id."""
url = '/v2/tasks/%s' % task_id url = '/v2/tasks/%s' % task_id
resp, body = self.http_client.get(url) resp, body = self.http_client.get(url)
#NOTE(flwang): remove 'self' for now until we have an elegant # NOTE(flwang): remove 'self' for now until we have an elegant
# way to pass it into the model constructor without conflict # way to pass it into the model constructor without conflict
body.pop('self', None) body.pop('self', None)
return self.model(**body) return self.model(**body)
@ -113,7 +113,7 @@ class Controller(object):
raise TypeError(utils.exception_to_str(e)) raise TypeError(utils.exception_to_str(e))
resp, body = self.http_client.post(url, data=task) resp, body = self.http_client.post(url, data=task)
#NOTE(flwang): remove 'self' for now until we have an elegant # NOTE(flwang): remove 'self' for now until we have an elegant
# way to pass it into the model constructor without conflict # way to pass it into the model constructor without conflict
body.pop('self', None) body.pop('self', None)
return self.model(**body) return self.model(**body)

View File

@ -1,7 +1,7 @@
# The order of packages is significant, because pip processes them in the order # The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration # of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later. # process, which may cause wedges in the gate later.
hacking<0.11,>=0.10.0 hacking>=0.10.0,<0.11
coverage>=3.6 coverage>=3.6
discover discover

10
tox.ini
View File

@ -40,15 +40,7 @@ downloadcache = ~/cache/pip
# H303 no wildcard import # H303 no wildcard import
# H404 multi line docstring should start with a summary # H404 multi line docstring should start with a summary
# TODO(kragniz) fix these and remove from the ignore list ignore = F403,F812,F821,H233,H303,H404
# E265 block comment should start with '# '
# H405 multi line docstring summary not separated with an empty line
# E123 closing bracket does not match indentation of opening bracket's line
# H238 old style class declaration, use new style (inherit from `object`)
# E128 continuation line under-indented for visual indent
ignore = F403,F812,F821,H233,H303,H404,E265,H405,E123,H238,E128
show-source = True show-source = True
exclude = .venv*,.tox,dist,*egg,build,.git,doc,*openstack/common*,*lib/python*,.update-venv exclude = .venv*,.tox,dist,*egg,build,.git,doc,*openstack/common*,*lib/python*,.update-venv