Skip to content

Commit 5d37bc1

Browse files
committed
build: ubuntu-24.04, more ruff rules
1 parent 8efe482 commit 5d37bc1

13 files changed

+86
-52
lines changed

.github/workflows/apply-pip-compile.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ on: workflow_dispatch
55
jobs:
66
apply-pip-compile:
77
name: Apply pip compile
8-
runs-on: ubuntu-latest
8+
runs-on: ubuntu-24.04
99
steps:
1010
- uses: actions/checkout@v4
1111
- uses: deargen/workflows/actions/apply-pip-compile@master

.github/workflows/check-docs.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ on: pull_request
44

55
jobs:
66
mkdocs:
7-
runs-on: ubuntu-latest
7+
runs-on: ubuntu-24.04
88

99
steps:
1010
- uses: actions/checkout@v4

.github/workflows/check-pip-compile.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ concurrency:
1414
jobs:
1515
check-pip-compile:
1616
name: Check pip compile
17-
runs-on: ubuntu-latest
17+
runs-on: ubuntu-24.04
1818
steps:
1919
- uses: actions/checkout@v4
2020
- uses: deargen/workflows/actions/check-pip-compile@master

.github/workflows/deploy.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
publish-to-pypi:
3434
if: ${{ github.event.inputs.dry-run == 'false' }}
3535
needs: commit-changelog-and-release
36-
runs-on: ubuntu-latest
36+
runs-on: ubuntu-24.04
3737
steps:
3838
- uses: actions/checkout@v4
3939
with:

.github/workflows/gen-init-py.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ on:
1111
jobs:
1212
generate-init-py:
1313
name: Generate __init__.py files
14-
runs-on: ubuntu-latest
14+
runs-on: ubuntu-24.04
1515
steps:
1616
- uses: actions/checkout@v4
1717
- uses: deargen/workflows/actions/gen-init-py@master

.github/workflows/tests.yml

+28-30
Original file line numberDiff line numberDiff line change
@@ -13,65 +13,63 @@ concurrency:
1313

1414
jobs:
1515
pytest:
16-
runs-on: ubuntu-latest
16+
runs-on: ubuntu-24.04
1717
defaults:
1818
run:
19-
shell: bash -el {0} # setup-miniconda requires bash
19+
shell: bash -leo pipefail {0} # required by setup-micromamba
2020
steps:
2121
- uses: actions/checkout@v4
22-
- name: Setup conda
23-
uses: deargen/workflows/actions/setup-conda-and-uv@master
24-
- name: Cache Conda environment
25-
id: cache-conda
22+
- name: Setup micromamba and uv
23+
uses: deargen/workflows/actions/setup-micromamba-and-uv@master
24+
- name: Cache Micromamba environment
25+
id: cache-micromamba
2626
uses: actions/cache@v4
2727
env:
28-
cache-name: cache-conda
28+
cache-name: cache-micromamba
2929
with:
30-
path: ~/miniconda3/envs/test
31-
key: ${{ runner.os }}-conda-${{ env.cache-name }}-${{ hashFiles('deps/lock/x86_64-manylinux_2_28/requirements_dev.txt') }}
30+
path: ~/micromamba/envs/test
31+
key: ${{ runner.os }}-micromamba-${{ env.cache-name }}-${{ hashFiles('deps/lock/x86_64-manylinux_2_28/requirements_dev.txt', '.github/workflows/tests.yml', 'pyproject.toml') }}
3232
# restore-keys: |
33-
# ${{ runner.os }}-conda-${{ env.cache-name }}-
34-
# ${{ runner.os }}-conda-
33+
# ${{ runner.os }}-micromamba-${{ env.cache-name }}-
34+
# ${{ runner.os }}-micromamba-
3535
# ${{ runner.os }}-
36-
- if: steps.cache-conda.outputs.cache-hit == 'true'
37-
run: echo 'conda cache hit!'
36+
- if: steps.cache-micromamba.outputs.cache-hit == 'true'
37+
run: echo 'micromamba cache hit!'
3838
- name: Install dependencies
39-
if: steps.cache-conda.outputs.cache-hit != 'true'
39+
if: steps.cache-micromamba.outputs.cache-hit != 'true'
4040
run: |
41-
# python -m pip install --upgrade pip
4241
uv pip install -r deps/lock/x86_64-manylinux_2_28/requirements_dev.txt
4342
uv pip install -e .
4443
bash scripts/install_binaries.sh
4544
- name: Run pytest
4645
uses: deargen/workflows/actions/run-pytest@master
4746

