Skip to content

Commit 22842ea

Browse files
authored
build: Embrace ruff (#319)
1 parent c62956c commit 22842ea

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+285
-236
lines changed

.vscode/extensions.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"recommendations": [
3+
"charliermarsh.ruff"
4+
]
5+
}

.vscode/settings.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,24 @@
11
{
2+
"files.trimTrailingWhitespace": true,
3+
"files.insertFinalNewline": true,
4+
"files.encoding": "utf8",
5+
"files.eol": "\n",
26
"python.testing.pytestArgs": [
37
"tests"
48
],
59
"python.testing.unittestEnabled": false,
610
"python.testing.pytestEnabled": true,
11+
"[python]": {
12+
"editor.defaultFormatter": "charliermarsh.ruff",
13+
"editor.formatOnSave": true,
14+
"editor.tabSize": 4,
15+
"editor.codeActionsOnSave": {
16+
"source.organizeImports": "explicit"
17+
}
18+
},
19+
"files.exclude": {
20+
"**/__pycache__": true,
21+
"build/**": true
22+
},
23+
"editor.rulers": [99],
724
}

examples/connect/databricks/dash/app.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
html.Div(id="greeting", children="Loading..."),
2424
html.Div(id="table-container"),
2525
html.Div(id="dummy"), # dummy element to trigger callback on page load
26-
]
26+
],
2727
)
2828

2929

