Skip to content

Commit 8a444e2

Browse files
authored
SNOW-633094: Switch all source code to use f-strings and with statements (#331)
1 parent ad44ebf commit 8a444e2

18 files changed

+734
-853
lines changed

.github/workflows/build_test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ jobs:
124124
dst_dir = Path(".") / ".tox"
125125
dst_dir.mkdir()
126126
for src_file in src_dir.glob("*/.coverage"):
127-
dst_file = dst_dir / ".coverage.{}".format(src_file.parent.name[9:])
128-
print("{} copy to {}".format(src_file, dst_file))
127+
dst_file = dst_dir / f".coverage.{src_file.parent.name[9:]}"
128+
print(f"{src_file} copy to {dst_file}")
129129
shutil.copy(str(src_file), str(dst_file))'
130130
- name: Combine coverages
131131
run: python -m tox -e coverage

.github/workflows/snyk-issue.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Snyk Issue
1+
name: Snyk Issue
22

33
on:
44
schedule:
@@ -26,4 +26,3 @@ jobs:
2626
jira_token: ${{ secrets.jira_token_public_repo }}
2727
env:
2828
gh_token: ${{ secrets.github_token }}
29-

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ repos:
1313
hooks:
1414
- id: isort
1515
- repo: https://github.com/asottile/pyupgrade
16-
rev: v2.34.0
16+
rev: v2.37.3
1717
hooks:
1818
- id: pyupgrade
1919
args: [--py37-plus]
@@ -25,7 +25,7 @@ repos:
2525
- --safe
2626
language_version: python3
2727
- repo: https://github.com/Lucas-C/pre-commit-hooks.git
28-
rev: v1.2.0
28+
rev: v1.3.0
2929
hooks:
3030
- id: insert-license
3131
name: insert-py-license

src/snowflake/sqlalchemy/base.py

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ def visit_merge_into(self, merge_into, **kw):
163163
)
164164

