Skip to content

Commit d76f591

Browse files
authored
Switch from flake8 to ruff (#414)
1 parent 920d60d commit d76f591

8 files changed

+148
-71
lines changed

.flake8

-16
This file was deleted.

.github/workflows/ci.yml

+3-8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ permissions:
1313
contents: read
1414

1515
env:
16+
FORCE_COLOR: 1
1617
PIP_DISABLE_PIP_VERSION_CHECK: 1
1718

1819
concurrency:
@@ -99,16 +100,10 @@ jobs:
99100
python-version: "3"
100101
cache: "pip"
101102
cache-dependency-path: "test-requirements.txt"
102-
103103
- name: Install dependencies
104-
run: |
105-
pip install -r test-requirements.txt
106-
# not included in test-requirements.txt as it depends on typing-extensions,
107-
# so it's a pain to have it installed locally
108-
pip install flake8-noqa
109-
104+
run: pip install -r test-requirements.txt
110105
- name: Lint implementation
111-
run: flake8 --color always
106+
run: ruff check
112107

113108
create-issue-on-failure:
114109
name: Create an issue if daily tests failed

doc/conf.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55

66
import os.path
77
import sys
8-
from sphinx.writers.html5 import HTML5Translator
8+
99
from docutils.nodes import Element
10+
from sphinx.writers.html5 import HTML5Translator
1011

1112
sys.path.insert(0, os.path.abspath('.'))
1213

pyproject.toml

+39
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,42 @@ email = "[email protected]"
6060
[tool.flit.sdist]
6161
include = ["CHANGELOG.md", "README.md", "tox.ini", "*/*test*.py"]
6262
exclude = []
63+
64+
[tool.ruff]
65+
line-length = 90
66+
target-version = "py38"
67+
68+
[tool.ruff.lint]
69+
select = [
70+
"B",
71+
"C4",
72+
"E",
73+
"F",
74+
"I",
75+
"ISC001",
76+
"PGH004",
77+
"RUF",
78+
"SIM201",
79+
"SIM202",
80+
"UP",
81+
"W",
82+
]
83+
84+
# Ignore various "modernization" rules that tell you off for importing/using
85+
# deprecated things from the typing module, etc.
86+
ignore = ["UP006", "UP007", "UP013", "UP014", "UP019", "UP035", "UP038"]
87+
88+
[tool.ruff.lint.per-file-ignores]
89+
"!src/typing_extensions.py" = [
90+
"B018",
91+
"B024",
92+
"C4",
93+
"E302",
94+
"E306",
95+
"E501",
96+
"E701",
97+
]
98+
99+
[tool.ruff.lint.isort]
100+
extra-standard-library = ["tomllib"]
101+
known-first-party = ["typing_extensions", "_typed_dict_test_helper"]

src/_typed_dict_test_helper.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from __future__ import annotations
22

33
from typing import Generic, Optional, T
4-
from typing_extensions import TypedDict, Annotated, Required
4+
5+
from typing_extensions import Annotated, Required, TypedDict
56

67

78
# this class must not be imported into test_typing_extensions.py at top level, otherwise

src/test_typing_extensions.py

+94-36
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,97 @@
1-
import sys
21
import abc
3-
import gc
4-
import io
5-
import contextlib
62
import collections
7-
from collections import defaultdict
83
import collections.abc
4+
import contextlib
95
import copy
10-
from functools import lru_cache
6+
import gc
117
import importlib
128
import inspect
9+
import io
1310
import pickle
1411
import re
1512
import subprocess
13+
import sys
1614
import tempfile
1715
import textwrap
1816
import types
19-
from pathlib import Path
20-
from unittest import TestCase, main, skipUnless, skipIf
21-
from unittest.mock import patch
2217
import typing
2318
import warnings
19+
from collections import defaultdict
20+
from functools import lru_cache
21+
from pathlib import Path
22+
from unittest import TestCase, main, skipIf, skipUnless
23+
from unittest.mock import patch
2424

2525
import typing_extensions
26-
from typing_extensions import NoReturn, Any, ClassVar, Final, IntVar, Literal, Type, NewType, TypedDict, Self
27-
from typing_extensions import TypeAlias, ParamSpec, Concatenate, ParamSpecArgs, ParamSpecKwargs, TypeGuard
28-
from typing_extensions import Awaitable, AsyncIterator, AsyncContextManager, Required, NotRequired, ReadOnly
29-
from typing_extensions import Protocol, runtime, runtime_checkable, Annotated, final, is_typeddict
30-
from typing_extensions import TypeVarTuple, Unpack, dataclass_transform, reveal_type, Never, assert_never, LiteralString
31-
from typing_extensions import assert_type, get_type_hints, get_origin, get_args, get_original_bases
32-
from typing_extensions import clear_overloads, get_overloads, overload, Iterator
33-
from typing_extensions import NamedTuple, TypeIs, no_type_check, Dict
34-
from typing_extensions import override, deprecated, Buffer, TypeAliasType, TypeVar, get_protocol_members, is_protocol
35-
from typing_extensions import Doc, NoDefault, List, Union, AnyStr, Iterable, Generic, Optional, Set, Tuple, Callable
3626
from _typed_dict_test_helper import Foo, FooGeneric, VeryAnnotated
27+
from typing_extensions import (
28+
Annotated,
29+
Any,
30+
AnyStr,
31+
AsyncContextManager,
32+
AsyncIterator,
33+
Awaitable,
34+
Buffer,
35+
Callable,
36+
ClassVar,
37+
Concatenate,
38+
Dict,
39+
Doc,
40+
Final,
41+
Generic,
42+
IntVar,
43+
Iterable,
44+
Iterator,
45+
List,
46+
Literal,
47+
LiteralString,
48+
NamedTuple,
49+
Never,
50+
NewType,
51+
NoDefault,
52+
NoReturn,
53+
NotRequired,
54+
Optional,
55+
ParamSpec,
56+
ParamSpecArgs,
57+
ParamSpecKwargs,
58+
Protocol,
59+
ReadOnly,
60+
Required,
61+
Self,
62+
Set,
63+
Tuple,
64+
Type,
65+
TypeAlias,
66+
TypeAliasType,
67+
TypedDict,
68+
TypeGuard,
69+
TypeIs,
70+
TypeVar,
71+
TypeVarTuple,
72+
Union,
73+
Unpack,
74+
assert_never,
75+
assert_type,
76+
clear_overloads,
77+
dataclass_transform,
78+
deprecated,
79+
final,
80+
get_args,
81+
get_origin,
82+
get_original_bases,
83+
get_overloads,
84+
get_protocol_members,
85+
get_type_hints,
86+
is_protocol,
87+
is_typeddict,
88+
no_type_check,
89+
overload,
90+
override,
91+
reveal_type,
92+
runtime,
93+
runtime_checkable,
94+
)
3795

3896
NoneType = type(None)
3997
T = TypeVar("T")
@@ -179,14 +237,14 @@ def g_bad_ann():
179237
class BaseTestCase(TestCase):
180238
def assertIsSubclass(self, cls, class_or_tuple, msg=None):
181239
if not issubclass(cls, class_or_tuple):
182-
message = f'{cls!r} is not a subclass of {repr(class_or_tuple)}'
240+
message = f'{cls!r} is not a subclass of {class_or_tuple!r}'
183241
if msg is not None:
184242
message += f' : {msg}'
185243
raise self.failureException(message)
186244

187245
def assertNotIsSubclass(self, cls, class_or_tuple, msg=None):
188246
if issubclass(cls, class_or_tuple):
189-
message = f'{cls!r} is a subclass of {repr(class_or_tuple)}'
247+
message = f'{cls!r} is a subclass of {class_or_tuple!r}'
190248
if msg is not None:
191249
message += f' : {msg}'
192250
raise self.failureException(message)
@@ -765,11 +823,11 @@ def test_repr(self):
765823
mod_name = 'typing'
766824
else:
767825
mod_name = 'typing_extensions'
768-
self.assertEqual(repr(Required), mod_name + '.Required')
826+
self.assertEqual(repr(Required), f'{mod_name}.Required')
769827
cv = Required[int]
770-
self.assertEqual(repr(cv), mod_name + '.Required[int]')
828+
self.assertEqual(repr(cv), f'{mod_name}.Required[int]')
771829
cv = Required[Employee]
772-
self.assertEqual(repr(cv), mod_name + '.Required[%s.Employee]' % __name__)
830+
self.assertEqual(repr(cv), f'{mod_name}.Required[{__name__}.Employee]')
773831

774832
def test_cannot_subclass(self):
775833
with self.assertRaises(TypeError):
@@ -810,11 +868,11 @@ def test_repr(self):
810868
mod_name = 'typing'
811869
else:
812870
mod_name = 'typing_extensions'
813-
self.assertEqual(repr(NotRequired), mod_name + '.NotRequired')
871+
self.assertEqual(repr(NotRequired), f'{mod_name}.NotRequired')
814872
cv = NotRequired[int]
815-
self.assertEqual(repr(cv), mod_name + '.NotRequired[int]')
873+
self.assertEqual(repr(cv), f'{mod_name}.NotRequired[int]')
816874
cv = NotRequired[Employee]
817-
self.assertEqual(repr(cv), mod_name + '.NotRequired[%s.Employee]' % __name__)
875+
self.assertEqual(repr(cv), f'{mod_name}.NotRequired[{ __name__}.Employee]')
818876

819877
def test_cannot_subclass(self):
820878
with self.assertRaises(TypeError):
@@ -872,7 +930,7 @@ def test_illegal_parameters_do_not_raise_runtime_errors(self):
872930
Literal[int]
873931
Literal[Literal[1, 2], Literal[4, 5]]
874932
Literal[3j + 2, ..., ()]
875-
Literal[b"foo", u"bar"]
933+
Literal[b"foo", "bar"]
876934
Literal[{"foo": 3, "bar": 4}]
877935
Literal[T]
878936

@@ -1747,7 +1805,7 @@ class D: ...
17471805
self.assertIsSubclass(D, A)
17481806
self.assertIsSubclass(D, B)
17491807

1750-
class M(): ...
1808+
class M: ...
17511809
collections.abc.Generator.register(M)
17521810
self.assertIsSubclass(M, typing_extensions.Generator)
17531811

@@ -2988,7 +3046,7 @@ class NonP(P):
29883046
class NonPR(PR): pass
29893047
class C(metaclass=abc.ABCMeta):
29903048
x = 1
2991-
class D(metaclass=abc.ABCMeta): # noqa: B024
3049+
class D(metaclass=abc.ABCMeta):
29923050
def meth(self): pass # noqa: B027
29933051
self.assertNotIsInstance(C(), NonP)
29943052
self.assertNotIsInstance(D(), NonPR)
@@ -3274,7 +3332,7 @@ def test_none_treated_correctly(self):
32743332
@runtime_checkable
32753333
class P(Protocol):
32763334
x: int = None
3277-
class B(object): pass
3335+
class B: pass
32783336
self.assertNotIsInstance(B(), P)
32793337
class C:
32803338
x = 1
@@ -5243,7 +5301,7 @@ def test_repr(self):
52435301
mod_name = 'typing'
52445302
else:
52455303
mod_name = 'typing_extensions'
5246-
self.assertEqual(repr(LiteralString), '{}.LiteralString'.format(mod_name))
5304+
self.assertEqual(repr(LiteralString), f'{mod_name}.LiteralString')
52475305

52485306
def test_cannot_subscript(self):
52495307
with self.assertRaises(TypeError):
@@ -5297,7 +5355,7 @@ def test_repr(self):
52975355
mod_name = 'typing'
52985356
else:
52995357
mod_name = 'typing_extensions'
5300-
self.assertEqual(repr(Self), '{}.Self'.format(mod_name))
5358+
self.assertEqual(repr(Self), f'{mod_name}.Self')
53015359

53025360
def test_cannot_subscript(self):
53035361
with self.assertRaises(TypeError):
@@ -5556,7 +5614,7 @@ def stmethod(): ...
55565614
def prop(self): ...
55575615

55585616
@final
5559-
@lru_cache() # noqa: B019
5617+
@lru_cache # noqa: B019
55605618
def cached(self): ...
55615619

55625620
# Use getattr_static because the descriptor returns the
@@ -6312,8 +6370,8 @@ def test_or(self):
63126370
X = TypeVar('X')
63136371
# use a string because str doesn't implement
63146372
# __or__/__ror__ itself
6315-
self.assertEqual(X | "x", Union[X, "x"]) # noqa: F821
6316-
self.assertEqual("x" | X, Union["x", X]) # noqa: F821
6373+
self.assertEqual(X | "x", Union[X, "x"])
6374+
self.assertEqual("x" | X, Union["x", X])
63176375
# make sure the order is correct
63186376
self.assertEqual(get_args(X | "x"), (X, typing.ForwardRef("x")))
63196377
self.assertEqual(get_args("x" | X), (typing.ForwardRef("x"), X))

0 commit comments

Comments
 (0)