4847
doctest:
49-
runs-on: ubuntu-latest
48+
runs-on: ubuntu-24.04
5049
defaults:
5150
run:
52-
shell: bash -el {0} # setup-miniconda requires bash
51+
shell: bash -leo pipefail {0} # required by setup-micromamba
5352
steps:
5453
- uses: actions/checkout@v4
55-
- name: Setup conda
56-
uses: deargen/workflows/actions/setup-conda-and-uv@master
57-
- name: Cache Conda environment
58-
id: cache-conda
54+
- name: Setup micromamba and uv
55+
uses: deargen/workflows/actions/setup-micromamba-and-uv@master
56+
- name: Cache Micromamba environment
57+
id: cache-micromamba
5958
uses: actions/cache@v4
6059
env:
61-
cache-name: cache-conda
60+
cache-name: cache-micromamba
6261
with:
63-
path: ~/miniconda3/envs/test
64-
key: ${{ runner.os }}-conda-${{ env.cache-name }}-${{ hashFiles('deps/lock/x86_64-manylinux_2_28/requirements_dev.txt') }}
62+
path: ~/micromamba/envs/test
63+
key: ${{ runner.os }}-micromamba-${{ env.cache-name }}-${{ hashFiles('deps/lock/x86_64-manylinux_2_28/requirements_dev.txt', '.github/workflows/tests.yml', 'pyproject.toml') }}
6564
# restore-keys: |
66-
# ${{ runner.os }}-conda-${{ env.cache-name }}-
67-
# ${{ runner.os }}-conda-
65+
# ${{ runner.os }}-micromamba-${{ env.cache-name }}-
66+
# ${{ runner.os }}-micromamba-
6867
# ${{ runner.os }}-
69-
- if: steps.cache-conda.outputs.cache-hit == 'true'
70-
run: echo 'conda cache hit!'
68+
- if: steps.cache-micromamba.outputs.cache-hit == 'true'
69+
run: echo 'micromamba cache hit!'
7170
- name: Install dependencies
72-
if: steps.cache-conda.outputs.cache-hit != 'true'
71+
if: steps.cache-micromamba.outputs.cache-hit != 'true'
7372
run: |
74-
# python -m pip install --upgrade pip
7573
uv pip install -r deps/lock/x86_64-manylinux_2_28/requirements_dev.txt
7674
uv pip install -e .
7775
bash scripts/install_binaries.sh

pyproject.toml

+24
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ src = ["src"] # for ruff isort
5252
extend-exclude = [
5353
"src/slack_helpers/_version.py", # CHANGE
5454
]
55+
namespace-packages = ["tools", "scripts"] # for INP rule, suppress on these directories
5556

