Skip to content

Commit e1fc615

Browse files
fix(kernel): match documented local path option types
Signed-off-by: Aakash Saravanan <aakash.saravanan@databricks.com>
1 parent 4bfd4b9 commit e1fc615

2 files changed

Lines changed: 26 additions & 8 deletions

File tree

‎src/databricks/sql/backend/kernel/client.py‎

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -587,20 +587,30 @@ def execute_command(
587587
stmt.set_sql(operation)
588588
allowed_paths = (
589589
cursor.connection.staging_allowed_local_path
590-
if _is_staging_statement(operation)
590+
if re.match(
591+
r"(?:PUT|GET)\b",
592+
_strip_leading_sql_comments(operation),
593+
re.IGNORECASE,
594+
)
591595
else None
592596
)
593-
if isinstance(allowed_paths, (str, os.PathLike)):
594-
allowed_paths = [allowed_paths]
595597
set_paths = getattr(stmt, "set_staging_allowed_local_paths", None)
596598
if callable(set_paths):
599+
if allowed_paths is not None and not isinstance(
600+
allowed_paths, (str, list)
601+
):
602+
raise ProgrammingError(
603+
"staging_allowed_local_path must be a string or a list of paths"
604+
)
605+
if isinstance(allowed_paths, str):
606+
allowed_paths = [allowed_paths]
597607
try:
598608
normalized_paths = [
599609
os.fsdecode(path) for path in allowed_paths or []
600610
]
601611
except (TypeError, ValueError) as exc:
602612
raise ProgrammingError(
603-
"staging_allowed_local_path must be a path or a list of paths"
613+
"staging_allowed_local_path must be a string or a list of paths"
604614
) from exc
605615
set_paths(normalized_paths)
606616
elif _is_staging_statement(operation):

‎tests/unit/test_kernel_client.py‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -811,7 +811,6 @@ def test_execute_command_forwards_row_limit(row_limit):
811811
[
812812
(None, []),
813813
("/tmp/files", ["/tmp/files"]),
814-
(Path("/tmp/files"), ["/tmp/files"]),
815814
([Path("/tmp/a"), Path("/tmp/b")], ["/tmp/a", "/tmp/b"]),
816815
(["/tmp/a", "/tmp/b"], ["/tmp/a", "/tmp/b"]),
817816
],
@@ -847,9 +846,18 @@ def test_execute_command_forwards_allowed_local_paths(allowed, expected, async_o
847846
(stmt.submit if async_op else stmt.execute).assert_called_once()
848847

849848

850-
@pytest.mark.parametrize("allowed", [123, [object()]])
851849
@pytest.mark.parametrize(
852-
"operation", ["SELECT 1", "PUT 'input' INTO '/Volumes/c/s/v/file'"]
850+
"allowed",
851+
[123, [object()], Path("/tmp/files"), ("/tmp/files",), (), {"/tmp/files": True}],
852+
)
853+
@pytest.mark.parametrize(
854+
"operation",
855+
[
856+
"SELECT 1",
857+
"PUT 'input' INTO '/Volumes/c/s/v/file'",
858+
"GET '/Volumes/c/s/v/file' TO 'output'",
859+
"REMOVE '/Volumes/c/s/v/file'",
860+
],
853861
)
854862
def test_malformed_local_paths_only_reject_transfers(allowed, operation):
855863
c = _make_client()
@@ -867,7 +875,7 @@ def execute():
867875
operation, MagicMock(), 1, 1, False, cursor, False, [], False, False
868876
)
869877

870-
if operation.startswith("PUT"):
878+
if operation.startswith(("PUT", "GET")):
871879
with pytest.raises(ProgrammingError, match="staging_allowed_local_path"):
872880
execute()
873881
stmt.execute.assert_not_called()

0 commit comments

Comments
 (0)