Skip to content

Commit 9f1e3c0

Browse files
authored
feat(library): setup ruff and pyright (#7)
This configuration should provide some extra guarantees about code correctness and formatting and should be VSCode friendly.
1 parent 1d7a023 commit 9f1e3c0

File tree

5 files changed

+206
-1
lines changed

5 files changed

+206
-1
lines changed

.vscode/extensions.json

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

.vscode/settings.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
// Python configuration
3+
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
4+
5+
// Formatting
6+
"[python]": {
7+
"editor.defaultFormatter": "charliermarsh.ruff",
8+
"editor.formatOnSave": true,
9+
"editor.codeActionsOnSave": {
10+
"source.fixAll": "explicit",
11+
"source.organizeImports": "explicit"
12+
}
13+
},
14+
15+
// Ruff linter
16+
"ruff.enable": true,
17+
"ruff.lint.run": "onType",
18+
"ruff.organizeImports": true,
19+
20+
// Type checking (Pylance)
21+
"python.analysis.typeCheckingMode": "basic",
22+
"python.analysis.autoImportCompletions": true,
23+
24+
// Testing
25+
"python.testing.pytestEnabled": true,
26+
"python.testing.unittestEnabled": false,
27+
"python.testing.pytestArgs": [
28+
"library/tests"
29+
],
30+
31+
// File associations
32+
"files.exclude": {
33+
"**/__pycache__": true,
34+
"**/*.pyc": true,
35+
"**/.pytest_cache": true
36+
},
37+
38+
// Editor settings
39+
"editor.rulers": [100],
40+
"files.trimTrailingWhitespace": true,
41+
"files.insertFinalNewline": true
42+
}

library/README.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,76 @@ uv run pytest tests/iqb_score_test.py::TestIQBInitialization
6161
uv run pytest tests/iqb_score_test.py::TestIQBInitialization::test_init_with_name
6262
```
6363

64+
## Code Quality Tools
65+
66+
The library uses Ruff for linting/formatting and Pyright for type checking.
67+
68+
### Linting with Ruff
69+
70+
Ruff is a fast Python linter that checks code style, potential bugs, and code quality issues:
71+
72+
```bash
73+
# From the library directory
74+
cd library
75+
76+
# Check for linting issues
77+
uv run ruff check .
78+
79+
# Check and auto-fix issues
80+
uv run ruff check --fix .
81+
82+
# Format code (like Black)
83+
uv run ruff format .
84+
85+
# Check specific files
86+
uv run ruff check src/iqb/iqb_score.py
87+
```
88+
89+
Ruff configuration is in `pyproject.toml` under `[tool.ruff]`.
90+
91+
### Type Checking with Pyright
92+
93+
Pyright performs static type analysis to catch type-related bugs:
94+
95+
```bash
96+
# From the library directory
97+
cd library
98+
99+
# Run type checking
100+
uv run pyright
101+
102+
# Run with verbose output to verify it's checking the right files
103+
uv run pyright --verbose
104+
```
105+
106+
**Verifying Pyright is Working:**
107+
108+
Pyright can be silent if misconfigured. To verify it's actually checking your code:
109+
110+
```bash
111+
# This should show which files are being analyzed
112+
uv run pyright --verbose
113+
114+
# Expected output should include:
115+
# - "Loading pyproject.toml file at ..."
116+
# - "Found X source files" (should be ~5 files)
117+
# - Python version and search paths
118+
# - "X errors, Y warnings, Z informations"
119+
```
120+
121+
If you see "Found 0 source files", the configuration is wrong.
122+
123+
To test that Pyright catches errors, temporarily introduce a type error:
124+
125+
```python
126+
# In src/iqb/iqb_score.py, add:
127+
x: int = "this should fail" # Pyright should catch this!
128+
```
129+
130+
If Pyright reports an error, it's working correctly. Remove the test line afterwards.
131+
132+
Pyright configuration is in `pyproject.toml` under `[tool.pyright]`.
133+
64134
## Development
65135

66136
### Adding New Tests

library/pyproject.toml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ packages = ["src/iqb"]
2727
[dependency-groups]
2828
dev = [
2929
"pytest>=8.0.0",
30+
"ruff>=0.8.0",
31+
"pyright>=1.1.380",
3032
]
3133

3234
[tool.pytest.ini_options]
@@ -39,3 +41,33 @@ addopts = [
3941
"--strict-markers",
4042
"--tb=short",
4143
]
44+
45+
[tool.ruff]
46+
line-length = 100
47+
target-version = "py313"
48+
49+
[tool.ruff.lint]
50+
select = [
51+
"E", # pycodestyle errors
52+
"W", # pycodestyle warnings
53+
"F", # pyflakes
54+
"I", # isort
55+
"N", # pep8-naming
56+
"UP", # pyupgrade
57+
"B", # flake8-bugbear
58+
"C4", # flake8-comprehensions
59+
"SIM", # flake8-simplify
60+
]
61+
ignore = [
62+
"E501", # line too long (handled by formatter)
63+
]
64+
65+
[tool.ruff.lint.isort]
66+
known-first-party = ["iqb"]
67+
68+
[tool.pyright]
69+
include = ["src", "tests"]
70+
exclude = ["**/__pycache__", ".venv"]
71+
pythonVersion = "3.13"
72+
typeCheckingMode = "basic"
73+
reportMissingTypeStubs = false

uv.lock

Lines changed: 55 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)