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..cbb3672bd986 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.272 # 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/build.py b/mypy/build.py index 2f556120d430..f388f0909854 100644 --- a/mypy/build.py +++ b/mypy/build.py @@ -3076,7 +3076,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", ) @@ -3164,7 +3164,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/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/mypy/typeanal.py b/mypy/typeanal.py index 39a44a289365..d577f355dbc8 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 e4c22da12603..25bfdd8b03c4 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/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..b46bbd670e60 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,3 +39,40 @@ skip_glob = [ "mypyc/test-data/*", "test-data/*", ] + +[tool.ruff] +line-length = 99 +target-version = "py37" + +select = [ + "E", # pycoderstyle (error) + "F", # pyflakes + "B", # flake8-bugbear + "RUF100", # Unused noqa comments + "PGH004" # blanket noqa comments +] + +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 = [ + "@*", + # 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/*", +] 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..51cd62d4064c 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.272 # must match version in .pre-commit-config.yaml setuptools>=65.5.1 six tomli>=1.1.0