-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pycodestyle-whitespace-rules #1111
Pycodestyle-whitespace-rules #1111
Conversation
Add CheckCode(E201) variant and CheckKind (WhiteSpaceAfter `char`).
So currently I've added the two variants to Now I just am unsure as to how to go about implementing logic for either AST for tokens as per CONTRIBUTING.md suggestions. |
My approach here is to typically try and stay as closely as I can to the existing The hiccup is that I could see a few paths forward here:
let text = checker.locator.slice_source_code_range(&Range::from_located(stmt)); Then, use run regular expressions against the |
Another option is that I may be able to add the logical line code, in which case, adding new |
Sorry for delayed response. I was working on a solution using method 2 you described. I believe I have a working solution but have three problems.
I can check this code in if you would like to look at it. I am also not opposed to attempting to implement the logical_line functionality myself. I believe it is found here. |
Ok cool! I've made a little bit of progress on the logical line stuff, but I need to benchmark it to know if it's way too slow. Happy to take a look at what you have thus far, it may end up being better. The main thing I was unsure about with Approach 2 (after writing that comment) is that statements are nested, so taking the source code for a single statement isn't actually equivalent to a logical line, unless I'm misunderstanding. For example, if you have... def f():
x = 1 And you use the approach I described above, the first string would be the entire function, and the second would be To answer your questions:
|
#1130 implements the logical line building, and it seems to work in testing a variety of cases against pycodestyle. But it's way too slow, like more than doubles Ruff's runtime on the CPython benchmark. All the time is spent building the logical lines. |
Alright I figured I would just push my code and we can go from there. I focused on implementation. I basically pull out the logical line you suggested and then implement the regex search. You can see from returned data (first screenshot) that we are capturing the errors but always with column: 1. The print statements verify we can get the correct column using |
I think that to get the right range, we'd want to do something like this: self.add_check(Check::new(
CheckKind::WhiteSpaceAfter(character),
Range {
location: Location::new(stmt.location.row(), stmt.location.column() + found),
end_location: Location::new(stmt.location.row(), stmt.location.column() + found + 1)
}
)); (Not exactly right, doesn't handle newlines and multiple whitespaces, but the idea would be to use |
I think this approach is going to be somewhat limiting though, because it's not the case that each statement corresponds to one logical line. For example, if we have a nested function: def f():
def g():
pass Then with the current approach, we'd first look at this string: """
def f():
def g():
pass
""" And then, when we recursed, we'd look at this string: """
def g():
pass
""" Pycodestyle also has some rules whereby it removes comments and removes string contents (which I assume get in the way of the regular expressions), so we'd need to tokenize and find a way to handle those too. In short, I think we do need to create logical lines separately, or come up with a whole new strategy for this that's very different from Pycodestyle's strategy (e.g., iterate over the token stream, look for |
Closing for now to keep the PR list up-to-date, can always reopen. |
Add support for E2 and maybe E3 pycodestyle rules.