diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 9c0085ed..813d005a 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -26,14 +26,12 @@ jobs: $RUNNER_TOOL_CACHE/Python/* ~\AppData\Local\pip\Cache key: ${{ runner.os }}-build-${{ matrix.python-version }} - - name: install-tox - run: python -m pip install --upgrade tox virtualenv setuptools pip - - name: run-tox - run: tox -e py - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 - if: matrix.python-version == '3.8' && matrix.os == 'ubuntu-18.04' - with: - env_vars: OS,PYTHON - name: codecov-umbrella - fail_ci_if_error: true + - name: install-reqs + run: | + python -m pip install --upgrade tox virtualenv setuptools pip + python -m pip install -U -r requirements-dev.txt + python -m pip install -e . + - name: run-tests + run: pytest tests --cov=100 + - name: run-pyrefly + run: pyrefly check nbqa diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dc8fa082..d6afb1d8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -42,7 +42,7 @@ repos: hooks: - id: mypy exclude: ^docs/ - additional_dependencies: [types-setuptools, types-toml] + additional_dependencies: [types-setuptools, types-toml, tokenize-rt] - repo: https://github.com/asottile/pyupgrade rev: v3.19.1 hooks: diff --git a/nbqa/__main__.py b/nbqa/__main__.py index 087eb1d3..c529ec7a 100644 --- a/nbqa/__main__.py +++ b/nbqa/__main__.py @@ -460,7 +460,10 @@ def _get_configs(cli_args: CLIArgs, project_root: Path) -> Configs: if getattr(cli_args, section) is not None: if section == "addopts": # addopts are added to / overridden rather than replaced outright - config["addopts"] = (*config["addopts"], *getattr(cli_args, section)) + config["addopts"] = ( # type: ignore[missing-attribute,unused-ignore] + *config["addopts"], + *getattr(cli_args, section), + ) else: # TypedDict key must be a string literal config[section] = getattr(cli_args, section) # type: ignore @@ -767,7 +770,7 @@ def _main(cli_args: CLIArgs, configs: Configs) -> int: for key, i in nb_to_tmp_mapping.items() if key not in ( - *saved_sources.failed_notebooks, + *saved_sources.failed_notebooks, # type: ignore[not-a-type, unused-ignore] *saved_sources.non_python_notebooks, ) ], diff --git a/nbqa/path_utils.py b/nbqa/path_utils.py index 3a5b37d8..6b954d77 100644 --- a/nbqa/path_utils.py +++ b/nbqa/path_utils.py @@ -4,7 +4,7 @@ import os import string from pathlib import Path -from typing import Any, Dict, Optional, Tuple +from typing import Any, Dict, Optional, Tuple, cast def remove_prefix(string_: str, prefix: str) -> str: @@ -106,7 +106,10 @@ def read_notebook(notebook: str) -> Tuple[Optional[Dict[str, Any]], Optional[boo config = None try: - md_content = jupytext.jupytext.read(notebook, config=config) + # jupytext isn't typed unfortunately + md_content = cast( # type: ignore[missing-attribute,unused-ignore] + Any, jupytext.jupytext.read(notebook, config=config) + ) except: # noqa: E72a # pylint: disable=bare-except return None, None diff --git a/nbqa/replace_source.py b/nbqa/replace_source.py index 94588f63..48da39a0 100644 --- a/nbqa/replace_source.py +++ b/nbqa/replace_source.py @@ -58,7 +58,7 @@ def _restore_semicolon( for idx, token in tokenize_rt.reversed_enumerate(tokens): if not token.src.strip(" \n") or token.name == "COMMENT": continue - tokens[idx] = token._replace(src=token.src + ";") + tokens[idx] = token._replace(src=token.src + ";") # type: ignore[missing-attribute,unused-ignore] break source = tokenize_rt.tokens_to_src(tokens) return source @@ -226,7 +226,9 @@ def _write_notebook( for cell in notebook_json["cells"]: cell["source"] = "".join(cell["source"]) - jupytext.jupytext.write(notebook_json, temp_notebook, config=config) + jupytext.jupytext.write( # type: ignore[missing-attribute,unused-ignore] + notebook_json, temp_notebook, config=config + ) def mutate( # pylint: disable=too-many-locals,too-many-arguments diff --git a/nbqa/save_code_source.py b/nbqa/save_code_source.py index 5de39e99..352a091b 100644 --- a/nbqa/save_code_source.py +++ b/nbqa/save_code_source.py @@ -328,7 +328,7 @@ def _has_trailing_semicolon(src: str) -> tuple[str, bool]: if not token.src.strip(" \n") or token.name == "COMMENT": continue if token.name == "OP" and token.src == ";": - tokens[idx] = token._replace(src="") + tokens[idx] = token._replace(src="") # type: ignore[missing-attribute,unused-ignore] trailing_semicolon = True break if not trailing_semicolon: diff --git a/requirements-dev.txt b/requirements-dev.txt index 45632468..4c8569c9 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -12,6 +12,7 @@ pre-commit pre-commit-hooks pydocstyle pylint +pyrefly pytest pytest-cov pytest-randomly diff --git a/tox.ini b/tox.ini index c596dc3c..32c21179 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py{38,39,310,311}, docs, docs-links +envlist = pyrefly, py{38,39,310,311}, docs, docs-links [testenv:docs] deps = -rdocs/requirements-docs.txt @@ -19,3 +19,9 @@ commands = coverage run -m pytest {posargs:tests -vv -W error} coverage xml coverage report --fail-under 100 --show-missing + +[testenv:pyrefly] +deps = + -rrequirements-dev.txt +commands = + pyrefly check nbqa