Skip to content

Commit 7bbd70d

Browse files
authored
Merge pull request #71 from mvoitko/feature/add-flake8-code-check
Add Flake8 check plugin to pytest. Fix code style
2 parents 72fbe2b + a1c60ee commit 7bbd70d

File tree

9 files changed

+80
-41
lines changed

9 files changed

+80
-41
lines changed

.gitignore

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
.DS_Store
2-
*.egg
32
/.env/
43
/.vscode/
5-
*.pyc
6-
.cache/
7-
*.iml
8-
/pybigquery.egg-info
9-
/dist
104
/build
5+
/dist
6+
/pybigquery.egg-info
7+
.idea/
8+
.cache/
9+
.pytest_cache/
1110
env
11+
venv/
12+
*.egg
13+
*.iml
14+
*.pyc

dev_requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ google-cloud-bigquery>=1.6.0
33
future==0.16.0
44

55
pytest==3.2.2
6+
pytest-flake8==1.0.6
67
pytz==2017.2

pybigquery/parse_url.py

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import re
2-
GROUP_DELIMITER = re.compile(r'\s*\,\s*')
3-
KEY_VALUE_DELIMITER = re.compile(r'\s*\:\s*')
42

53
from google.cloud.bigquery import QueryJobConfig
4+
from google.cloud.bigquery.dataset import DatasetReference
65
from google.cloud.bigquery.job import CreateDisposition, WriteDisposition, QueryPriority, SchemaUpdateOption
7-
86
from google.cloud.bigquery.table import EncryptionConfiguration, TableReference
9-
from google.cloud.bigquery.dataset import DatasetReference
7+
8+
GROUP_DELIMITER = re.compile(r'\s*\,\s*')
9+
KEY_VALUE_DELIMITER = re.compile(r'\s*\:\s*')
10+
1011

1112
def parse_boolean(bool_string):
1213
bool_string = bool_string.lower()
@@ -17,17 +18,22 @@ def parse_boolean(bool_string):
1718
else:
1819
raise ValueError()
1920

20-
def parse_url(url):
21+
22+
def parse_url(url): # noqa: C901
2123
query = url.query
2224

2325
# use_legacy_sql (legacy)
24-
if 'use_legacy_sql' in query: raise ValueError("legacy sql is not supported by this dialect")
26+
if 'use_legacy_sql' in query:
27+
raise ValueError("legacy sql is not supported by this dialect")
2528
# allow_large_results (legacy)
26-
if 'allow_large_results' in query: raise ValueError("allow_large_results is only allowed for legacy sql, which is not supported by this dialect")
29+
if 'allow_large_results' in query:
30+
raise ValueError("allow_large_results is only allowed for legacy sql, which is not supported by this dialect")
2731
# flatten_results (legacy)
28-
if 'flatten_results' in query: raise ValueError("flatten_results is only allowed for legacy sql, which is not supported by this dialect")
32+
if 'flatten_results' in query:
33+
raise ValueError("flatten_results is only allowed for legacy sql, which is not supported by this dialect")
2934
# maximum_billing_tier (deprecated)
30-
if 'maximum_billing_tier' in query: raise ValueError("maximum_billing_tier is a deprecated argument")
35+
if 'maximum_billing_tier' in query:
36+
raise ValueError("maximum_billing_tier is a deprecated argument")
3137

3238
project_id = url.host
3339
location = None
@@ -77,7 +83,8 @@ def parse_url(url):
7783

7884
# default_dataset
7985
if 'default_dataset' in query or 'dataset_id' in query or 'project_id' in query:
80-
raise ValueError("don't pass default_dataset, dataset_id, project_id in url query, instead use the url host and database")
86+
raise ValueError(
87+
"don't pass default_dataset, dataset_id, project_id in url query, instead use the url host and database")
8188