165165
def visit_merge_into_clause(self, merge_into_clause, **kw):
166+
case_predicate = (
167+
f" AND {str(merge_into_clause.predicate._compiler_dispatch(self, **kw))}"
168+
if merge_into_clause.predicate is not None
169+
else ""
170+
)
166171
if merge_into_clause.command == "INSERT":
167172
sets, sets_tos = zip(*merge_into_clause.set.items())
168173
sets, sets_tos = list(sets), list(sets_tos)
@@ -171,9 +176,7 @@ def visit_merge_into_clause(self, merge_into_clause, **kw):
171176
*sorted(merge_into_clause.set.items(), key=operator.itemgetter(0))
172177
)
173178
return "WHEN NOT MATCHED{} THEN {} ({}) VALUES ({})".format(
174-
" AND %s" % merge_into_clause.predicate._compiler_dispatch(self, **kw)
175-
if merge_into_clause.predicate is not None
176-
else "",
179+
case_predicate,
177180
merge_into_clause.command,
178181
", ".join(sets),
179182
", ".join(map(lambda e: e._compiler_dispatch(self, **kw), sets_tos)),
@@ -193,9 +196,7 @@ def visit_merge_into_clause(self, merge_into_clause, **kw):
193196
else ""
194197
)
195198
return "WHEN MATCHED{} THEN {}{}".format(
196-
" AND %s" % merge_into_clause.predicate._compiler_dispatch(self, **kw)
197-
if merge_into_clause.predicate is not None
198-
else "",
199+
case_predicate,
199200
merge_into_clause.command,
200201
" SET %s" % sets if merge_into_clause.set else "",
201202
)
@@ -296,7 +297,7 @@ def visit_aws_bucket(self, aws_bucket, **kw):
296297
)
297298
)
298299
uri = "'s3://{}{}'".format(
299-
aws_bucket.bucket, "/" + aws_bucket.path if aws_bucket.path else ""
300+
aws_bucket.bucket, f"/{aws_bucket.path}" if aws_bucket.path else ""
300301
)
301302
return (
302303
uri,
@@ -316,14 +317,14 @@ def visit_azure_container(self, azure_container, **kw):
316317
encryption_list.sort(key=operator.itemgetter(0))
317318
encryption = "ENCRYPTION=({})".format(
318319
" ".join(
319-
("{}='{}'" if isinstance(v, string_types) else "{}={}").format(n, v)
320+
f"{n}='{v}'" if isinstance(v, string_types) else f"{n}={v}"
320321
for n, v in encryption_list
321322
)
322323
)
323324
uri = "'azure://{}.blob.core.windows.net/{}{}'".format(
324325
azure_container.account,
325326
azure_container.container,
326-
"/" + azure_container.path if azure_container.path else "",
327+
f"/{azure_container.path}" if azure_container.path else "",
327328
)
328329
return (
329330
uri,
@@ -333,15 +334,10 @@ def visit_azure_container(self, azure_container, **kw):
333334

334335
def visit_external_stage(self, external_stage, **kw):
335336
if external_stage.file_format is None:
336-
return "@{}{}{}".format(
337-
external_stage.namespace, external_stage.name, external_stage.path
337+
return (
338+
f"@{external_stage.namespace}{external_stage.name}{external_stage.path}"
338339
)
339-
return "@{}{}{} (file_format => {})".format(
340-
external_stage.namespace,
341-
external_stage.name,
342-
external_stage.path,
343-
external_stage.file_format,
344-
)
340+
return f"@{external_stage.namespace}{external_stage.name}{external_stage.path} (file_format => {external_stage.file_format})"
345341

346342
def delete_extra_from_clause(
347343
self, delete_stmt, from_table, extra_froms, from_hints, **kw
@@ -378,18 +374,9 @@ def visit_regexp_replace_op_binary(self, binary, operator, **kw):
378374
string, pattern, flags = self._get_regexp_args(binary, kw)
379375
replacement = self.process(binary.modifiers["replacement"], **kw)
380376
if flags is None:
381-
return "REGEXP_REPLACE({}, {}, {})".format(
382-
string,
383-
pattern,
384-
replacement,
385-
)
377+
return f"REGEXP_REPLACE({string}, {pattern}, {replacement})"
386378
else:
387-
return "REGEXP_REPLACE({}, {}, {}, {})".format(
388-
string,
389-
pattern,
390-
replacement,
391-
flags,
392-
)
379+
return f"REGEXP_REPLACE({string}, {pattern}, {replacement}, {flags})"
393380

394381
def visit_not_regexp_match_op_binary(self, binary, operator, **kw):
395382
return f"NOT {self.visit_regexp_match_op_binary(binary, operator, **kw)}"

src/snowflake/sqlalchemy/custom_commands.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,13 @@ def __init__(self, command):
4040
self.command = command
4141

4242
def __repr__(self):
43+
case_predicate = (
44+
f" AND {str(self.predicate)}" if self.predicate is not None else ""
45+
)
4346
if self.command == "INSERT":
4447
sets, sets_tos = zip(*self.set.items())
4548
return "WHEN NOT MATCHED{} THEN {} ({}) VALUES ({})".format(
46-
" AND %s" % self.predicate if self.predicate is not None else "",
49+
case_predicate,
4750
self.command,
4851
", ".join(sets),
4952
", ".join(map(str, sets_tos)),
@@ -56,9 +59,9 @@ def __repr__(self):
5659
else ""
5760
)
5861
return "WHEN MATCHED{} THEN {}{}".format(
59-
" AND %s" % self.predicate if self.predicate is not None else "",
62+
case_predicate,
6063
self.command,
61-
" SET %s" % sets if self.set else "",
64+
f" SET {str(sets)}" if self.set else "",
6265
)
6366

6467
def values(self, **kwargs):
@@ -72,7 +75,7 @@ def where(self, expr):
7275
def __repr__(self):
7376
clauses = " ".join([repr(clause) for clause in self.clauses])
7477
return f"MERGE INTO {self.target} USING {self.source} ON {self.on}" + (
75-
" " + clauses if clauses else ""
78+
f" {clauses}" if clauses else ""
7679
)
7780

7881
def when_matched_then_update(self):
@@ -450,7 +453,7 @@ def from_parent_stage(cls, parent_stage, path, file_format=None):
450453
"""
451454
return cls(
452455
parent_stage.name,
453-
parent_stage.path + "/" + path,
456+
f"{parent_stage.path}/{path}",
454457
parent_stage.namespace,
455458
file_format,
456459
)
@@ -514,15 +517,15 @@ def __repr__(self):
514517
)
515518
encryption = "ENCRYPTION=({})".format(
516519
" ".join(
517-
("{}='{}'" if isinstance(v, string_types) else "{}={}").format(n, v)
520+
f"{n}='{v}'" if isinstance(v, string_types) else f"{n}={v}"
518521
for n, v in self.encryption_used.items()
519522
)
520523
)
521-
uri = "'s3://{}{}'".format(self.bucket, "/" + self.path if self.path else "")
524+
uri = "'s3://{}{}'".format(self.bucket, f"/{self.path}" if self.path else "")
522525
return "{}{}{}".format(
523526
uri,
524-
" " + credentials if self.credentials_used else "",
525-
" " + encryption if self.encryption_used else "",
527+
f" {credentials}" if self.credentials_used else "",
528+
f" {encryption}" if self.encryption_used else "",
526529
)
527530

528531
def credentials(
@@ -590,12 +593,12 @@ def __repr__(self):
590593
)
591594
encryption = "ENCRYPTION=({})".format(
592595
" ".join(
593-
("{}='{}'" if isinstance(v, string_types) else "{}={}").format(n, v)
596+
f"{n}='{v}'" if isinstance(v, string_types) else f"{n}={v}"
594597
for n, v in self.encryption_used.items()
595598
)
596599
)
597600
uri = "'azure://{}.blob.core.windows.net/{}{}'".format(
598-
self.account, self.container, "/" + self.path if self.path else ""
601+
self.account, self.container, f"/{self.path}" if self.path else ""
599602
)
600603
return "{}{}{}".format(
601604
uri,

src/snowflake/sqlalchemy/snowdialect.py

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ def create_connect_args(self, url):
204204
opts["schema"] = name_spaces[1]
205205
else:
206206
raise sa_exc.ArgumentError(
207-
"Invalid name space is specified: {}".format(opts["database"])
207+
f"Invalid name space is specified: {opts['database']}"
208208
)
209209
if ".snowflakecomputing.com" not in opts["host"] and not opts.get("port"):
210210
opts["account"] = opts["host"]
@@ -239,11 +239,7 @@ def _has_object(self, connection, object_type, object_name, schema=None):
239239
full_name = self._denormalize_quote_join(schema, object_name)
240240
try:
241241
results = connection.execute(
242-
text(
243-
"DESC {} /* sqlalchemy:_has_object */ {}".format(
244-
object_type, full_name
245-
)
246-
)
242+
text(f"DESC {object_type} /* sqlalchemy:_has_object */ {full_name}")
247243
)
248244
row = results.fetchone()
249245
have = row is not None
@@ -529,9 +525,7 @@ def _get_schema_columns(self, connection, schema, **kw):
529525
col_type_kw = {}
530526
if col_type is None:
531527
sa_util.warn(
532-
"Did not recognize type '{}' of column '{}'".format(
533-
coltype, column_name
534-
)
528+
f"Did not recognize type '{coltype}' of column '{column_name}'"
535529
)
536530
col_type = sqltypes.NULLTYPE
537531
else:
@@ -624,9 +618,7 @@ def _get_table_columns(self, connection, table_name, schema=None, **kw):
624618
col_type_kw = {}
625619
if col_type is None:
626620
sa_util.warn(
627-
"Did not recognize type '{}' of column '{}'".format(
628-
coltype, column_name
629-
)
621+
f"Did not recognize type '{coltype}' of column '{column_name}'"
630622
)
631623
col_type = sqltypes.NULLTYPE
632624
else:
@@ -685,9 +677,7 @@ def get_table_names(self, connection, schema=None, **kw):
685677
if schema:
686678
cursor = connection.execute(
687679
text(
688-
"SHOW /* sqlalchemy:get_table_names */ TABLES IN {}".format(
689-
self._denormalize_quote_join(schema)
690-
)
680+
f"SHOW /* sqlalchemy:get_table_names */ TABLES IN {self._denormalize_quote_join(schema)}"
691681
)
692682
)
693683
else:
@@ -709,9 +699,7 @@ def get_view_names(self, connection, schema=None, **kw):
709699
if schema:
710700
cursor = connection.execute(
711701
text(
712-
"SHOW /* sqlalchemy:get_view_names */ VIEWS IN {}".format(
713-
self._denormalize_quote_join(schema)
714-
)
702+
f"SHOW /* sqlalchemy:get_view_names */ VIEWS IN {self._denormalize_quote_join(schema)}"
715703
)
716704
)
717705
else:
@@ -730,18 +718,15 @@ def get_view_definition(self, connection, view_name, schema=None, **kw):
730718
if schema:
731719
cursor = connection.execute(
732720
text(
733-
"SHOW /* sqlalchemy:get_view_definition */ VIEWS "
734-
"LIKE '{}' IN {}".format(
735-
self._denormalize_quote_join(view_name),
736-
self._denormalize_quote_join(schema),
737-
)
721+
f"SHOW /* sqlalchemy:get_view_definition */ VIEWS \
722+
LIKE '{self._denormalize_quote_join(view_name)}' IN {self._denormalize_quote_join(schema)}"
738723
)
739724
)
740725
else:
741726
cursor = connection.execute(
742727
text(
743-
"SHOW /* sqlalchemy:get_view_definition */ VIEWS "
744-
"LIKE '{}'".format(self._denormalize_quote_join(view_name))
728+
f"SHOW /* sqlalchemy:get_view_definition */ VIEWS \
729+
LIKE '{self._denormalize_quote_join(view_name)}'"
745730
)
746731
)
747732

@@ -759,8 +744,8 @@ def get_temp_table_names(self, connection, schema=None, **kw):
759744
if schema:
760745
cursor = connection.execute(
761746
text(
762-
"SHOW /* sqlalchemy:get_temp_table_names */ TABLES "
763-
"IN {}".format(self._denormalize_quote_join(schema))
747+
f"SHOW /* sqlalchemy:get_temp_table_names */ TABLES \
748+
IN {self._denormalize_quote_join(schema)}"
764749
)
765750
)
766751
else:
@@ -807,7 +792,7 @@ def _get_table_comment(self, connection, table_name, schema=None, **kw):
807792
"SHOW /* sqlalchemy:_get_table_comment */ "
808793
"TABLES LIKE '{}'{}".format(
809794
table_name,
810-
(f" IN SCHEMA {self.normalize_name(schema)}") if schema else "",
795+
f" IN SCHEMA {self.normalize_name(schema)}" if schema else "",
811796
)
812797
)
813798
cursor = connection.execute(text(sql_command))
@@ -821,7 +806,7 @@ def _get_view_comment(self, connection, table_name, schema=None, **kw):
821806
"SHOW /* sqlalchemy:_get_view_comment */ "
822807
"VIEWS LIKE '{}'{}".format(
823808
table_name,
824-
(f" IN SCHEMA {self.normalize_name(schema)}") if schema else "",
809+
f" IN SCHEMA {self.normalize_name(schema)}" if schema else "",
825810
)
826811
)
827812
cursor = connection.execute(text(sql_command))

tests/conftest.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,7 @@
2323
INTERNAL_SKIP_TAGS = {"external"}
2424
RUNNING_ON_GH = os.getenv("GITHUB_ACTIONS") == "true"
2525

26-
if os.getenv("TRAVIS") == "true":
27-
TEST_SCHEMA = "TRAVIS_JOB_{}".format(os.getenv("TRAVIS_JOB_ID"))
28-
else:
29-
TEST_SCHEMA = "sqlalchemy_tests_" + str(uuid.uuid4()).replace("-", "_")
26+
TEST_SCHEMA = f"sqlalchemy_tests_{str(uuid.uuid4()).replace('-', '_')}"
3027

3128
create_engine_with_future_flag = create_engine
3229

0 commit comments

Comments
 (0)