From 0ee7349e6b755e5d7b74dd441de9ccebf2c086f8 Mon Sep 17 00:00:00 2001 From: dosisod <39638017+dosisod@users.noreply.github.com> Date: Sat, 3 Jun 2023 16:51:53 -0700 Subject: [PATCH 1/6] Switch from `flake8` to `ruff`: To quote Ruff's README: "An extremely fast Python linter, written in Rust". In my testing Ruff takes 200ms to lint the entire codebase whereas flake8 takes about 5.5 seconds (27x slower). Running `pre-commit run -a` only takes about 2.3 seconds now, which should make local dev work a bit faster (assuming you run linters regularly). Ruff includes a lot of rules out of the box, including all the (important) rules from `flake8`, `flake8-bugbear`, `flake8-noqa`, and many more. Having all these built-in rules makes it much easier to incrementally improve the codebase without having to install tons of flake8 plugins. I made sure that the configs matched as close as I could get them. Some minor rules like line indentation and such aren't in Ruff since they are always just disabled. Ruff also ignores everything in the `.gitignore` file, so that cleans up the exclude section. Lastly, the `test-data` section seemed to have its own `.flake8` config file, but it was disabled in the `setup.cfg` file. I migrated the config over, but it doesn't really matter because it is being ignored anyways. Is this intentional? --- .github/workflows/test.yml | 2 +- .gitignore | 1 - .pre-commit-config.yaml | 13 +++-------- CONTRIBUTING.md | 2 +- mypy/server/objgraph.py | 4 ++-- mypyc/irbuild/specialize.py | 2 +- pyproject.toml | 38 ++++++++++++++++++++++++++++++++ setup.cfg | 43 ------------------------------------- test-data/.flake8 | 22 ------------------- test-data/unit/README.md | 2 +- test-requirements.txt | 4 +--- 11 files changed, 48 insertions(+), 85 deletions(-) delete mode 100644 test-data/.flake8 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 81587f3ca747..6fc8fb11c6f4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -96,7 +96,7 @@ jobs: # We also run these checks with pre-commit in CI, # but it's useful to run them with tox too, # to ensure the tox env works as expected - - name: Formatting with Black + isort and code style with flake8 + - name: Formatting with Black + isort and code style with ruff python: '3.10' arch: x64 os: ubuntu-latest diff --git a/.gitignore b/.gitignore index c6761f0ed736..6c35e3d89342 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,5 @@ test_capi *.o *.a test_capi -/.mypyc-flake8-cache.json /mypyc/lib-rt/build/ /mypyc/lib-rt/*.so diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 92d827fba006..4e4ab681cc98 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,14 +13,7 @@ repos: rev: 5.12.0 # must match test-requirements.txt hooks: - id: isort - - repo: https://github.com/pycqa/flake8 - rev: 6.0.0 # must match test-requirements.txt + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.0.270 # must match test-requirements.txt hooks: - - id: flake8 - additional_dependencies: - - flake8-bugbear==23.3.23 # must match test-requirements.txt - - flake8-noqa==1.3.1 # must match test-requirements.txt - -ci: - # We run flake8 as part of our GitHub Actions suite in CI - skip: [flake8] + - id: ruff diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d169d7f3159e..99ba2f8c9a76 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -89,7 +89,7 @@ pytest -n0 -k 'test_name' pytest mypy/test/testcheck.py::TypeCheckSuite::check-dataclasses.test # Run the linter -flake8 +ruff . # Run formatters black . && isort . diff --git a/mypy/server/objgraph.py b/mypy/server/objgraph.py index 89a086b8a0ab..37d0f4d2ca1a 100644 --- a/mypy/server/objgraph.py +++ b/mypy/server/objgraph.py @@ -46,7 +46,7 @@ def get_edge_candidates(o: object) -> Iterator[tuple[object, object]]: try: if attr not in ATTR_BLACKLIST and hasattr(o, attr) and not isproperty(o, attr): e = getattr(o, attr) - if not type(e) in ATOMIC_TYPE_BLACKLIST: + if type(e) not in ATOMIC_TYPE_BLACKLIST: yield attr, e except AssertionError: pass @@ -70,7 +70,7 @@ def get_edges(o: object) -> Iterator[tuple[object, object]]: if se is not o and se is not type(o) and hasattr(s, "__self__"): yield s.__self__, se else: - if not type(e) in TYPE_BLACKLIST: + if type(e) not in TYPE_BLACKLIST: yield s, e diff --git a/mypyc/irbuild/specialize.py b/mypyc/irbuild/specialize.py index ff9df0cd597b..14a6f8e92df2 100644 --- a/mypyc/irbuild/specialize.py +++ b/mypyc/irbuild/specialize.py @@ -446,7 +446,7 @@ def translate_sum_call(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> V # handle 'start' argument, if given if len(expr.args) == 2: # ensure call to sum() was properly constructed - if not expr.arg_kinds[1] in (ARG_POS, ARG_NAMED): + if expr.arg_kinds[1] not in (ARG_POS, ARG_NAMED): return None start_expr = expr.args[1] else: diff --git a/pyproject.toml b/pyproject.toml index 3d100dff5101..f2b9c9621d13 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,3 +39,41 @@ skip_glob = [ "mypyc/test-data/*", "test-data/*", ] + +[tool.ruff] +line-length = 99 + +# Things to ignore: +# B006: use of mutable defaults in function signatures +# B007: Loop control variable not used within the loop body. +# B011: Don't use assert False +# B023: Function definition does not bind loop variable +# E203: conflicts with black +# E402: module level import not at top of file +# E501: conflicts with black +# E731: Do not assign a `lambda` expression, use a `def` +# E741: Ambiguous variable name +extend-ignore = ["B006", "B007", "B011", "B023", "E203", "E402", "E501", "E731", "E741"] + +extend-exclude = [ + "@*", + # Sphinx configuration is irrelevant + "docs/source/conf.py", + "mypyc/doc/conf.py", + # tests have more relaxed styling requirements + # fixtures have their own .pyi-specific configuration + "test-data/*", + "mypyc/test-data/*", + # typeshed has its own .pyi-specific configuration + "mypy/typeshed/*", +] + +[tool.ruff.per-file-ignores] + +# Some PEP8 deviations are considered irrelevant to stub files: +# (error counts as of 2016-12-19) +# 1487 F401 imported but unused +# 1248 E701 multiple statements on one line (colon) +# 427 F811 redefinition + +"test-data/*" = ["F401", "F811", "E701"] diff --git a/setup.cfg b/setup.cfg index 511f794474e7..04d75ac8d19f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,46 +1,3 @@ -[flake8] -max-line-length = 99 -noqa-require-code = True -# typeshed and unit test fixtures have .pyi-specific flake8 configuration -exclude = - # from .gitignore: directories, and file patterns that intersect with *.py - build, - bin, - lib, - include, - @*, - env, - docs/build, - out, - .venv, - .mypy_cache, - .git, - .cache, - # Sphinx configuration is irrelevant - docs/source/conf.py, - mypyc/doc/conf.py, - # tests have more relaxed styling requirements - # fixtures have their own .pyi-specific configuration - test-data/*, - mypyc/test-data/*, - # typeshed has its own .pyi-specific configuration - mypy/typeshed/*, - .tox - .eggs - .Python - -# Things to ignore: -# E203: conflicts with black -# E501: conflicts with black -# W601: has_key() deprecated (false positives) -# E402: module level import not at top of file -# B006: use of mutable defaults in function signatures -# B007: Loop control variable not used within the loop body. -# B011: Don't use assert False -# B023: Function definition does not bind loop variable -# E741: Ambiguous variable name -extend-ignore = E203,E501,W601,E402,B006,B007,B011,B023,E741 - [coverage:run] branch = true source = mypy diff --git a/test-data/.flake8 b/test-data/.flake8 deleted file mode 100644 index df2f9caf8c94..000000000000 --- a/test-data/.flake8 +++ /dev/null @@ -1,22 +0,0 @@ -# Some PEP8 deviations are considered irrelevant to stub files: -# (error counts as of 2016-12-19) -# 17381 E704 multiple statements on one line (def) -# 11840 E301 expected 1 blank line -# 7467 E302 expected 2 blank lines -# 1772 E501 line too long -# 1487 F401 imported but unused -# 1248 E701 multiple statements on one line (colon) -# 427 F811 redefinition -# 356 E305 expected 2 blank lines - -# Nice-to-haves ignored for now -# 152 E128 continuation line under-indented for visual indent -# 43 E127 continuation line over-indented for visual indent - -[flake8] -ignore = F401, F811, E127, E128, E301, E302, E305, E501, E701, E704, B303 -# We are checking with Python 3 but many of the stubs are Python 2 stubs. -# A nice future improvement would be to provide separate .flake8 -# configurations for Python 2 and Python 3 files. -builtins = StandardError,apply,basestring,buffer,cmp,coerce,execfile,file,intern,long,raw_input,reduce,reload,unichr,unicode,xrange -exclude = .venv*,@* diff --git a/test-data/unit/README.md b/test-data/unit/README.md index 97680c949bef..f2c727b43543 100644 --- a/test-data/unit/README.md +++ b/test-data/unit/README.md @@ -159,7 +159,7 @@ To run mypy on itself: To run the linter: - flake8 + ruff . You can also run all of the above tests using `runtests.py` (this includes type checking mypy and linting): diff --git a/test-requirements.txt b/test-requirements.txt index 42c8a08a2b5d..b13166b22d12 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -3,9 +3,6 @@ attrs>=18.0 black==23.3.0 # must match version in .pre-commit-config.yaml filelock>=3.3.0 -flake8==6.0.0; python_version >= "3.8" # must match version in .pre-commit-config.yaml -flake8-bugbear==23.3.23; python_version >= "3.8" # must match version in .pre-commit-config.yaml -flake8-noqa==1.3.1; python_version >= "3.8" # must match version in .pre-commit-config.yaml isort[colors]==5.12.0; python_version >= "3.8" # must match version in .pre-commit-config.yaml lxml>=4.9.1; (python_version<'3.11' or sys_platform!='win32') and python_version<'3.12' pre-commit @@ -17,6 +14,7 @@ pytest-xdist>=1.34.0 pytest-forked>=1.3.0,<2.0.0 pytest-cov>=2.10.0 py>=1.5.2 +ruff==0.0.270 # must match version in .pre-commit-config.yaml setuptools>=65.5.1 six tomli>=1.1.0 From df7ed7af5d872460c490a576b35ff71195595c3a Mon Sep 17 00:00:00 2001 From: dosisod <39638017+dosisod@users.noreply.github.com> Date: Sat, 3 Jun 2023 17:45:21 -0700 Subject: [PATCH 2/6] Make comments inline [skip ci] --- pyproject.toml | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f2b9c9621d13..d41cd625614d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,17 +43,17 @@ skip_glob = [ [tool.ruff] line-length = 99 -# Things to ignore: -# B006: use of mutable defaults in function signatures -# B007: Loop control variable not used within the loop body. -# B011: Don't use assert False -# B023: Function definition does not bind loop variable -# E203: conflicts with black -# E402: module level import not at top of file -# E501: conflicts with black -# E731: Do not assign a `lambda` expression, use a `def` -# E741: Ambiguous variable name -extend-ignore = ["B006", "B007", "B011", "B023", "E203", "E402", "E501", "E731", "E741"] +extend-ignore = [ + "B006", # use of mutable defaults in function signatures + "B007", # Loop control variable not used within the loop body. + "B011", # Don't use assert False + "B023", # Function definition does not bind loop variable + "E203", # conflicts with black + "E402", # module level import not at top of file + "E501", # conflicts with black + "E731", # Do not assign a `lambda` expression, use a `def` + "E741", # Ambiguous variable name +] extend-exclude = [ "@*", @@ -70,10 +70,8 @@ extend-exclude = [ [tool.ruff.per-file-ignores] -# Some PEP8 deviations are considered irrelevant to stub files: -# (error counts as of 2016-12-19) -# 1487 F401 imported but unused -# 1248 E701 multiple statements on one line (colon) -# 427 F811 redefinition - -"test-data/*" = ["F401", "F811", "E701"] +"test-data/*" = [ + "F401", # imported but unused + "F811", # redefinition + "E701", # multiple statements on one line (colon) +] From 26633c5b9ca14e31768776ed3f5857b490102504 Mon Sep 17 00:00:00 2001 From: dosisod <39638017+dosisod@users.noreply.github.com> Date: Fri, 16 Jun 2023 23:08:36 -0700 Subject: [PATCH 3/6] Add `target-version` flag to Ruff --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index d41cd625614d..8980b2e4e708 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,6 +42,7 @@ skip_glob = [ [tool.ruff] line-length = 99 +target-version = "py37" extend-ignore = [ "B006", # use of mutable defaults in function signatures From 76259836d8149ca08d65ca4a015fc9b0ec38790e Mon Sep 17 00:00:00 2001 From: dosisod <39638017+dosisod@users.noreply.github.com> Date: Sun, 18 Jun 2023 21:46:30 -0700 Subject: [PATCH 4/6] Add review suggestions --- .pre-commit-config.yaml | 2 +- mypy/build.py | 4 ++-- mypy/plugins/common.py | 4 +--- mypy/typeanal.py | 2 +- mypy/types.py | 2 +- pyproject.toml | 9 ++++++++- test-requirements.txt | 2 +- 7 files changed, 15 insertions(+), 10 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4e4ab681cc98..cbb3672bd986 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,6 +14,6 @@ repos: hooks: - id: isort - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.0.270 # must match test-requirements.txt + rev: v0.0.272 # must match test-requirements.txt hooks: - id: ruff diff --git a/mypy/build.py b/mypy/build.py index 7913eae9c6ed..413e94b5fb8e 100644 --- a/mypy/build.py +++ b/mypy/build.py @@ -3077,7 +3077,7 @@ def load_graph( manager.errors.report( -1, -1, - "See https://mypy.readthedocs.io/en/stable/running_mypy.html#mapping-file-paths-to-modules " # noqa: E501 + "See https://mypy.readthedocs.io/en/stable/running_mypy.html#mapping-file-paths-to-modules " "for more info", severity="note", ) @@ -3165,7 +3165,7 @@ def load_graph( manager.errors.report( -1, 0, - "See https://mypy.readthedocs.io/en/stable/running_mypy.html#mapping-file-paths-to-modules " # noqa: E501 + "See https://mypy.readthedocs.io/en/stable/running_mypy.html#mapping-file-paths-to-modules " "for more info", severity="note", ) diff --git a/mypy/plugins/common.py b/mypy/plugins/common.py index f803387cde8b..65d967577bea 100644 --- a/mypy/plugins/common.py +++ b/mypy/plugins/common.py @@ -28,9 +28,7 @@ require_bool_literal_argument, set_callable_name, ) -from mypy.typeops import ( # noqa: F401 # Part of public API - try_getting_str_literals as try_getting_str_literals, -) +from mypy.typeops import try_getting_str_literals as try_getting_str_literals from mypy.types import ( AnyType, CallableType, diff --git a/mypy/typeanal.py b/mypy/typeanal.py index d1e6e315b9e3..f2e17b2beedc 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -1256,7 +1256,7 @@ def analyze_callable_type(self, t: UnboundType) -> Type: code=codes.VALID_TYPE, ) self.note( - "See https://mypy.readthedocs.io/en/stable/kinds_of_types.html#callable-types-and-lambdas", # noqa: E501 + "See https://mypy.readthedocs.io/en/stable/kinds_of_types.html#callable-types-and-lambdas", t, ) return AnyType(TypeOfAny.from_error) diff --git a/mypy/types.py b/mypy/types.py index 5fbdd385826c..d0c7caf457ab 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -2957,7 +2957,7 @@ def get_proper_types( # to make it easier to gradually get modules working with mypyc. # Import them here, after the types are defined. # This is intended as a re-export also. -from mypy.type_visitor import ( # noqa: F811,F401 +from mypy.type_visitor import ( # noqa: F811 ALL_STRATEGY as ALL_STRATEGY, ANY_STRATEGY as ANY_STRATEGY, BoolTypeQuery as BoolTypeQuery, diff --git a/pyproject.toml b/pyproject.toml index 8980b2e4e708..b4b118ca9a24 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,7 +44,14 @@ skip_glob = [ line-length = 99 target-version = "py37" -extend-ignore = [ +select = [ + "E", # pycoderstyle (error) + "F", # pyflakes + "B", # flake8-bugbear + "RUF100", # flake8-noqa +] + +ignore = [ "B006", # use of mutable defaults in function signatures "B007", # Loop control variable not used within the loop body. "B011", # Don't use assert False diff --git a/test-requirements.txt b/test-requirements.txt index b13166b22d12..51cd62d4064c 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -14,7 +14,7 @@ pytest-xdist>=1.34.0 pytest-forked>=1.3.0,<2.0.0 pytest-cov>=2.10.0 py>=1.5.2 -ruff==0.0.270 # must match version in .pre-commit-config.yaml +ruff==0.0.272 # must match version in .pre-commit-config.yaml setuptools>=65.5.1 six tomli>=1.1.0 From 580c503a647b7ba61cec1e9c3db4528c1b299807 Mon Sep 17 00:00:00 2001 From: dosisod <39638017+dosisod@users.noreply.github.com> Date: Sun, 18 Jun 2023 21:55:39 -0700 Subject: [PATCH 5/6] Remove `per-file-ignores` setting --- pyproject.toml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b4b118ca9a24..2baabe007f19 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -75,11 +75,3 @@ extend-exclude = [ # typeshed has its own .pyi-specific configuration "mypy/typeshed/*", ] - -[tool.ruff.per-file-ignores] - -"test-data/*" = [ - "F401", # imported but unused - "F811", # redefinition - "E701", # multiple statements on one line (colon) -] From 925089fdbedac0cf1a64bd850e351315cd3c82ae Mon Sep 17 00:00:00 2001 From: Logan Hunt <39638017+dosisod@users.noreply.github.com> Date: Mon, 19 Jun 2023 21:35:30 -0700 Subject: [PATCH 6/6] Update pyproject.toml Co-authored-by: Alex Waygood --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 2baabe007f19..b46bbd670e60 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,7 +48,8 @@ select = [ "E", # pycoderstyle (error) "F", # pyflakes "B", # flake8-bugbear - "RUF100", # flake8-noqa + "RUF100", # Unused noqa comments + "PGH004" # blanket noqa comments ] ignore = [