8289
# destination
8390
if 'destination' in query:
@@ -88,13 +95,15 @@ def parse_url(url):
8895
try:
8996
dest_project, dest_dataset, dest_table = query['destination'].split('.')
9097
except ValueError:
91-
raise ValueError("url query destination parameter should be fully qualified with project, dataset, and table")
98+
raise ValueError(
99+
"url query destination parameter should be fully qualified with project, dataset, and table")
92100

93101
job_config.destination = TableReference(DatasetReference(dest_project, dest_dataset), dest_table)
94102

95103
# destination_encryption_configuration
96104
if 'destination_encryption_configuration' in query:
97-
job_config.destination_encryption_configuration = EncryptionConfiguration(query['destination_encryption_configuration'])
105+
job_config.destination_encryption_configuration = EncryptionConfiguration(
106+
query['destination_encryption_configuration'])
98107

99108
# dry_run
100109
if 'dry_run' in query:

pybigquery/sqlalchemy_bigquery.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77

88
from google import auth
99
from google.cloud import bigquery
10-
from google.cloud.bigquery import dbapi, QueryJobConfig
10+
from google.cloud.bigquery import dbapi
1111
from google.cloud.bigquery.schema import SchemaField
12-
from google.cloud.bigquery.table import EncryptionConfiguration, TableReference
12+
from google.cloud.bigquery.table import TableReference
1313
from google.oauth2 import service_account
1414
from google.api_core.exceptions import NotFound
1515
from sqlalchemy.exc import NoSuchTableError
@@ -92,6 +92,7 @@ def format_label(self, label, name=None):
9292
result = self.quote(name)
9393
return result
9494

