flake8 7.2.0__tar.gz → 7.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {flake8-7.2.0/src/flake8.egg-info → flake8-7.4.0}/PKG-INFO +4 -5
- {flake8-7.2.0 → flake8-7.4.0}/setup.cfg +3 -4
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/__init__.py +2 -2
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/_compat.py +7 -0
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/api/legacy.py +2 -2
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/checker.py +21 -56
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/discover_files.py +1 -1
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/formatting/base.py +1 -1
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/main/application.py +1 -1
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/main/debug.py +1 -1
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/main/options.py +1 -1
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/options/config.py +3 -3
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/options/manager.py +2 -2
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/plugins/finder.py +5 -5
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/plugins/pyflakes.py +5 -1
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/processor.py +19 -8
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/statistics.py +2 -2
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/style_guide.py +5 -5
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/utils.py +3 -3
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/violation.py +1 -1
- {flake8-7.2.0 → flake8-7.4.0/src/flake8.egg-info}/PKG-INFO +4 -5
- flake8-7.4.0/src/flake8.egg-info/requires.txt +3 -0
- flake8-7.2.0/src/flake8.egg-info/requires.txt +0 -3
- {flake8-7.2.0 → flake8-7.4.0}/LICENSE +0 -0
- {flake8-7.2.0 → flake8-7.4.0}/README.rst +0 -0
- {flake8-7.2.0 → flake8-7.4.0}/setup.py +0 -0
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/__main__.py +0 -0
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/api/__init__.py +0 -0
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/defaults.py +0 -0
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/exceptions.py +0 -0
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/formatting/__init__.py +0 -0
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/formatting/_windows_color.py +0 -0
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/formatting/default.py +0 -0
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/main/__init__.py +0 -0
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/main/cli.py +0 -0
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/options/__init__.py +0 -0
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/options/aggregator.py +0 -0
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/options/parse_args.py +0 -0
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/plugins/__init__.py +0 -0
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/plugins/pycodestyle.py +0 -0
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8/plugins/reporter.py +0 -0
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8.egg-info/SOURCES.txt +0 -0
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8.egg-info/dependency_links.txt +0 -0
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8.egg-info/entry_points.txt +0 -0
- {flake8-7.2.0 → flake8-7.4.0}/src/flake8.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: flake8
|
|
3
|
-
Version: 7.
|
|
3
|
+
Version: 7.4.0
|
|
4
4
|
Summary: the modular source code checker: pep8 pyflakes and co
|
|
5
5
|
Home-page: https://github.com/pycqa/flake8
|
|
6
6
|
Author: Tarek Ziade
|
|
@@ -12,7 +12,6 @@ Classifier: Development Status :: 5 - Production/Stable
|
|
|
12
12
|
Classifier: Environment :: Console
|
|
13
13
|
Classifier: Framework :: Flake8
|
|
14
14
|
Classifier: Intended Audience :: Developers
|
|
15
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
16
15
|
Classifier: Programming Language :: Python
|
|
17
16
|
Classifier: Programming Language :: Python :: 3
|
|
18
17
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
@@ -20,12 +19,12 @@ Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
|
20
19
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
21
20
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
21
|
Classifier: Topic :: Software Development :: Quality Assurance
|
|
23
|
-
Requires-Python: >=3.
|
|
22
|
+
Requires-Python: >=3.10
|
|
24
23
|
Description-Content-Type: text/x-rst
|
|
25
24
|
License-File: LICENSE
|
|
26
25
|
Requires-Dist: mccabe<0.8.0,>=0.7.0
|
|
27
|
-
Requires-Dist: pycodestyle<2.
|
|
28
|
-
Requires-Dist: pyflakes<
|
|
26
|
+
Requires-Dist: pycodestyle<2.16.0,>=2.15.0
|
|
27
|
+
Requires-Dist: pyflakes<4.1.0,>=4.0.0
|
|
29
28
|
|
|
30
29
|
.. image:: https://github.com/PyCQA/flake8/workflows/main/badge.svg
|
|
31
30
|
:target: https://github.com/PyCQA/flake8/actions?query=workflow%3Amain
|
|
@@ -16,7 +16,6 @@ classifiers =
|
|
|
16
16
|
Environment :: Console
|
|
17
17
|
Framework :: Flake8
|
|
18
18
|
Intended Audience :: Developers
|
|
19
|
-
License :: OSI Approved :: MIT License
|
|
20
19
|
Programming Language :: Python
|
|
21
20
|
Programming Language :: Python :: 3
|
|
22
21
|
Programming Language :: Python :: 3 :: Only
|
|
@@ -29,9 +28,9 @@ classifiers =
|
|
|
29
28
|
packages = find:
|
|
30
29
|
install_requires =
|
|
31
30
|
mccabe>=0.7.0,<0.8.0
|
|
32
|
-
pycodestyle>=2.
|
|
33
|
-
pyflakes>=
|
|
34
|
-
python_requires = >=3.
|
|
31
|
+
pycodestyle>=2.15.0,<2.16.0
|
|
32
|
+
pyflakes>=4.0.0,<4.1.0
|
|
33
|
+
python_requires = >=3.10
|
|
35
34
|
package_dir =
|
|
36
35
|
=src
|
|
37
36
|
|
|
@@ -17,7 +17,7 @@ import sys
|
|
|
17
17
|
LOG = logging.getLogger(__name__)
|
|
18
18
|
LOG.addHandler(logging.NullHandler())
|
|
19
19
|
|
|
20
|
-
__version__ = "7.
|
|
20
|
+
__version__ = "7.4.0"
|
|
21
21
|
__version_info__ = tuple(int(i) for i in __version__.split(".") if i.isdigit())
|
|
22
22
|
|
|
23
23
|
_VERBOSITY_TO_LOG_LEVEL = {
|
|
@@ -66,5 +66,5 @@ def configure_logging(
|
|
|
66
66
|
LOG.addHandler(handler)
|
|
67
67
|
LOG.setLevel(log_level)
|
|
68
68
|
LOG.debug(
|
|
69
|
-
"Added a %s logging handler to logger root at %s", filename, __name__
|
|
69
|
+
"Added a %s logging handler to logger root at %s", filename, __name__,
|
|
70
70
|
)
|
|
@@ -9,3 +9,10 @@ if sys.version_info >= (3, 12): # pragma: >=3.12 cover
|
|
|
9
9
|
FSTRING_END = tokenize.FSTRING_END
|
|
10
10
|
else: # pragma: <3.12 cover
|
|
11
11
|
FSTRING_START = FSTRING_MIDDLE = FSTRING_END = -1
|
|
12
|
+
|
|
13
|
+
if sys.version_info >= (3, 14): # pragma: >=3.14 cover
|
|
14
|
+
TSTRING_START = tokenize.TSTRING_START
|
|
15
|
+
TSTRING_MIDDLE = tokenize.TSTRING_MIDDLE
|
|
16
|
+
TSTRING_END = tokenize.TSTRING_END
|
|
17
|
+
else: # pragma: <3.14 cover
|
|
18
|
+
TSTRING_START = TSTRING_MIDDLE = TSTRING_END = -1
|
|
@@ -135,7 +135,7 @@ class StyleGuide:
|
|
|
135
135
|
stdin_display_name=self.options.stdin_display_name,
|
|
136
136
|
filename_patterns=self.options.filename,
|
|
137
137
|
exclude=self.options.exclude,
|
|
138
|
-
)
|
|
138
|
+
),
|
|
139
139
|
)
|
|
140
140
|
return not paths
|
|
141
141
|
|
|
@@ -153,7 +153,7 @@ class StyleGuide:
|
|
|
153
153
|
if not issubclass(reporter, formatter.BaseFormatter):
|
|
154
154
|
raise ValueError(
|
|
155
155
|
"Report should be subclass of "
|
|
156
|
-
"flake8.formatter.BaseFormatter."
|
|
156
|
+
"flake8.formatter.BaseFormatter.",
|
|
157
157
|
)
|
|
158
158
|
self._application.formatter = reporter(self.options)
|
|
159
159
|
self._application.guide = None
|
|
@@ -19,6 +19,7 @@ from flake8 import exceptions
|
|
|
19
19
|
from flake8 import processor
|
|
20
20
|
from flake8 import utils
|
|
21
21
|
from flake8._compat import FSTRING_START
|
|
22
|
+
from flake8._compat import TSTRING_START
|
|
22
23
|
from flake8.discover_files import expand_paths
|
|
23
24
|
from flake8.options.parse_args import parse_args
|
|
24
25
|
from flake8.plugins.finder import Checkers
|
|
@@ -44,40 +45,39 @@ SERIAL_RETRY_ERRNOS = {
|
|
|
44
45
|
# noise in diffs.
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
_mp_options: argparse.Namespace
|
|
48
|
+
_mp: tuple[Checkers, argparse.Namespace] | None = None
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
@contextlib.contextmanager
|
|
52
52
|
def _mp_prefork(
|
|
53
|
-
plugins: Checkers, options: argparse.Namespace
|
|
53
|
+
plugins: Checkers, options: argparse.Namespace,
|
|
54
54
|
) -> Generator[None]:
|
|
55
55
|
# we can save significant startup work w/ `fork` multiprocessing
|
|
56
|
-
global
|
|
57
|
-
|
|
56
|
+
global _mp
|
|
57
|
+
_mp = plugins, options
|
|
58
58
|
try:
|
|
59
59
|
yield
|
|
60
60
|
finally:
|
|
61
|
-
|
|
61
|
+
_mp = None
|
|
62
62
|
|
|
63
63
|
|
|
64
64
|
def _mp_init(argv: Sequence[str]) -> None:
|
|
65
|
-
global
|
|
65
|
+
global _mp
|
|
66
66
|
|
|
67
67
|
# Ensure correct signaling of ^C using multiprocessing.Pool.
|
|
68
68
|
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
_mp_plugins, _mp_options # noqa: B018
|
|
73
|
-
except NameError:
|
|
70
|
+
# for `fork` this'll already be set
|
|
71
|
+
if _mp is None:
|
|
74
72
|
plugins, options = parse_args(argv)
|
|
75
|
-
|
|
73
|
+
_mp = plugins.checkers, options
|
|
76
74
|
|
|
77
75
|
|
|
78
76
|
def _mp_run(filename: str) -> tuple[str, Results, dict[str, int]]:
|
|
77
|
+
assert _mp is not None, _mp
|
|
78
|
+
plugins, options = _mp
|
|
79
79
|
return FileChecker(
|
|
80
|
-
filename=filename, plugins=
|
|
80
|
+
filename=filename, plugins=plugins, options=options,
|
|
81
81
|
).run_checks()
|
|
82
82
|
|
|
83
83
|
|
|
@@ -137,7 +137,7 @@ class Manager:
|
|
|
137
137
|
if utils.is_using_stdin(self.options.filenames):
|
|
138
138
|
LOG.warning(
|
|
139
139
|
"The --jobs option is not compatible with supplying "
|
|
140
|
-
"input using - . Ignoring --jobs arguments."
|
|
140
|
+
"input using - . Ignoring --jobs arguments.",
|
|
141
141
|
)
|
|
142
142
|
return 0
|
|
143
143
|
|
|
@@ -252,7 +252,7 @@ class Manager:
|
|
|
252
252
|
stdin_display_name=self.options.stdin_display_name,
|
|
253
253
|
filename_patterns=self.options.filename,
|
|
254
254
|
exclude=self.exclude,
|
|
255
|
-
)
|
|
255
|
+
),
|
|
256
256
|
)
|
|
257
257
|
self.jobs = min(len(self.filenames), self.jobs)
|
|
258
258
|
|
|
@@ -332,11 +332,11 @@ class FileChecker:
|
|
|
332
332
|
assert self.processor is not None, self.filename
|
|
333
333
|
try:
|
|
334
334
|
params = self.processor.keyword_arguments_for(
|
|
335
|
-
plugin.parameters, arguments
|
|
335
|
+
plugin.parameters, arguments,
|
|
336
336
|
)
|
|
337
337
|
except AttributeError as ae:
|
|
338
338
|
raise exceptions.PluginRequestedUnknownParameters(
|
|
339
|
-
plugin_name=plugin.display_name, exception=ae
|
|
339
|
+
plugin_name=plugin.display_name, exception=ae,
|
|
340
340
|
)
|
|
341
341
|
try:
|
|
342
342
|
return plugin.obj(**arguments, **params)
|
|
@@ -372,43 +372,6 @@ class FileChecker:
|
|
|
372
372
|
token = ()
|
|
373
373
|
row, column = (1, 0)
|
|
374
374
|
|
|
375
|
-
if (
|
|
376
|
-
column > 0
|
|
377
|
-
and token
|
|
378
|
-
and isinstance(exception, SyntaxError)
|
|
379
|
-
and len(token) == 4 # Python 3.9 or earlier
|
|
380
|
-
):
|
|
381
|
-
# NOTE(sigmavirus24): SyntaxErrors report 1-indexed column
|
|
382
|
-
# numbers. We need to decrement the column number by 1 at
|
|
383
|
-
# least.
|
|
384
|
-
column_offset = 1
|
|
385
|
-
row_offset = 0
|
|
386
|
-
# See also: https://github.com/pycqa/flake8/issues/169,
|
|
387
|
-
# https://github.com/PyCQA/flake8/issues/1372
|
|
388
|
-
# On Python 3.9 and earlier, token will be a 4-item tuple with the
|
|
389
|
-
# last item being the string. Starting with 3.10, they added to
|
|
390
|
-
# the tuple so now instead of it ending with the code that failed
|
|
391
|
-
# to parse, it ends with the end of the section of code that
|
|
392
|
-
# failed to parse. Luckily the absolute position in the tuple is
|
|
393
|
-
# stable across versions so we can use that here
|
|
394
|
-
physical_line = token[3]
|
|
395
|
-
|
|
396
|
-
# NOTE(sigmavirus24): Not all "tokens" have a string as the last
|
|
397
|
-
# argument. In this event, let's skip trying to find the correct
|
|
398
|
-
# column and row values.
|
|
399
|
-
if physical_line is not None:
|
|
400
|
-
# NOTE(sigmavirus24): SyntaxErrors also don't exactly have a
|
|
401
|
-
# "physical" line so much as what was accumulated by the point
|
|
402
|
-
# tokenizing failed.
|
|
403
|
-
# See also: https://github.com/pycqa/flake8/issues/169
|
|
404
|
-
lines = physical_line.rstrip("\n").split("\n")
|
|
405
|
-
row_offset = len(lines) - 1
|
|
406
|
-
logical_line = lines[0]
|
|
407
|
-
logical_line_length = len(logical_line)
|
|
408
|
-
if column > logical_line_length:
|
|
409
|
-
column = logical_line_length
|
|
410
|
-
row -= row_offset
|
|
411
|
-
column -= column_offset
|
|
412
375
|
return row, column
|
|
413
376
|
|
|
414
377
|
def run_ast_checks(self) -> None:
|
|
@@ -548,12 +511,14 @@ class FileChecker:
|
|
|
548
511
|
self.run_logical_checks()
|
|
549
512
|
|
|
550
513
|
def check_physical_eol(
|
|
551
|
-
self, token: tokenize.TokenInfo, prev_physical: str
|
|
514
|
+
self, token: tokenize.TokenInfo, prev_physical: str,
|
|
552
515
|
) -> None:
|
|
553
516
|
"""Run physical checks if and only if it is at the end of the line."""
|
|
554
517
|
assert self.processor is not None
|
|
555
518
|
if token.type == FSTRING_START: # pragma: >=3.12 cover
|
|
556
519
|
self.processor.fstring_start(token.start[0])
|
|
520
|
+
elif token.type == TSTRING_START: # pragma: >=3.14 cover
|
|
521
|
+
self.processor.tstring_start(token.start[0])
|
|
557
522
|
# a newline token ends a single physical line.
|
|
558
523
|
elif processor.is_eol_token(token):
|
|
559
524
|
# if the file does not end with a newline, the NEWLINE
|
|
@@ -596,7 +561,7 @@ def _try_initialize_processpool(
|
|
|
596
561
|
|
|
597
562
|
|
|
598
563
|
def find_offset(
|
|
599
|
-
offset: int, mapping: processor._LogicalMapping
|
|
564
|
+
offset: int, mapping: processor._LogicalMapping,
|
|
600
565
|
) -> tuple[int, int]:
|
|
601
566
|
"""Find the offset tuple for a single offset."""
|
|
602
567
|
if isinstance(offset, tuple):
|
|
@@ -110,7 +110,7 @@ class BaseFormatter:
|
|
|
110
110
|
The formatted error string.
|
|
111
111
|
"""
|
|
112
112
|
raise NotImplementedError(
|
|
113
|
-
"Subclass of BaseFormatter did not implement" " format."
|
|
113
|
+
"Subclass of BaseFormatter did not implement" " format.",
|
|
114
114
|
)
|
|
115
115
|
|
|
116
116
|
def show_statistics(self, statistics: Statistics) -> None:
|
|
@@ -76,7 +76,7 @@ class Application:
|
|
|
76
76
|
assert self.formatter is not None
|
|
77
77
|
assert self.options is not None
|
|
78
78
|
self.guide = style_guide.StyleGuideManager(
|
|
79
|
-
self.options, self.formatter
|
|
79
|
+
self.options, self.formatter,
|
|
80
80
|
)
|
|
81
81
|
|
|
82
82
|
def make_file_checker_manager(self, argv: Sequence[str]) -> None:
|
|
@@ -14,7 +14,7 @@ def information(version: str, plugins: Plugins) -> dict[str, Any]:
|
|
|
14
14
|
(loaded.plugin.package, loaded.plugin.version)
|
|
15
15
|
for loaded in plugins.all_plugins()
|
|
16
16
|
if loaded.plugin.package not in {"flake8", "local"}
|
|
17
|
-
}
|
|
17
|
+
},
|
|
18
18
|
)
|
|
19
19
|
return {
|
|
20
20
|
"version": version,
|
|
@@ -78,7 +78,7 @@ def load_config(
|
|
|
78
78
|
if config is not None:
|
|
79
79
|
if not cfg.read(config, encoding="UTF-8"):
|
|
80
80
|
raise exceptions.ExecutionError(
|
|
81
|
-
f"The specified config file does not exist: {config}"
|
|
81
|
+
f"The specified config file does not exist: {config}",
|
|
82
82
|
)
|
|
83
83
|
cfg_dir = os.path.dirname(config)
|
|
84
84
|
else:
|
|
@@ -89,7 +89,7 @@ def load_config(
|
|
|
89
89
|
for filename in extra:
|
|
90
90
|
if not cfg.read(filename, encoding="UTF-8"):
|
|
91
91
|
raise exceptions.ExecutionError(
|
|
92
|
-
f"The specified config file does not exist: {filename}"
|
|
92
|
+
f"The specified config file does not exist: {filename}",
|
|
93
93
|
)
|
|
94
94
|
|
|
95
95
|
return cfg, cfg_dir
|
|
@@ -131,7 +131,7 @@ def parse_config(
|
|
|
131
131
|
raise ValueError(
|
|
132
132
|
f"Error code {error_code!r} "
|
|
133
133
|
f"supplied to {option_name!r} option "
|
|
134
|
-
f"does not match {VALID_CODE_PREFIX.pattern!r}"
|
|
134
|
+
f"does not match {VALID_CODE_PREFIX.pattern!r}",
|
|
135
135
|
)
|
|
136
136
|
|
|
137
137
|
assert option.config_name is not None
|
|
@@ -5,9 +5,9 @@ import argparse
|
|
|
5
5
|
import enum
|
|
6
6
|
import functools
|
|
7
7
|
import logging
|
|
8
|
+
from collections.abc import Callable
|
|
8
9
|
from collections.abc import Sequence
|
|
9
10
|
from typing import Any
|
|
10
|
-
from typing import Callable
|
|
11
11
|
|
|
12
12
|
from flake8 import utils
|
|
13
13
|
from flake8.plugins.finder import Plugins
|
|
@@ -165,7 +165,7 @@ class Option:
|
|
|
165
165
|
if long_option_name is _ARG.NO:
|
|
166
166
|
raise ValueError(
|
|
167
167
|
"When specifying parse_from_config=True, "
|
|
168
|
-
"a long_option_name must also be specified."
|
|
168
|
+
"a long_option_name must also be specified.",
|
|
169
169
|
)
|
|
170
170
|
self.config_name = long_option_name[2:].replace("-", "_")
|
|
171
171
|
|
|
@@ -83,8 +83,8 @@ class Plugins(NamedTuple):
|
|
|
83
83
|
f"{loaded.plugin.package}: {loaded.plugin.version}"
|
|
84
84
|
for loaded in self.all_plugins()
|
|
85
85
|
if loaded.plugin.package not in {"flake8", "local"}
|
|
86
|
-
}
|
|
87
|
-
)
|
|
86
|
+
},
|
|
87
|
+
),
|
|
88
88
|
)
|
|
89
89
|
|
|
90
90
|
|
|
@@ -167,7 +167,7 @@ def _flake8_plugins(
|
|
|
167
167
|
# ideally pycodestyle's plugin entrypoints would exactly represent
|
|
168
168
|
# the codes they produce...
|
|
169
169
|
yield Plugin(
|
|
170
|
-
pycodestyle_meta["name"], pycodestyle_meta["version"], ep
|
|
170
|
+
pycodestyle_meta["name"], pycodestyle_meta["version"], ep,
|
|
171
171
|
)
|
|
172
172
|
else:
|
|
173
173
|
yield Plugin(name, version, ep)
|
|
@@ -240,7 +240,7 @@ def _check_required_plugins(
|
|
|
240
240
|
f"required plugins were not installed!\n"
|
|
241
241
|
f"- installed: {', '.join(sorted(plugin_names))}\n"
|
|
242
242
|
f"- expected: {', '.join(sorted(expected_names))}\n"
|
|
243
|
-
f"- missing: {', '.join(sorted(missing_plugins))}"
|
|
243
|
+
f"- missing: {', '.join(sorted(missing_plugins))}",
|
|
244
244
|
)
|
|
245
245
|
|
|
246
246
|
|
|
@@ -338,7 +338,7 @@ def _classify_plugins(
|
|
|
338
338
|
if not VALID_CODE_PREFIX.match(loaded.entry_name):
|
|
339
339
|
raise ExecutionError(
|
|
340
340
|
f"plugin code for `{loaded.display_name}` does not match "
|
|
341
|
-
f"{VALID_CODE_PREFIX.pattern}"
|
|
341
|
+
f"{VALID_CODE_PREFIX.pattern}",
|
|
342
342
|
)
|
|
343
343
|
|
|
344
344
|
return Plugins(
|
|
@@ -36,6 +36,7 @@ FLAKE8_PYFLAKES_CODES = {
|
|
|
36
36
|
"StringDotFormatMissingArgument": "F524",
|
|
37
37
|
"StringDotFormatMixingAutomatic": "F525",
|
|
38
38
|
"FStringMissingPlaceholders": "F541",
|
|
39
|
+
"TStringMissingPlaceholders": "F542",
|
|
39
40
|
"MultiValueRepeatedKeyLiteral": "F601",
|
|
40
41
|
"MultiValueRepeatedKeyVariable": "F602",
|
|
41
42
|
"TooManyExpressionsInStarredAssignment": "F621",
|
|
@@ -49,6 +50,8 @@ FLAKE8_PYFLAKES_CODES = {
|
|
|
49
50
|
"YieldOutsideFunction": "F704",
|
|
50
51
|
"ReturnOutsideFunction": "F706",
|
|
51
52
|
"DefaultExceptNotLast": "F707",
|
|
53
|
+
"LazyImportNotAtModuleScope": "F708",
|
|
54
|
+
"LazyImportStarNotPermitted": "F709",
|
|
52
55
|
"DoctestSyntaxError": "F721",
|
|
53
56
|
"ForwardAnnotationSyntaxError": "F722",
|
|
54
57
|
"RedefinedWhileUnused": "F811",
|
|
@@ -59,6 +62,7 @@ FLAKE8_PYFLAKES_CODES = {
|
|
|
59
62
|
"DuplicateArgument": "F831",
|
|
60
63
|
"UnusedVariable": "F841",
|
|
61
64
|
"UnusedAnnotation": "F842",
|
|
65
|
+
"EagerUseOfLazyImport": "F851",
|
|
62
66
|
"RaiseNotImplemented": "F901",
|
|
63
67
|
}
|
|
64
68
|
|
|
@@ -71,7 +75,7 @@ class FlakesChecker(pyflakes.checker.Checker):
|
|
|
71
75
|
def __init__(self, tree: ast.AST, filename: str) -> None:
|
|
72
76
|
"""Initialize the PyFlakes plugin with an AST tree and filename."""
|
|
73
77
|
super().__init__(
|
|
74
|
-
tree, filename=filename, withDoctest=self.with_doctest
|
|
78
|
+
tree, filename=filename, withDoctest=self.with_doctest,
|
|
75
79
|
)
|
|
76
80
|
|
|
77
81
|
@classmethod
|
|
@@ -13,13 +13,15 @@ from flake8 import defaults
|
|
|
13
13
|
from flake8 import utils
|
|
14
14
|
from flake8._compat import FSTRING_END
|
|
15
15
|
from flake8._compat import FSTRING_MIDDLE
|
|
16
|
+
from flake8._compat import TSTRING_END
|
|
17
|
+
from flake8._compat import TSTRING_MIDDLE
|
|
16
18
|
from flake8.plugins.finder import LoadedPlugin
|
|
17
19
|
|
|
18
20
|
LOG = logging.getLogger(__name__)
|
|
19
21
|
NEWLINE = frozenset([tokenize.NL, tokenize.NEWLINE])
|
|
20
22
|
|
|
21
23
|
SKIP_TOKENS = frozenset(
|
|
22
|
-
[tokenize.NL, tokenize.NEWLINE, tokenize.INDENT, tokenize.DEDENT]
|
|
24
|
+
[tokenize.NL, tokenize.NEWLINE, tokenize.INDENT, tokenize.DEDENT],
|
|
23
25
|
)
|
|
24
26
|
|
|
25
27
|
_LogicalMapping = list[tuple[int, tuple[int, int]]]
|
|
@@ -113,7 +115,7 @@ class FileProcessor:
|
|
|
113
115
|
self.verbose = options.verbose
|
|
114
116
|
#: Statistics dictionary
|
|
115
117
|
self.statistics = {"logical lines": 0}
|
|
116
|
-
self._fstring_start = -1
|
|
118
|
+
self._fstring_start = self._tstring_start = -1
|
|
117
119
|
|
|
118
120
|
@functools.cached_property
|
|
119
121
|
def file_tokens(self) -> list[tokenize.TokenInfo]:
|
|
@@ -125,10 +127,16 @@ class FileProcessor:
|
|
|
125
127
|
"""Signal the beginning of an fstring."""
|
|
126
128
|
self._fstring_start = lineno
|
|
127
129
|
|
|
130
|
+
def tstring_start(self, lineno: int) -> None: # pragma: >=3.14 cover
|
|
131
|
+
"""Signal the beginning of an tstring."""
|
|
132
|
+
self._tstring_start = lineno
|
|
133
|
+
|
|
128
134
|
def multiline_string(self, token: tokenize.TokenInfo) -> Generator[str]:
|
|
129
135
|
"""Iterate through the lines of a multiline string."""
|
|
130
136
|
if token.type == FSTRING_END: # pragma: >=3.12 cover
|
|
131
137
|
start = self._fstring_start
|
|
138
|
+
elif token.type == TSTRING_END: # pragma: >=3.14 cover
|
|
139
|
+
start = self._tstring_start
|
|
132
140
|
else:
|
|
133
141
|
start = token.start[0]
|
|
134
142
|
|
|
@@ -165,7 +173,7 @@ class FileProcessor:
|
|
|
165
173
|
"""Update the checker_state attribute for the plugin."""
|
|
166
174
|
if "checker_state" in plugin.parameters:
|
|
167
175
|
self.checker_state = self._checker_states.setdefault(
|
|
168
|
-
plugin.entry_name, {}
|
|
176
|
+
plugin.entry_name, {},
|
|
169
177
|
)
|
|
170
178
|
|
|
171
179
|
def next_logical_line(self) -> None:
|
|
@@ -198,7 +206,10 @@ class FileProcessor:
|
|
|
198
206
|
continue
|
|
199
207
|
if token_type == tokenize.STRING:
|
|
200
208
|
text = mutate_string(text)
|
|
201
|
-
elif token_type
|
|
209
|
+
elif token_type in {
|
|
210
|
+
FSTRING_MIDDLE,
|
|
211
|
+
TSTRING_MIDDLE,
|
|
212
|
+
}: # pragma: >=3.12 cover # noqa: E501
|
|
202
213
|
# A curly brace in an FSTRING_MIDDLE token must be an escaped
|
|
203
214
|
# curly brace. Both 'text' and 'end' will account for the
|
|
204
215
|
# escaped version of the token (i.e. a single brace) rather
|
|
@@ -269,7 +280,7 @@ class FileProcessor:
|
|
|
269
280
|
|
|
270
281
|
def _noqa_line_range(self, min_line: int, max_line: int) -> dict[int, str]:
|
|
271
282
|
line_range = range(min_line, max_line + 1)
|
|
272
|
-
joined = "".join(self.lines[min_line - 1
|
|
283
|
+
joined = "".join(self.lines[min_line - 1: max_line])
|
|
273
284
|
return dict.fromkeys(line_range, joined)
|
|
274
285
|
|
|
275
286
|
@functools.cached_property
|
|
@@ -356,7 +367,7 @@ class FileProcessor:
|
|
|
356
367
|
elif any(defaults.NOQA_FILE.search(line) for line in self.lines):
|
|
357
368
|
LOG.warning(
|
|
358
369
|
"Detected `flake8: noqa` on line with code. To ignore an "
|
|
359
|
-
"error on a line use `noqa` instead."
|
|
370
|
+
"error on a line use `noqa` instead.",
|
|
360
371
|
)
|
|
361
372
|
return False
|
|
362
373
|
else:
|
|
@@ -377,12 +388,12 @@ class FileProcessor:
|
|
|
377
388
|
|
|
378
389
|
def is_eol_token(token: tokenize.TokenInfo) -> bool:
|
|
379
390
|
"""Check if the token is an end-of-line token."""
|
|
380
|
-
return token[0] in NEWLINE or token[4][token[3][1]
|
|
391
|
+
return token[0] in NEWLINE or token[4][token[3][1]:].lstrip() == "\\\n"
|
|
381
392
|
|
|
382
393
|
|
|
383
394
|
def is_multiline_string(token: tokenize.TokenInfo) -> bool:
|
|
384
395
|
"""Check if this is a multiline string."""
|
|
385
|
-
return token.type
|
|
396
|
+
return token.type in {FSTRING_END, TSTRING_END} or (
|
|
386
397
|
token.type == tokenize.STRING and "\n" in token.string
|
|
387
398
|
)
|
|
388
399
|
|
|
@@ -35,7 +35,7 @@ class Statistics:
|
|
|
35
35
|
self._store[key].increment()
|
|
36
36
|
|
|
37
37
|
def statistics_for(
|
|
38
|
-
self, prefix: str, filename: str | None = None
|
|
38
|
+
self, prefix: str, filename: str | None = None,
|
|
39
39
|
) -> Generator[Statistic]:
|
|
40
40
|
"""Generate statistics for the prefix and filename.
|
|
41
41
|
|
|
@@ -108,7 +108,7 @@ class Statistic:
|
|
|
108
108
|
"""
|
|
109
109
|
|
|
110
110
|
def __init__(
|
|
111
|
-
self, error_code: str, filename: str, message: str, count: int
|
|
111
|
+
self, error_code: str, filename: str, message: str, count: int,
|
|
112
112
|
) -> None:
|
|
113
113
|
"""Initialize our Statistic."""
|
|
114
114
|
self.error_code = error_code
|
|
@@ -218,7 +218,7 @@ class StyleGuideManager:
|
|
|
218
218
|
self.decider = decider or DecisionEngine(options)
|
|
219
219
|
self.style_guides: list[StyleGuide] = []
|
|
220
220
|
self.default_style_guide = StyleGuide(
|
|
221
|
-
options, formatter, self.stats, decider=decider
|
|
221
|
+
options, formatter, self.stats, decider=decider,
|
|
222
222
|
)
|
|
223
223
|
self.style_guides = [
|
|
224
224
|
self.default_style_guide,
|
|
@@ -228,7 +228,7 @@ class StyleGuideManager:
|
|
|
228
228
|
self.style_guide_for = functools.cache(self._style_guide_for)
|
|
229
229
|
|
|
230
230
|
def populate_style_guides_with(
|
|
231
|
-
self, options: argparse.Namespace
|
|
231
|
+
self, options: argparse.Namespace,
|
|
232
232
|
) -> Generator[StyleGuide]:
|
|
233
233
|
"""Generate style guides from the per-file-ignores option.
|
|
234
234
|
|
|
@@ -240,7 +240,7 @@ class StyleGuideManager:
|
|
|
240
240
|
per_file = utils.parse_files_to_codes_mapping(options.per_file_ignores)
|
|
241
241
|
for filename, violations in per_file:
|
|
242
242
|
yield self.default_style_guide.copy(
|
|
243
|
-
filename=filename, extend_ignore_with=violations
|
|
243
|
+
filename=filename, extend_ignore_with=violations,
|
|
244
244
|
)
|
|
245
245
|
|
|
246
246
|
def _style_guide_for(self, filename: str) -> StyleGuide:
|
|
@@ -288,7 +288,7 @@ class StyleGuideManager:
|
|
|
288
288
|
"""
|
|
289
289
|
guide = self.style_guide_for(filename)
|
|
290
290
|
return guide.handle_error(
|
|
291
|
-
code, filename, line_number, column_number, text, physical_line
|
|
291
|
+
code, filename, line_number, column_number, text, physical_line,
|
|
292
292
|
)
|
|
293
293
|
|
|
294
294
|
|
|
@@ -330,7 +330,7 @@ class StyleGuide:
|
|
|
330
330
|
options.extend_ignore = options.extend_ignore or []
|
|
331
331
|
options.extend_ignore.extend(extend_ignore_with or [])
|
|
332
332
|
return StyleGuide(
|
|
333
|
-
options, self.formatter, self.stats, filename=filename
|
|
333
|
+
options, self.formatter, self.stats, filename=filename,
|
|
334
334
|
)
|
|
335
335
|
|
|
336
336
|
@contextlib.contextmanager
|
|
@@ -23,7 +23,7 @@ NORMALIZE_PACKAGE_NAME_RE = re.compile(r"[-_.]+")
|
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
def parse_comma_separated_list(
|
|
26
|
-
value: str, regexp: Pattern[str] = COMMA_SEPARATED_LIST_RE
|
|
26
|
+
value: str, regexp: Pattern[str] = COMMA_SEPARATED_LIST_RE,
|
|
27
27
|
) -> list[str]:
|
|
28
28
|
"""Parse a comma-separated list.
|
|
29
29
|
|
|
@@ -115,7 +115,7 @@ def parse_files_to_codes_mapping( # noqa: C901
|
|
|
115
115
|
f"Expected `per-file-ignores` to be a mapping from file exclude "
|
|
116
116
|
f"patterns to ignore codes.\n\n"
|
|
117
117
|
f"Configured `per-file-ignores` setting:\n\n"
|
|
118
|
-
f"{textwrap.indent(value.strip(), ' ')}"
|
|
118
|
+
f"{textwrap.indent(value.strip(), ' ')}",
|
|
119
119
|
)
|
|
120
120
|
|
|
121
121
|
for token in _tokenize_files_to_codes_mapping(value):
|
|
@@ -150,7 +150,7 @@ def parse_files_to_codes_mapping( # noqa: C901
|
|
|
150
150
|
|
|
151
151
|
|
|
152
152
|
def normalize_paths(
|
|
153
|
-
paths: Sequence[str], parent: str = os.curdir
|
|
153
|
+
paths: Sequence[str], parent: str = os.curdir,
|
|
154
154
|
) -> list[str]:
|
|
155
155
|
"""Normalize a list of paths relative to a parent directory.
|
|
156
156
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: flake8
|
|
3
|
-
Version: 7.
|
|
3
|
+
Version: 7.4.0
|
|
4
4
|
Summary: the modular source code checker: pep8 pyflakes and co
|
|
5
5
|
Home-page: https://github.com/pycqa/flake8
|
|
6
6
|
Author: Tarek Ziade
|
|
@@ -12,7 +12,6 @@ Classifier: Development Status :: 5 - Production/Stable
|
|
|
12
12
|
Classifier: Environment :: Console
|
|
13
13
|
Classifier: Framework :: Flake8
|
|
14
14
|
Classifier: Intended Audience :: Developers
|
|
15
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
16
15
|
Classifier: Programming Language :: Python
|
|
17
16
|
Classifier: Programming Language :: Python :: 3
|
|
18
17
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
@@ -20,12 +19,12 @@ Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
|
20
19
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
21
20
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
21
|
Classifier: Topic :: Software Development :: Quality Assurance
|
|
23
|
-
Requires-Python: >=3.
|
|
22
|
+
Requires-Python: >=3.10
|
|
24
23
|
Description-Content-Type: text/x-rst
|
|
25
24
|
License-File: LICENSE
|
|
26
25
|
Requires-Dist: mccabe<0.8.0,>=0.7.0
|
|
27
|
-
Requires-Dist: pycodestyle<2.
|
|
28
|
-
Requires-Dist: pyflakes<
|
|
26
|
+
Requires-Dist: pycodestyle<2.16.0,>=2.15.0
|
|
27
|
+
Requires-Dist: pyflakes<4.1.0,>=4.0.0
|
|
29
28
|
|
|
30
29
|
.. image:: https://github.com/PyCQA/flake8/workflows/main/badge.svg
|
|
31
30
|
:target: https://github.com/PyCQA/flake8/actions?query=workflow%3Amain
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|