@@ -38,7 +38,8 @@ def update_page(_):
3838
"""
3939
session_token = flask.request.headers.get("Posit-Connect-User-Session-Token")
4040
posit_strategy = PositCredentialsStrategy(
41-
local_strategy=databricks_cli, user_session_token=session_token
41+
local_strategy=databricks_cli,
42+
user_session_token=session_token,
4243
)
4344
cfg = Config(
4445
host=DATABRICKS_HOST_URL,

examples/connect/databricks/fastapi/app.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
# -*- coding: utf-8 -*-
22
# mypy: ignore-errors
3+
from __future__ import annotations
4+
35
import os
4-
from typing import Annotated
6+
from typing import TYPE_CHECKING, Annotated
57

68
from databricks import sql
79
from databricks.sdk.core import Config, databricks_cli
810
from fastapi import FastAPI, Header
9-
from fastapi.responses import JSONResponse
1011

1112
from posit.connect.external.databricks import PositCredentialsStrategy
1213

14+
if TYPE_CHECKING:
15+
from fastapi.responses import JSONResponse
16+
1317
DATABRICKS_HOST = os.getenv("DATABRICKS_HOST")
1418
DATABRICKS_HOST_URL = f"https://{DATABRICKS_HOST}"
1519
SQL_HTTP_PATH = os.getenv("DATABRICKS_PATH")

examples/connect/databricks/flask/app.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ def get_fares():
3131

3232
session_token = request.headers.get("Posit-Connect-User-Session-Token")
3333
posit_strategy = PositCredentialsStrategy(
34-
local_strategy=databricks_cli, user_session_token=session_token
34+
local_strategy=databricks_cli,
35+
user_session_token=session_token,
3536
)
3637
cfg = Config(
3738
host=DATABRICKS_HOST_URL,

examples/connect/databricks/shiny/app.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ def server(i: Inputs, o: Outputs, session: Session):
2424
"""
2525
session_token = session.http_conn.headers.get("Posit-Connect-User-Session-Token")
2626
posit_strategy = PositCredentialsStrategy(
27-
local_strategy=databricks_cli, user_session_token=session_token
27+
local_strategy=databricks_cli,
28+
user_session_token=session_token,
2829
)
2930
cfg = Config(
3031
host=DATABRICKS_HOST_URL,

examples/connect/databricks/streamlit/app.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616

1717
session_token = st.context.headers.get("Posit-Connect-User-Session-Token")
1818
posit_strategy = PositCredentialsStrategy(
19-
local_strategy=databricks_cli, user_session_token=session_token
19+
local_strategy=databricks_cli,
20+
user_session_token=session_token,
2021
)
2122
cfg = Config(
2223
host=DATABRICKS_HOST_URL,

integration/tests/posit/connect/test_users.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,19 @@ class TestUser:
66
def setup_class(cls):
77
cls.client = client = connect.Client()
88
cls.aron = client.users.create(
9-
username="aron", email="[email protected]", password="s3cur3p@ssword"
9+
username="aron",
10+
11+
password="s3cur3p@ssword",
1012
)
1113
cls.bill = client.users.create(
12-
username="bill", email="[email protected]", password="s3cur3p@ssword"
14+
username="bill",
15+
16+
password="s3cur3p@ssword",
1317
)
1418
cls.cole = client.users.create(
15-
username="cole", email="[email protected]", password="s3cur3p@ssword"
19+
username="cole",
20+
21+
password="s3cur3p@ssword",
1622
)
1723

1824
def test_lock(self):
@@ -71,7 +77,9 @@ def test_find_one(self):
7177

7278
def test_multiple_users(self):
7379
user = self.client.users.create(
74-
username="example", email="[email protected]", password="s3cur3p@ssword"
80+
username="example",
81+
82+
password="s3cur3p@ssword",
7583
)
7684
# assert filtering limits to the provided user.
7785
assert self.me.content.find_one() == self.content

pyproject.toml

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,19 @@ docstring-code-format = true
4444
docstring-code-line-length = "dynamic"
4545

4646
[tool.ruff.lint]
47-
select = [
47+
extend-ignore = [
48+
"E501", # Line too long
49+
"PT011", # `pytest.raises(ValueError)` is too broad
50+
"PT022", # No teardown in fixture
51+
"F841", # Local variable is assigned but never used
52+
"COM812", # missing-trailing-comma
53+
"ISC001", # single-line-implicit-string-concatenation
54+
"ISC002", # multi-line-implicit-string-concatenation
55+
]
56+
extend-select = [
57+
# "C90", # Many false positives # C90; mccabe: https://docs.astral.sh/ruff/rules/complex-structure/
58+
# "DTZ", # Dates with timezones are different from dates without timezones # DTZ; flake8-datetimez: https://docs.astral.sh/ruff/rules/#flake8-datetimez-dtz
59+
4860
# flake8-builtins
4961
# https://docs.astral.sh/ruff/rules/#flake8-builtins-a
5062
#
@@ -58,17 +70,28 @@ select = [
5870
# Check docstring formatting. Many of these rules are intentionally ignored below.
5971
"D",
6072

61-
# pyflakes - unused-import
62-
# https://docs.astral.sh/ruff/rules/unused-import/
63-
#
64-
# Check for unused imports.
65-
"F401",
66-
67-
# isort
68-
# https://docs.astral.sh/ruff/rules/#isort-i
69-
#
70-
# Sort imports.
71-
"I",
73+
"E", # E; pycodestyle: https://docs.astral.sh/ruff/rules/#pycodestyle-e-w
74+
"F", # F; Pyflakes: https://docs.astral.sh/ruff/rules/#pyflakes-f
75+
"I", # I; isort: https://docs.astral.sh/ruff/rules/#isort-i
76+
"B", # B; flake8-bugbear: https://docs.astral.sh/ruff/rules/#flake8-bugbear-b
77+
"Q", # Q; flake8-quotes: https://docs.astral.sh/ruff/rules/#flake8-quotes-q
78+
"COM", # COM; Commas: https://docs.astral.sh/ruff/rules/#flake8-commas-com
79+
"C4", # C4; flake8-comprehensions: https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4
80+
"FA102", # FA102; flake8-future-annotations: https://docs.astral.sh/ruff/rules/#flake8-future-annotations-fa
81+
"ISC", # ISC; flake8-implicit-str-concat: https://docs.astral.sh/ruff/rules/#flake8-implicit-str-concat-isc
82+
"ICN", # ICN; flake8-import-conventions: https://docs.astral.sh/ruff/rules/#flake8-import-conventions-icn
83+
"PIE", # PIE; flake8-pie: https://docs.astral.sh/ruff/rules/#flake8-pie-pie
84+
"PYI013", # PYI013; flake8-pyi Non-empty class body must not contain `...`: https://docs.astral.sh/ruff/rules/#flake8-pyi-pyi
85+
"PYI030", # PYI030; flake8-pyi Multiple literal members in a union: https://docs.astral.sh/ruff/rules/#flake8-pyi-pyi
86+
"PYI034", # PYI034; flake8-pyi `__new__` methods usually reutrn `Self`: https://docs.astral.sh/ruff/rules/#flake8-pyi-pyi
87+
"PT", # PT; flake8-pytest-style: https://docs.astral.sh/ruff/rules/#flake8-pytest-style-pt
88+
"SIM118", # SIM118; flake8-simplify Use `key {operator} dict`: https://docs.astral.sh/ruff/rules/#flake8-simplify-sim
89+
"TCH", # TCH; flake8-type-checking: https://docs.astral.sh/ruff/rules/#flake8-type-checking-tch
90+
# "FIX", # FIX; flake8-fixme: https://docs.astral.sh/ruff/rules/#flake8-fixme-fix
91+
# "PGH", # PGH; pygrep-hooks: https://docs.astral.sh/ruff/rules/#pygrep-hooks-pgh
92+
"NPY", # NPY; NumPy-specific rules: https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy
93+
"RUF005", # RUF005; Ruff specific rules Consider {expression} instead of concatenation: https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf
94+
"RUF100", # RUF100; Ruff specific rules Unused `noqa` directive https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf
7295
]
7396
ignore = [
7497
# NumPy style docstring convention with noted exceptions.
@@ -95,6 +118,14 @@ ignore = [
95118
[tool.ruff.lint.pydocstyle]
96119
convention = "numpy"
97120

121+
# # Ruff is enabled in config file to run on save
122+
# Disable isort due to timing conflict with ruff
123+
[tool.isort]
124+
skip_glob = "**"
125+
# Disable local black to avoid conflict with ruff
126+
[tool.black]
127+
exclude = ".*"
128+
98129

99130
[dependency-groups]
100131
build = ["build"]

src/posit/connect/bundles.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def download(self, output: io.BufferedWriter | str) -> None:
7474
"""
7575
if not isinstance(output, (io.BufferedWriter, str)):
7676
raise TypeError(
77-
f"download() expected argument type 'io.BufferedWriter` or 'str', but got '{type(output).__name__}'"
77+
f"download() expected argument type 'io.BufferedWriter` or 'str', but got '{type(output).__name__}'",
7878
)
7979

8080
path = f"v1/content/{self.content_guid}/bundles/{self.id}/download"
@@ -160,7 +160,7 @@ def create(self, archive: io.BufferedReader | bytes | str) -> Bundle:
160160
data = file.read()
161161
else:
162162
raise TypeError(
163-
f"create() expected argument type 'io.BufferedReader', 'bytes', or 'str', but got '{type(archive).__name__}'"
163+
f"create() expected argument type 'io.BufferedReader', 'bytes', or 'str', but got '{type(archive).__name__}'",
164164
)
165165

166166
path = f"v1/content/{self.content_guid}/bundles"

0 commit comments

Comments
 (0)