95+
9596
_type_map = {
9697
'STRING': types.String,
9798
'BOOLEAN': types.Boolean,
@@ -310,7 +311,6 @@ def _add_default_dataset_to_job_config(job_config, project_id, dataset_id):
310311

311312
job_config.default_dataset = '{}.{}'.format(project_id, dataset_id)
312313

313-
314314
def _create_client_from_credentials(self, credentials, default_query_job_config, project_id):
315315
if project_id is None:
316316
project_id = credentials.project_id
@@ -426,10 +426,20 @@ def _table_reference(self, provided_schema_name, provided_table_name,
426426
raise ValueError("Did not understand schema: {}".format(provided_schema_name))
427427
if (dataset_id_from_schema and dataset_id_from_table and
428428
dataset_id_from_schema != dataset_id_from_table):
429-
raise ValueError("dataset_id specified in schema and table_name disagree: got {} in schema, and {} in table_name".format(dataset_id_from_schema, dataset_id_from_table))
429+
raise ValueError(
430+
"dataset_id specified in schema and table_name disagree: "
431+
"got {} in schema, and {} in table_name".format(
432+
dataset_id_from_schema, dataset_id_from_table
433+
)
434+
)
430435
if (project_id_from_schema and project_id_from_table and
431436
project_id_from_schema != project_id_from_table):
432-
raise ValueError("project_id specified in schema and table_name disagree: got {} in schema, and {} in table_name".format(project_id_from_schema, project_id_from_table))
437+
raise ValueError(
438+
"project_id specified in schema and table_name disagree: "
439+
"got {} in schema, and {} in table_name".format(
440+
project_id_from_schema, project_id_from_table
441+
)
442+
)
433443
project_id = project_id_from_schema or project_id_from_table or client_project
434444
dataset_id = dataset_id_from_schema or dataset_id_from_table or self.dataset_id
435445

setup.cfg

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
[egg_info]
22
tag_build =
33

4+
[flake8]
5+
application-import-names = pybigquery
6+
import-order-style = pep8
7+
inline-quotes = double
8+
max-line-length = 120
9+
max-complexity = 18
10+
411
[tool:pytest]
5-
addopts= --tb short --capture no
12+
addopts= --tb short --capture no --color=yes --flake8
613
python_files=test/*test_*.py
714

815
[sqla_testing]

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ def readme():
77
with io.open("README.rst", "r", encoding="utf8") as f:
88
return f.read()
99

10+
1011
setup(
1112
name="pybigquery",
1213
version='0.4.15',

test/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
from sqlalchemy.dialects import registry
22

3-
registry.register("bigquery", "pybigquery.sqlalchemy_bigquery", "BigQueryDialect")
3+
registry.register("bigquery", "pybigquery.sqlalchemy_bigquery", "BigQueryDialect")

test/test_parse_url.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,15 @@ def test_basic(url_with_everything):
5555
assert credentials_path == '/some/path/to.json'
5656
assert isinstance(job_config, QueryJobConfig)
5757

58+
5859
@pytest.mark.parametrize('param, value', [
5960
('clustering_fields', ['a', 'b', 'c']),
6061
('create_disposition', 'CREATE_IF_NEEDED'),
6162
('destination', TableReference(DatasetReference('different-project', 'different-dataset'), 'table')),
62-
('destination_encryption_configuration', lambda enc: enc.kms_key_name == EncryptionConfiguration('some-configuration').kms_key_name),
63+
('destination_encryption_configuration',
64+
lambda enc: enc.kms_key_name == EncryptionConfiguration('some-configuration').kms_key_name),
6365
('dry_run', True),
64-
('labels', { 'a': 'b', 'c': 'd' }),
66+
('labels', {'a': 'b', 'c': 'd'}),
6567
('maximum_bytes_billed', 1000),
6668
('priority', 'INTERACTIVE'),
6769
('schema_update_options', ['ALLOW_FIELD_ADDITION', 'ALLOW_FIELD_RELAXATION']),
@@ -77,11 +79,6 @@ def test_all_values(url_with_everything, param, value):
7779
else:
7880
assert config_value == value
7981

80-
# def test_malformed():
81-
# location, dataset_id, arraysize, credentials_path, job_config = parse_url(make_url('bigquery:///?credentials_path=a'))
82-
83-
# print(credentials_path)
84-
# assert False
8582

8683
@pytest.mark.parametrize("param, value", [
8784
('arraysize', 'not-int'),
@@ -100,13 +97,15 @@ def test_bad_values(param, value):
10097
with pytest.raises(ValueError):
10198
parse_url(url)
10299

100+
103101
def test_empty_url():
104102
for value in parse_url(make_url('bigquery://')):
105103
assert value is None
106104

107105
for value in parse_url(make_url('bigquery:///')):
108106
assert value is None
109107

108+
110109
def test_empty_with_non_config():
111110
url = parse_url(make_url('bigquery:///?location=some-location&arraysize=1000&credentials_path=/some/path/to.json'))
112111
project_id, location, dataset_id, arraysize, credentials_path, job_config = url
@@ -118,6 +117,7 @@ def test_empty_with_non_config():
118117
assert credentials_path == '/some/path/to.json'
119118
assert job_config is None
120119

120+
121121
def test_only_dataset():
122122
url = parse_url(make_url('bigquery:///some-dataset'))
123123
project_id, location, dataset_id, arraysize, credentials_path, job_config = url
@@ -131,6 +131,7 @@ def test_only_dataset():
131131
# we can't actually test that the dataset is on the job_config,
132132
# since we take care of that afterwards, when we have a client to fill in the project
133133

134+
134135
@pytest.mark.parametrize('disallowed_arg', [
135136
'use_legacy_sql',
136137
'allow_large_results',
@@ -145,6 +146,7 @@ def test_disallowed(disallowed_arg):
145146
with pytest.raises(ValueError):
146147
parse_url(url)
147148

149+
148150
@pytest.mark.parametrize('not_implemented_arg', [
149151
'query_parameters',
150152
'table_definitions',

test/test_sqlalchemy_bigquery.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ def session_using_test_dataset(engine_using_test_dataset):
158158
def inspector(engine):
159159
return inspect(engine)
160160

161+
161162
@pytest.fixture(scope='session')
162163
def inspector_using_test_dataset(engine_using_test_dataset):
163164
return inspect(engine_using_test_dataset)
@@ -197,8 +198,8 @@ def test_dry_run(engine, api_client):
197198
sql = 'SELECT * FROM sample_one_row'
198199
with pytest.raises(BadRequest) as excinfo:
199200
api_client.dry_run_query(sql)
200-
201-
assert 'Table name "sample_one_row" missing dataset while no default dataset is set in the request.' in str(excinfo.value.message)
201+
expected_message = 'Table name "sample_one_row" missing dataset while no default dataset is set in the request.'
202+
assert expected_message in str(excinfo.value.message)
202203

203204

204205
def test_engine_with_dataset(engine_using_test_dataset):
@@ -278,7 +279,7 @@ def test_reflect_select_shared_table(engine):
278279

279280
def test_reflect_table_does_not_exist(engine):
280281
with pytest.raises(NoSuchTableError):
281-
table = Table('test_pybigquery.table_does_not_exist', MetaData(bind=engine), autoload=True)
282+
Table('test_pybigquery.table_does_not_exist', MetaData(bind=engine), autoload=True)
282283

283284
assert Table('test_pybigquery.table_does_not_exist', MetaData(bind=engine)).exists() is False
284285

@@ -313,8 +314,8 @@ def test_nested_labels(engine, table):
313314
col = table.c.integer
314315
exprs = [
315316
sqlalchemy.func.sum(
316-
sqlalchemy.func.sum(col.label("inner")
317-
).label("outer")).over(),
317+
sqlalchemy.func.sum(col.label("inner")).label("outer")
318+
).over(),
318319
sqlalchemy.func.sum(
319320
sqlalchemy.case([[
320321
sqlalchemy.literal(True),
@@ -345,7 +346,10 @@ def test_session_query(session, table, session_using_test_dataset, table_using_t
345346
table.c.string,
346347
col_concat,
347348
func.avg(table.c.integer),
348-
func.sum(case([(table.c.boolean == True, 1)], else_=0))
349+
func.sum(case(
350+
[(table.c.boolean == sqlalchemy.literal(True), 1)],
351+
else_=0
352+
))
349353
)
350354
.group_by(table.c.string, col_concat)
351355
.having(func.avg(table.c.integer) > 10)
@@ -442,7 +446,7 @@ def test_dml(engine, session, table_dml):
442446

443447
def test_create_table(engine):
444448
meta = MetaData()
445-
table = Table(
449+
Table(
446450
'test_pybigquery.test_table_create', meta,
447451
Column('integer_c', sqlalchemy.Integer, doc="column description"),
448452
Column('float_c', sqlalchemy.Float),
@@ -472,6 +476,7 @@ class TableTest(Base):
472476
Base.metadata.create_all(engine)
473477
Base.metadata.drop_all(engine)
474478

479+
475480
def test_schemas_names(inspector, inspector_using_test_dataset):
476481
datasets = inspector.get_schema_names()
477482
assert 'test_pybigquery' in datasets
@@ -507,10 +512,10 @@ def test_view_names(inspector, inspector_using_test_dataset):
507512

508513

509514
def test_get_indexes(inspector, inspector_using_test_dataset):
510-
for table in ['test_pybigquery.sample', 'test_pybigquery.sample_one_row']:
515+
for _ in ['test_pybigquery.sample', 'test_pybigquery.sample_one_row']:
511516
indexes = inspector.get_indexes('test_pybigquery.sample')
512517
assert len(indexes) == 2
513-
assert indexes[0] == {'name':'partition', 'column_names': ['timestamp'], 'unique': False}
518+
assert indexes[0] == {'name': 'partition', 'column_names': ['timestamp'], 'unique': False}
514519
assert indexes[1] == {'name': 'clustering', 'column_names': ['integer', 'string'], 'unique': False}
515520

516521

@@ -555,6 +560,7 @@ def test_table_reference(dialect, provided_schema_name,
555560
assert ref.dataset_id == 'dataset'
556561
assert ref.project == 'project'
557562

563+
558564
@pytest.mark.parametrize('provided_schema_name,provided_table_name,client_project',
559565
[
560566
('project.dataset', 'other_dataset.table', 'project'),

0 commit comments

Comments
 (0)