Charlie Marsh
9532f342a6
Enable project-specific typing module re-exports ( #1754 )
...
Resolves #1744 .
2023-01-09 18:17:50 -05:00
Mohamed Daahir
0ee37aa0aa
Cache build artifacts using Swatinem/rust-cache@v1 ( #1750 )
...
This GitHub Action caches build artifacts in addition to dependencies
which halves the CI duration time.
Resolves #1752 .
2023-01-09 15:35:32 -05:00
Charlie Marsh
8a26c8b4e0
Fix wasm builds
2023-01-09 12:58:07 -05:00
Charlie Marsh
2cb59b0f45
Use dedicated warnings for flake8-to-ruff ( #1748 )
2023-01-09 12:48:06 -05:00
Charlie Marsh
2729f3d207
Add support for defining extra builtins ( #1747 )
...
Resolves #1745 .
2023-01-09 12:24:28 -05:00
Charlie Marsh
59155ce9f6
Rename checks
and plugins
to rules
( #1739 )
2023-01-09 01:39:51 -05:00
Charlie Marsh
caf6c65de7
Bump version to 0.0.216
2023-01-09 01:14:28 -05:00
Matt Oberle
147d594b38
Add isort.force-sort-within-sections setting ( #1635 )
...
This commit is a first attempt at addressing issue #1003 .
The default `isort` behavior is `force-sort-within-sections = false`,
which places `from X import Y` statements after `import X` statements.
When `force-sort-within-sections = true` all imports are sorted by
module name.
When module names are equivalent, the `import` statement comes before
the `from` statement.
2023-01-09 01:06:48 -05:00
Charlie Marsh
f18078a1eb
Allow unused arguments for empty methods with docstrings ( #1742 )
...
Resolves #1741 .
2023-01-09 00:34:07 -05:00
Harutaka Kawamura
fe4eb13601
Autofix PT004, PT005, PT024, and PT025 ( #1740 )
2023-01-08 22:41:00 -05:00
Charlie Marsh
161ab05533
Rename more local usages of check
to diagnostic
( #1738 )
2023-01-08 18:10:08 -05:00
Charlie Marsh
2c537e24cc
Move violation structs out of registry.rs
( #1728 )
2023-01-08 17:54:20 -05:00
Charlie Marsh
0fe349b5f8
Rename CheckCategory
to RuleOrigin
( #1726 )
2023-01-08 17:50:18 -05:00
Charlie Marsh
09dc3c7225
Rename Check
to Diagnostic
( #1725 )
...
Along with:
- `CheckKind` -> `DiagnosticKind`
- `CheckCode` -> `RuleCode`
- `CheckCodePrefix` -> `RuleCodePrefix`
2023-01-08 17:46:20 -05:00
Harutaka Kawamura
498134b7ee
Audit unittest assert methods ( #1736 )
...
I ran the following code in Python 3.10 to automatically generate a list
of enums.
```python
import unittest
print(
",\n".join(
sorted(
m.removeprefix("assert") if m != "assert_" else "Underscore"
for m in dir(unittest.TestCase)
if m.startswith("assert")
)
)
)
```
2023-01-08 16:21:34 -05:00
Charlie Marsh
0152814a00
Bump version to 0.0.215
2023-01-07 22:17:29 -05:00
Harutaka Kawamura
0b3fab256b
Remove assertNotContains
( #1729 )
...
`unittest.TestCase` doens't have a method named `assertNotContains`.
2023-01-07 22:15:48 -05:00
Chammika Mannakkara
212ce4d331
buf-fix: flake8_simplify SIM212 ( #1732 )
...
bug-fix in #1717
Use the correct `IfExprWithTwistedArms` struct.
2023-01-07 22:03:48 -05:00
Charlie Marsh
491b1e4968
Move RUFF_CACHE_DIR to Clap's env support ( #1733 )
2023-01-07 22:01:27 -05:00
Charlie Marsh
8b01b53d89
Move RUFF_CACHE_DIR to Clap's env support ( #1733 )
2023-01-07 22:01:20 -05:00
messense
f9a5867d3e
Add RUFF_FORMAT
environment variable support ( #1731 )
...
Resolves #1716
2023-01-07 21:54:19 -05:00
Harutaka Kawamura
4149627f19
Add more unittest assert methods to PT009 ( #1730 )
2023-01-07 21:52:48 -05:00
Charlie Marsh
7d24146df7
Implement --isolated
CLI flag ( #1727 )
...
Closes #1724 .
2023-01-07 18:43:58 -05:00
Charlie Marsh
1c6ef3666c
Treat failures to fix TypedDict conversions as debug logs ( #1723 )
...
This also allows us to flag the error, even if we can't fix it.
Closes #1212 .
2023-01-07 17:51:45 -05:00
Charlie Marsh
16d933fcf5
Respect isort:skip action comment ( #1722 )
...
Resolves : #1718 .
2023-01-07 17:30:18 -05:00
Charlie Marsh
a9cc56b2ac
Add ComparableExpr
hierarchy for comparing expressions ( #1721 )
2023-01-07 17:29:21 -05:00
Charlie Marsh
4de6c26ff9
Automatically remove duplicate dictionary keys ( #1710 )
...
For now, to be safe, we're only removing keys with duplicate _values_.
See: #1647 .
2023-01-07 16:16:42 -05:00
Charlie Marsh
98856e05d6
Fix clippy errors
2023-01-07 15:49:59 -05:00
Charlie Marsh
edf46c06d0
Bump version to 0.0.214
2023-01-07 15:34:45 -05:00
Chammika Mannakkara
9cfce61f36
flake8_simplify : SIM210, SIM211, SIM212 ( #1717 )
2023-01-07 15:32:34 -05:00
Charlie Marsh
bdb9a4d1a7
Update CONTRIBUTING.md to point to violations.rs ( #1720 )
2023-01-07 15:20:21 -05:00
Martin Fischer
82e0c0ced6
structs 9/9: Run cargo test and cargo insta accept
2023-01-07 15:14:58 -05:00
Martin Fischer
6a723b50c7
structs 8/9: Run cargo fix and cargo fmt
2023-01-07 15:14:58 -05:00
Martin Fischer
6208eb7bbf
structs 7/9: Manually fix errors introduced in the previous commit
2023-01-07 15:14:58 -05:00
Martin Fischer
43db446dfa
structs 6/9: Automatically change CheckKind::* to violations::*
...
The changes in this commit were generated by running:
for f in $(find src -name '*.rs'); do sed -Ei 's/use crate::registry::.*;/\0use crate::violations;/g' $f; done
for f in $(find src -name '*.rs'); do sed -Ei 's/CheckKind::([A-Z])/violations::\1/g' $f; done
git checkout src/registry.rs src/lib.rs src/lib_wasm.rs src/violations.rs
cargo +nightly fmt
2023-01-07 15:14:58 -05:00
Martin Fischer
3c8fdbf107
structs 5/9: Make Check::new call into() on the passed kind
2023-01-07 15:14:58 -05:00
Martin Fischer
54fb47ea6a
structs 4/9: Implement define_rule_mapping!
2023-01-07 15:14:58 -05:00
Martin Fischer
efadfeda96
structs 3/9: Manually implement autofix_formatter for conditional autofixes
2023-01-07 15:14:58 -05:00
Martin Fischer
90198f7563
structs 2/9: Generate violations.rs from registry.rs
...
# The changes of this commit were generated using the following code:
# (followed by cargo +nightly fmt)
import re
import subprocess
import io
indent = ' ' * 4
def split_words(s):
return re.split(r'\b', s)
def checkkind_match_arms(f, strip_some=False):
bodies = {}
while (line := next(f).rstrip()) != indent * 2 + '}':
if line.lstrip().startswith('//'):
continue
if line.strip() == '':
continue
parts = line.split('=>', maxsplit=1)
if parts[0].strip() == '_':
break
left, body = parts
left = left.strip()
body = body.strip()
if body == '{':
body = ''
while (line := next(f).rstrip()) != indent * 3 + '}':
body += line + '\n'
else:
body = body.rstrip(',')
kind = split_words(left)[3]
if strip_some:
body = re.sub('\)$', '', re.sub(r'Some\(', '', body, 1).rstrip(), 1)
if ('(' in left and not '(..)' in left) or '{' in left:
body = (
'let '
+ left.replace('CheckKind::', '').replace('CheckCode::', '')
+ ' = self;\n'
+ body
)
bodies[kind] = body
return bodies
with open('src/registry.rs') as f:
orig_registry_code = f.read()
# simplify the parsing of multiline match arms
registry_code = subprocess.check_output(
['rustfmt', '+nightly', '--config', 'force_multiline_blocks=true'],
encoding='utf-8',
input=orig_registry_code,
)
f = io.StringIO(registry_code)
# 1. Parse the CheckCode enum
while next(f).strip() != 'pub enum CheckCode {':
pass
checkcode_lines = []
while (line := next(f).strip().rstrip(',')) != '}':
checkcode_lines.append(line)
# 2. Parse the CheckKind enum
while next(f).strip() != 'pub enum CheckKind {':
pass
struct_defs = {}
while (line := next(f).strip()) != '}':
if line.startswith('//'):
continue
line = line.rstrip(',')
line = re.sub(r'{', '{ pub ', line)
line = re.sub(r'\(', '(pub ', line)
line = re.sub(',', ', pub', line)
kind = split_words(line)[1]
struct_defs[kind] = 'pub struct ' + line + (';' * (line[-1] != '}'))
# 3. parse the kind() impl for CheckKind
while next(f).rstrip() != " pub fn kind(&self) -> CheckKind {":
pass
assert next(f).strip() == 'match self {'
placeholders = checkkind_match_arms(f)
# 4. parse the CheckKind -> CheckCode mapping
while next(f).strip() != "pub fn code(&self) -> &'static CheckCode {":
pass
assert next(f).strip() == 'match self {'
kind2code = {}
while (line := next(f).strip().rstrip(',')) != '}':
if line.startswith('//'):
continue
parts = re.split(r'\b', line)
kind2code[parts[3]] = parts[-2]
code2kind = {code: kind for kind, code in kind2code.items()}
# 5. parse the body() impl for CheckKind
while next(f).rstrip() != " pub fn body(&self) -> String {":
pass
assert next(f).strip() == 'match self {'
bodies = checkkind_match_arms(f)
# 6. find fixable
always_fixable = []
sometimes_fixable = []
while next(f).strip() != "// Always-fixable checks.":
pass
while (line := next(f).strip()) != '// Conditionally-fixable checks.':
always_fixable.append(split_words(line)[3])
while (line := next(f).strip()) != '// Non-fixable checks.':
sometimes_fixable.append(split_words(line)[3])
# 7. find autofix message
while next(f).rstrip() != indent + "pub fn commit(&self) -> Option<String> {":
pass
assert next(f).strip() == 'match self {'
autofix_msg = checkkind_match_arms(f, strip_some=True)
reg = '''\
macro_rules! define_rule_mapping {
($($code:ident => $mod:ident::$name:ident,)+) => {
// TODO: implement
};
}
define_rule_mapping!(
'''
for line in checkcode_lines:
if line.startswith('//'):
reg += indent + line + '\n'
continue
code = line
reg += indent + code + ' => violations::' + code2kind[code] + ',\n'
reg += ');\n\n'
with open('src/registry.rs', 'w') as f:
marker = '#[derive'
f.write(orig_registry_code.replace(marker, reg + marker, 1))
out = '''\
use itertools::Itertools;
use crate::define_violation;
use crate::flake8_debugger::types::DebuggerUsingType;
use crate::flake8_pytest_style::types::{ParametrizeNameType, ParametrizeValuesType, ParametrizeValuesRowType};
use crate::flake8_quotes::settings::Quote;
use crate::flake8_tidy_imports::settings::Strictness;
use crate::pyupgrade::types::Primitive;
use crate::registry::{
Branch, DeferralKeyword, EqCmpop, IsCmpop, LiteralType, MockReference, UnusedCodes,
};
use crate::violation::{AlwaysAutofixableViolation, Violation};
'''
for line in checkcode_lines:
if line.startswith('//'):
out += '\n' + line + '\n\n'
continue
code = line
kind = code2kind[code]
out += 'define_violation!(' + struct_defs[kind] + ');\n'
if kind in always_fixable:
out += f'impl AlwaysAutofixableViolation for {kind} {{\n'
else:
out += f'impl Violation for {kind} {{\n'
out += 'fn message(&self) -> String {'
out += bodies[kind]
out += '}'
if kind in always_fixable:
out += 'fn autofix_title(&self) -> String {'
out += autofix_msg[kind]
out += '}'
elif kind in sometimes_fixable:
out += 'fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {'
out += 'todo!()'
out += '}'
out += 'fn placeholder() -> Self {'
out += placeholders[code].replace('CheckKind::', '')
out += '}'
out += '}\n\n'
with open('src/violations.rs', 'w') as f:
f.write(out)
with open('src/lib.rs', 'r') as f:
mod = f.read()
with open('src/lib.rs', 'w') as f:
marker = 'mod violation;'
f.write(mod.replace(marker, marker + '\nmod violations;'))
2023-01-07 15:14:58 -05:00
Martin Fischer
15084dff9d
structs 1/9: Manually preprocess registry.rs
2023-01-07 15:14:58 -05:00
Martin Fischer
eea1379a74
structs 0/9: Introduce Violation trait
...
For every available rule registry.rs currently defines:
1. A CheckCode variant to identify the rule.
2. A CheckKind variant to represent violations of the rule.
3. A mapping from the CheckCode variant to a placeholder CheckKind instance.
4. A mapping from the CheckKind variant to CheckCode.
5. A mapping from the CheckKind to a string description.
6. A mapping from the CheckKind to a boolean indicating if autofix is available.
7. A mapping from the CheckKind to a string describing the autofix if available.
Since registry.rs defines all of this for every single rule and
ruff has hundreds of rules, this results in the lines specific to
a particular rule to be hundreds of lines apart, making the code
cumbersome to read and edit.
This commit introduces a new Violation trait so that the rule-specific
details of the above steps 5.-7. can be defined next to the rule
implementation. The idea is that once all CheckCode/CheckKind variants
have been converted to this new approach then the steps 1.-4. in
registry.rs could simply be generated via a declarative macro, e.g:
define_rule_mapping!(
E501 => pycodestyle::LineTooLong,
...
);
(where `pycodestyle::LineTooLong` would be a struct that implements the
new Violation trait).
The define_rule_mapping! macro would then take care of generating the
CheckCode and CheckKind enums, as well as all of the implementations for
the previously mentioned mappings, by simply calling the methods of the
new Violation trait.
There is another nice benefit from this approach: We want to introduce
more thorough documentation for rules and we want the documentation of a
rule to be defined close by the implementation (so that it's easier to
check if they match and that they're less likely to become out of sync).
Since these new Violation structs can be defined close by the
implementation of a rule we can also use them as an anchor point for the
documentation of a rule by simply adding the documentation in the form
of a Rust doc comment to the struct.
2023-01-07 15:14:58 -05:00
Charlie Marsh
3e80c0d43e
Fix clippy errors
2023-01-07 12:53:36 -05:00
Harutaka Kawamura
76a366e05a
Trim trailing whitespace when extracting isort directives ( #1715 )
2023-01-07 12:39:31 -05:00
Harutaka Kawamura
07f72990a9
Implement autofix for PT009 ( #1713 )
2023-01-07 12:28:25 -05:00
messense
402feffe85
Implement flake8-simplify SIM103 ( #1712 )
...
Ref #998
Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2023-01-07 07:33:24 -05:00
Harutaka Kawamura
5cdd7ccdb8
Use text in comment token ( #1714 )
...
https://github.com/RustPython/RustPython/pull/4426 has been merged. We
can simplify code using text in comment tokens.
2023-01-07 07:29:04 -05:00
Charlie Marsh
f1c3ebfe0f
Bump version to 0.0.213
2023-01-07 00:30:56 -05:00
Charlie Marsh
c7e4e41a7a
Revert "Include list of fixed files in stderr
output ( #1701 )" ( #1711 )
...
This reverts commit 53ed52dc59
.
I want to get some feedback on this before I send it out.
2023-01-07 00:30:25 -05:00
Charlie Marsh
311a823a4a
Increase blackd wait time ( #1709 )
...
Resolves #1511 .
2023-01-06 23:08:25 -05:00
Harutaka Kawamura
8c836aeecf
Add more backticks to flake8-pytest-style error messages ( #1707 )
2023-01-06 22:55:24 -05:00