diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index da758e84..4b17f66e 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -49,9 +49,9 @@ jobs: sudo apt-get install -y libsqlcipher-dev || (sudo apt-get update && sudo apt-get install -y libsqlcipher-dev) python -m pip install --upgrade pip python -m pip install -e .[dev,encrypt] - - name: Run pyright + - name: Run basedpyright run: | - pyright + basedpyright formatting: runs-on: ubuntu-latest strategy: diff --git a/.nvim.lua b/.nvim.lua new file mode 100644 index 00000000..ae712e9a --- /dev/null +++ b/.nvim.lua @@ -0,0 +1 @@ +vim.lsp.enable("basedpyright") diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index eed612eb..251398eb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,13 +1,13 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.14.13 + rev: v0.15.1 hooks: - id: ruff-check args: [--fix, --exit-non-zero-on-fix] - - repo: https://github.com/RobertCraigie/pyright-python - rev: v1.1.408 + - repo: https://github.com/DetachHead/basedpyright-prek-mirror + rev: 1.38.0 hooks: - - id: pyright + - id: basedpyright - repo: https://github.com/pycqa/isort rev: 6.0.1 hooks: diff --git a/README.md b/README.md index 9773bfe9..01e80f34 100644 --- a/README.md +++ b/README.md @@ -57,11 +57,11 @@ Install module with encryption > python -m pip install .[encrypt] ``` -For development, install as a link to repository such that code changes are used. It is recommended to install pre-commit hooks +For development, install as a link to repository such that code changes are used. It is recommended to install prek hooks ```bash > python -m pip install -e .[dev] -> pre-commit install +> prek install ``` --- @@ -133,7 +133,7 @@ Code development of this project adheres to [Google Python Guide](https://google Linters - `ruff` for Python -- `pyright` for Python type analysis +- `basedpyright` for Python type analysis - `djlint` for Jinja HTML templates - `codespell` for all files diff --git a/nummus/models/asset.py b/nummus/models/asset.py index 8ba6ea6e..f6d9e3ff 100644 --- a/nummus/models/asset.py +++ b/nummus/models/asset.py @@ -566,9 +566,7 @@ def update_valuations( # yfinance raises Exception if no data found raise exc.AssetWebError(e) from e - valuations: dict[int, float] = utils.pd_series_to_dict( - raw["Close"], # type: ignore[attr-defined] - ) + valuations: dict[int, float] = utils.pd_series_to_dict(raw["Close"]) query = AssetValuation.query().where(AssetValuation.asset_id == self.id_) update_rows( @@ -583,7 +581,7 @@ def update_valuations( ) splits: dict[int, float] = utils.pd_series_to_dict( - raw.loc[raw["Stock Splits"] != 0]["Stock Splits"], # type: ignore[attr-defined] + raw.loc[raw["Stock Splits"] != 0]["Stock Splits"], ) query = AssetSplit.query().where(AssetSplit.asset_id == self.id_) diff --git a/nummus/models/base_uri.py b/nummus/models/base_uri.py index 07453d4f..139972ce 100644 --- a/nummus/models/base_uri.py +++ b/nummus/models/base_uri.py @@ -72,7 +72,7 @@ def _reverse_box(box: list[int]) -> list[int]: if max(box) != (n - 1): msg = f"Box's maximum should be n - 1: {box}" raise ValueError(msg) - if sum(box) != (n * (n - 1) / 2): + if sum(box) != (n * (n - 1) // 2): msg = f"Box's sum should be n * (n - 1) / 2: {box}" raise ValueError(msg) box_rev = [0] * n diff --git a/nummus/models/utils.py b/nummus/models/utils.py index 88704c9b..66f4e926 100644 --- a/nummus/models/utils.py +++ b/nummus/models/utils.py @@ -95,22 +95,21 @@ def get_constraints( """ config = "\n".join(dump_table_configs(model)) - constraints: list[tuple[type[Constraint], str]] = [] re_unique = re.compile(r"UNIQUE \(([^\)]+)\)") - for cols in re_unique.findall(config): - cols: str - constraints.append((UniqueConstraint, cols)) + constraints: list[tuple[type[Constraint], str]] = [ + (UniqueConstraint, cols) for cols in re_unique.findall(config) + ] re_check = re.compile(r'CONSTRAINT "[^"]+" CHECK \(([^\)]+)\)') - for sql_text in re_check.findall(config): - sql_text: str - constraints.append((CheckConstraint, sql_text)) + constraints.extend( + (CheckConstraint, sql_text) for sql_text in re_check.findall(config) + ) re_foreign = re.compile(r"FOREIGN KEY\((\w+)\) REFERENCES \w+ \(\w+\)") - for cols in re_foreign.findall(config): - sql_text: str - constraints.append((ForeignKeyConstraint, cols)) + constraints.extend( + (ForeignKeyConstraint, cols) for cols in re_foreign.findall(config) + ) return constraints diff --git a/pyproject.toml b/pyproject.toml index c76360d4..23807a40 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -70,13 +70,13 @@ test = [ ] dev = [ "nummus-financial[deploy,test]", - "ruff>=0.14.13", + "ruff>=0.15.1", "codespell>=2.4.1", "black>=25.9", "isort", - "pre-commit", + "prek", "djlint>=1.36.4", - "pyright>=1.1.408", + "basedpyright>=1.38.0", "taplo", "scipy-stubs", "pandas-stubs", @@ -148,11 +148,10 @@ skip_gitignore = true float_to_top = true force_alphabetical_sort_within_sections = true -[tool.pyright] +[tool.basedpyright] include = ["nummus", "tests", "tools"] exclude = ["**/__pycache__", "typing"] venvPath = "." -venv = ".venv" typeCheckingMode = "strict" reportUnknownParameterType = "warning" diff --git a/tests/controllers/budgeting/test_contexts.py b/tests/controllers/budgeting/test_contexts.py index bd7fbfe8..4a2a70c4 100644 --- a/tests/controllers/budgeting/test_contexts.py +++ b/tests/controllers/budgeting/test_contexts.py @@ -468,7 +468,7 @@ def test_ctx_budget( assert group["position"] == -1 assert group["uri"] is None unhidden = [cat for cat in group["categories"] if not cat["hidden"]] - target: list[budgeting.CategoryContext] = [ + target = [ { "name": "emergency fund", "emoji_name": "Emergency Fund", diff --git a/tests/mock_yfinance.py b/tests/mock_yfinance.py index 046ec150..28f10069 100644 --- a/tests/mock_yfinance.py +++ b/tests/mock_yfinance.py @@ -84,6 +84,6 @@ def history( dt += datetime.timedelta(days=1) return pd.DataFrame( - index=pd.to_datetime(dates), # type: ignore[attr-defined] + index=pd.to_datetime(dates), data={"Close": close, "Stock Splits": split}, ) diff --git a/tools/linters.sh b/tools/linters.sh index 9f82496c..9935f983 100755 --- a/tools/linters.sh +++ b/tools/linters.sh @@ -3,4 +3,4 @@ ruff check . djlint . codespell . -S node_modules -pyright # No dot cause it gets included files from pyproject.toml +basedpyright # No dot cause it gets included files from pyproject.toml