5657
[tool.ruff.lint]
5758
# OPTIONALLY ADD MORE LATER
@@ -73,6 +74,7 @@ select = [
7374
"RET503", # return
7475
"PTH", # path
7576
"NPY", # numpy
77+
"PD", # pandas
7678
"PYI", # type stubs for pyright/pylance
7779
"PT", # pytest
7880
"PIE", #
@@ -82,6 +84,21 @@ select = [
8284
"DTZ", # datetime
8385
"YTT",
8486
"ASYNC",
87+
"FBT", # boolean trap
88+
"A", # Shadowing python builtins
89+
"EXE", # executable (shebang)
90+
"FA", # future annotations
91+
"ISC", # Implicit string concatenation
92+
"ICN", # Import convention
93+
"INP", # Implicit namespace package (no __init__.py)
94+
"Q", # Quotes
95+
"RSE", # raise
96+
"SLOT", # __slots__
97+
"PL", # Pylint
98+
"TRY", # try
99+
"FAST", # FastAPI
100+
"AIR", # airflow
101+
"DOC", # docstring
85102

86103
# Not important
87104
"T10", # debug statements
@@ -97,12 +114,14 @@ ignore = [
97114
"D212", # Multi-line docstring summary should start at the first line
98115
"D417", # require documentation for every function parameter.
99116
"D401", # require an imperative mood for all docstrings.
117+
"DOC201", # missing Return field in docstring
100118
"PTH123", # Path.open should be used instead of built-in open
101119
"PT006", # Pytest parameterize style
102120
"N812", # Lowercase `functional` imported as non-lowercase `F` (import torch.nn.functional as F)
103121
"NPY002", # legacy numpy random
104122
"UP017", # datetime.timezone.utc -> datetime.UTC
105123
"SIM108", # use ternary operator instead of if-else
124+
"TRY003", # long message in except
106125
]
107126

108127
[tool.ruff.lint.pydocstyle]
@@ -128,6 +147,11 @@ known-third-party = ["wandb"]
128147
# NOTE: Ruff code TID is currently disabled, so this settings doesn't do anything.
129148
banned-module-level-imports = ["torch", "tensorflow"]
130149

150+
[tool.ruff.lint.pylint]
151+
max-args = 10
152+
max-bool-expr = 10
153+
max-statements = 100
154+
131155
[tool.pyright]
132156
include = ["src"]
133157

src/slack_helpers/cli/main.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,18 @@
66
)
77

88

9-
def version_callback(value: bool):
9+
def version_callback(*, value: bool):
1010
if value:
1111
from .. import __version__
1212

1313
print(__version__)
14-
raise typer.Exit()
14+
raise typer.Exit
1515

1616

1717
@app.callback()
1818
def common(
1919
ctx: typer.Context,
20+
*,
2021
version: bool = typer.Option(
2122
None, "-v", "--version", callback=version_callback, help="Show version"
2223
),

src/slack_helpers/health/font.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55

66

77
class FontNotInstalledError(Exception):
8-
pass
8+
def __init__(self, font_name: str):
9+
self.message = f"Font {font_name} is not installed."
10+
super().__init__(self.message)
911

1012

1113
def verify_fonts_installed():
@@ -30,11 +32,12 @@ def verify_fonts_installed():
3032
def verify_fonts_bool():
3133
try:
3234
verify_fonts_installed()
33-
logger.info("✅ FiraCode font is installed.")
34-
return True
3535
except FontNotInstalledError:
36-
logger.error("😡 FiraCode font is not installed.")
36+
logger.exception("😡")
3737
return False
38+
else:
39+
logger.info("✅ FiraCode font is installed.")
40+
return True
3841

3942

4043
if __name__ == "__main__":

src/slack_helpers/health/slack.py

+12-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
logger = logging.getLogger(__name__)
77

88

9-
def check_one_env(env_var, secret=False, secret_show_first_n=0):
9+
def check_one_env(env_var, *, secret=False, secret_show_first_n=0):
1010
value = os.environ.get(env_var)
1111
if value is None:
1212
logger.error(f"😡 Please set the environment variable {env_var}.")
@@ -24,16 +24,24 @@ def check_one_env(env_var, secret=False, secret_show_first_n=0):
2424
return True
2525

2626

27-
def check_many_env(env_vars, secret=False, secret_show_first_n=0):
27+
def check_many_env(env_vars, *, secret=False, secret_show_first_n=0):
2828
ret = True
2929
for env_var in env_vars:
30-
if not check_one_env(env_var, secret, secret_show_first_n):
30+
if not check_one_env(
31+
env_var,
32+
secret=secret,
33+
secret_show_first_n=secret_show_first_n,
34+
):
3135
ret = False
3236
return ret
3337

3438

3539
def check_env():
36-
secrets_checked = check_many_env(["SLACK_BOT_TOKEN", "SLACK_APP_TOKEN"], True, 5)
40+
secrets_checked = check_many_env(
41+
["SLACK_BOT_TOKEN", "SLACK_APP_TOKEN"],
42+
secret=True,
43+
secret_show_first_n=5,
44+
)
3745
normal_checked = check_many_env(["SLACK_CHANNEL_ID"])
3846

3947
return secrets_checked and normal_checked

src/slack_helpers/send_only.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515

1616
def warn_once():
17-
global warned
17+
global warned # noqa: PLW0603
1818
if not warned:
1919
logger.warning(
2020
"You tried to send messages on Slack, but the token is not set. All messages will be ignored."
@@ -57,7 +57,7 @@ def send_text_as_file(
5757
Send a text as a file to the default client and channel (if not specified).
5858
5959
Slack is stupid and having special characters in the file makes it think it's a binary file.
60-
If ensure_preview is True, then we append `""" "dear-viewer" """` at the beginning of the file so Slack thinks
60+
If ensure_preview is True, then we append `\"\"\"\"dear-viewer\"\"\"\"` at the beginning of the file so Slack thinks
6161
it's a python file and will preview it.
6262
6363
Note:
@@ -71,12 +71,12 @@ def send_text_as_file(
7171
filename:
7272
content:
7373
title:
74-
ensure_preview: If True, append `""" "dear-viewer" """` at the beginning of the file to ensure that
74+
ensure_preview: If True, append `\"\"\"\"dear-viewer\"\"\"\"` at the beginning of the file to ensure that
7575
Slack will preview it.
7676
initial_comment:
7777
channel_id:
7878
client:
79-
"""
79+
""" # noqa: D301
8080
if client is None:
8181
client = default_client
8282
if client is None:
@@ -255,7 +255,7 @@ def send_svg_as_pdf(
255255
elif isinstance(svg_file, IOBase):
256256
cairosvg.svg2pdf(file_obj=svg_file, write_to=pdf_buf)
257257
else:
258-
raise ValueError(f"Unsupported type {type(svg_file)}")
258+
raise TypeError(f"Unsupported type {type(svg_file)}")
259259

260260
pdf_buf.seek(0)
261261

src/slack_helpers/utils/log.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ def setup_logging(
122122

123123
def main():
124124
logger.info("Hello, world!")
125-
raise Exception("Test exception")
125+
raise Exception("Test exception") # noqa: TRY002
126126

127127

128128
if __name__ == "__main__":

tools/examples/send_traceback.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
def main():
2727
try:
2828
setup_logging()
29-
raise Exception("This is an exception")
29+
raise Exception("This is an exception") # noqa: TRY301 TRY002
3030
except Exception:
3131
logger.exception("Exception occurred")
3232
slack_text = f"Exception occurred from host {socket.gethostname()}\n\n```{traceback.format_exc()}```"

0 commit comments

Comments
 (0)