Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: astral-sh/ruff
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.0.213
Choose a base ref
...
head repository: astral-sh/ruff
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.0.214
Choose a head ref
  • 19 commits
  • 373 files changed
  • 5 contributors

Commits on Jan 7, 2023

  1. Use text in comment token (#1714)

    RustPython/RustPython#4426 has been merged. We
    can simplify code using text in comment tokens.
    harupy authored Jan 7, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    5cdd7cc View commit details
  2. Implement flake8-simplify SIM103 (#1712)

    Ref #998
    
    Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
    messense and charliermarsh authored Jan 7, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    402feff View commit details
  3. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    07f7299 View commit details
  4. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    76a366e View commit details
  5. Fix clippy errors

    charliermarsh committed Jan 7, 2023
    Copy the full SHA
    3e80c0d View commit details
  6. 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.
    not-my-profile authored and charliermarsh committed Jan 7, 2023
    Copy the full SHA
    eea1379 View commit details
  7. Copy the full SHA
    15084df View commit details
  8. 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;'))
    not-my-profile authored and charliermarsh committed Jan 7, 2023
    Copy the full SHA
    90198f7 View commit details
  9. Copy the full SHA
    efadfed View commit details
  10. Copy the full SHA
    54fb47e View commit details
  11. Copy the full SHA
    3c8fdbf View commit details
  12. 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
    not-my-profile authored and charliermarsh committed Jan 7, 2023
    Copy the full SHA
    43db446 View commit details
  13. Copy the full SHA
    6208eb7 View commit details
  14. Copy the full SHA
    6a723b5 View commit details
  15. Copy the full SHA
    82e0c0c View commit details
  16. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    bdb9a4d View commit details
  17. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    9cfce61 View commit details
  18. Copy the full SHA
    edf46c0 View commit details
  19. Fix clippy errors

    charliermarsh committed Jan 7, 2023
    Copy the full SHA
    98856e0 View commit details
Loading