mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-24 19:12:44 +00:00
Add no-eval rule from pygrep-hooks (#994)
This commit is contained in:
parent
1a24d78f67
commit
117fcb6936
13 changed files with 267 additions and 47 deletions
23
LICENSE
23
LICENSE
|
@ -471,6 +471,29 @@ are:
|
|||
SOFTWARE.
|
||||
"""
|
||||
|
||||
- pygrep-hooks, licensed as follows:
|
||||
"""
|
||||
Copyright (c) 2018 Anthony Sottile
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
|
||||
- pyupgrade, licensed as follows:
|
||||
"""
|
||||
Copyright (c) 2017 Anthony Sottile
|
||||
|
|
25
README.md
25
README.md
|
@ -77,18 +77,20 @@ of [Conda](https://docs.conda.io/en/latest/):
|
|||
1. [pep8-naming (N)](#pep8-naming)
|
||||
1. [eradicate (ERA)](#eradicate)
|
||||
1. [flake8-bandit (S)](#flake8-bandit)
|
||||
1. [flake8-comprehensions (C)](#flake8-comprehensions)
|
||||
1. [flake8-comprehensions (C4)](#flake8-comprehensions)
|
||||
1. [flake8-boolean-trap (FBT)](#flake8-boolean-trap)
|
||||
1. [flake8-bugbear (B)](#flake8-bugbear)
|
||||
1. [flake8-builtins (A)](#flake8-builtins)
|
||||
1. [flake8-debugger (T)](#flake8-debugger)
|
||||
1. [flake8-debugger (T10)](#flake8-debugger)
|
||||
1. [flake8-tidy-imports (I25)](#flake8-tidy-imports)
|
||||
1. [flake8-print (T)](#flake8-print)
|
||||
1. [flake8-print (T20)](#flake8-print)
|
||||
1. [flake8-quotes (Q)](#flake8-quotes)
|
||||
1. [flake8-annotations (ANN)](#flake8-annotations)
|
||||
1. [flake8-2020 (YTT)](#flake8-2020)
|
||||
1. [flake8-blind-except (BLE)](#flake8-blind-except)
|
||||
1. [mccabe (C90)](#mccabe)
|
||||
1. [pygrep-hooks (PGH)](#pygrep-hooks)
|
||||
1. [Pylint (PL)](#pylint)
|
||||
1. [Ruff-specific rules (RUF)](#ruff-specific-rules)
|
||||
1. [Meta rules (M)](#meta-rules)
|
||||
1. [Editor Integrations](#editor-integrations)
|
||||
|
@ -726,6 +728,14 @@ For more, see [mccabe](https://pypi.org/project/mccabe/0.7.0/) on PyPI.
|
|||
| ---- | ---- | ------- | --- |
|
||||
| C901 | FunctionIsTooComplex | `...` is too complex (10) | |
|
||||
|
||||
### pygrep-hooks
|
||||
|
||||
For more, see [pygrep-hooks](https://github.com/pre-commit/pygrep-hooks) on GitHub.
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| PGH001 | NoEval | No builtin `eval()` allowed | |
|
||||
|
||||
### Pylint
|
||||
|
||||
For more, see [Pylint](https://pypi.org/project/pylint/2.15.7/) on PyPI.
|
||||
|
@ -902,6 +912,7 @@ natively, including:
|
|||
- [`yesqa`](https://github.com/asottile/yesqa)
|
||||
- [`eradicate`](https://pypi.org/project/eradicate/)
|
||||
- [`pyupgrade`](https://pypi.org/project/pyupgrade/) (16/33)
|
||||
- [`pygrep-hooks`](https://github.com/pre-commit/pygrep-hooks) (1/10)
|
||||
- [`autoflake`](https://pypi.org/project/autoflake/) (1/7)
|
||||
|
||||
Beyond the rule set, Ruff suffers from the following limitations vis-à-vis Flake8:
|
||||
|
@ -946,8 +957,10 @@ Today, Ruff can be used to replace Flake8 when used with any of the following pl
|
|||
- [`flake8-tidy-imports`](https://pypi.org/project/flake8-tidy-imports/) (1/3)
|
||||
- [`mccabe`](https://pypi.org/project/mccabe/)
|
||||
|
||||
Ruff can also replace [`isort`](https://pypi.org/project/isort/), [`yesqa`](https://github.com/asottile/yesqa),
|
||||
and a subset of the rules implemented in [`pyupgrade`](https://pypi.org/project/pyupgrade/) (16/33).
|
||||
Ruff can also replace [`isort`](https://pypi.org/project/isort/),
|
||||
[`yesqa`](https://github.com/asottile/yesqa), [`eradicate`](https://pypi.org/project/eradicate/),
|
||||
[`pygrep-hooks`](https://github.com/pre-commit/pygrep-hooks) (1/10), and a subset of the rules
|
||||
implemented in [`pyupgrade`](https://pypi.org/project/pyupgrade/) (16/33).
|
||||
|
||||
If you're looking to use Ruff, but rely on an unsupported Flake8 plugin, free to file an Issue.
|
||||
|
||||
|
@ -1261,7 +1274,7 @@ Exclusions are based on globs, and can be either:
|
|||
(to exclude any Python files in `directory`). Note that these paths are relative to the
|
||||
project root (e.g., the directory containing your `pyproject.toml`).
|
||||
|
||||
Note that you'll typically want to use [`extend_exclude`](#extend_exclude) to modify the excluded
|
||||
Note that you'll typically want to use [`extend_exclude`](#extend-exclude) to modify the excluded
|
||||
paths.
|
||||
|
||||
**Default value**: `[".bzr", ".direnv", ".eggs", ".git", ".hg", ".mypy_cache", ".nox", ".pants.d", ".ruff_cache", ".svn", ".tox", ".venv", "__pypackages__", "_build", "buck-out", "build", "dist", "node_modules", "venv"]`
|
||||
|
|
9
resources/test/fixtures/pygrep-hooks/PGH001_0.py
vendored
Normal file
9
resources/test/fixtures/pygrep-hooks/PGH001_0.py
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
from ast import literal_eval
|
||||
|
||||
eval("3 + 4")
|
||||
|
||||
literal_eval({1: 2})
|
||||
|
||||
|
||||
def fn() -> None:
|
||||
eval("3 + 4")
|
11
resources/test/fixtures/pygrep-hooks/PGH001_1.py
vendored
Normal file
11
resources/test/fixtures/pygrep-hooks/PGH001_1.py
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
def eval(content: str) -> None:
|
||||
pass
|
||||
|
||||
|
||||
eval("3 + 4")
|
||||
|
||||
literal_eval({1: 2})
|
||||
|
||||
|
||||
def fn() -> None:
|
||||
eval("3 + 4")
|
|
@ -28,11 +28,12 @@ pub fn main(cli: &Cli) -> Result<()> {
|
|||
output.push('\n');
|
||||
output.push('\n');
|
||||
|
||||
if let Some(url) = check_category.url() {
|
||||
if let Some((url, platform)) = check_category.url() {
|
||||
output.push_str(&format!(
|
||||
"For more, see [{}]({}) on PyPI.",
|
||||
"For more, see [{}]({}) on {}.",
|
||||
check_category.title(),
|
||||
url
|
||||
url,
|
||||
platform
|
||||
));
|
||||
output.push('\n');
|
||||
output.push('\n');
|
||||
|
|
|
@ -37,7 +37,7 @@ use crate::{
|
|||
docstrings, flake8_2020, flake8_annotations, flake8_bandit, flake8_blind_except,
|
||||
flake8_boolean_trap, flake8_bugbear, flake8_builtins, flake8_comprehensions, flake8_debugger,
|
||||
flake8_print, flake8_tidy_imports, mccabe, pep8_naming, pycodestyle, pydocstyle, pyflakes,
|
||||
pylint, pyupgrade, rules,
|
||||
pygrep_hooks, pylint, pyupgrade, rules,
|
||||
};
|
||||
|
||||
const GLOBAL_SCOPE_INDEX: usize = 0;
|
||||
|
@ -1700,6 +1700,11 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
// pygrep-hooks
|
||||
if self.settings.enabled.contains(&CheckCode::PGH001) {
|
||||
pygrep_hooks::checks::no_eval(self, func);
|
||||
}
|
||||
|
||||
// Ruff
|
||||
if self.settings.enabled.contains(&CheckCode::RUF101) {
|
||||
rules::plugins::convert_exit_to_sys_exit(self, func);
|
||||
|
|
146
src/checks.rs
146
src/checks.rs
|
@ -278,6 +278,8 @@ pub enum CheckCode {
|
|||
RUF101,
|
||||
// Meta
|
||||
M001,
|
||||
// pygrep-hooks
|
||||
PGH001,
|
||||
}
|
||||
|
||||
#[derive(EnumIter, Debug, PartialEq, Eq)]
|
||||
|
@ -302,11 +304,26 @@ pub enum CheckCategory {
|
|||
Flake82020,
|
||||
Flake8BlindExcept,
|
||||
McCabe,
|
||||
PygrepHooks,
|
||||
Pylint,
|
||||
Ruff,
|
||||
Meta,
|
||||
}
|
||||
|
||||
pub enum Platform {
|
||||
PyPI,
|
||||
GitHub,
|
||||
}
|
||||
|
||||
impl fmt::Display for Platform {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Platform::PyPI => fmt.write_str("PyPI"),
|
||||
Platform::GitHub => fmt.write_str("GitHub"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CheckCategory {
|
||||
pub fn title(&self) -> &'static str {
|
||||
match self {
|
||||
|
@ -331,51 +348,97 @@ impl CheckCategory {
|
|||
CheckCategory::Pydocstyle => "pydocstyle",
|
||||
CheckCategory::Pyflakes => "Pyflakes",
|
||||
CheckCategory::Pylint => "Pylint",
|
||||
CheckCategory::PygrepHooks => "pygrep-hooks",
|
||||
CheckCategory::Pyupgrade => "pyupgrade",
|
||||
CheckCategory::Ruff => "Ruff-specific rules",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn url(&self) -> Option<&'static str> {
|
||||
pub fn url(&self) -> Option<(&'static str, &'static Platform)> {
|
||||
match self {
|
||||
CheckCategory::Eradicate => Some("https://pypi.org/project/eradicate/2.1.0/"),
|
||||
CheckCategory::Flake82020 => Some("https://pypi.org/project/flake8-2020/1.7.0/"),
|
||||
CheckCategory::Flake8Annotations => {
|
||||
Some("https://pypi.org/project/flake8-annotations/2.9.1/")
|
||||
CheckCategory::Eradicate => {
|
||||
Some(("https://pypi.org/project/eradicate/2.1.0/", &Platform::PyPI))
|
||||
}
|
||||
CheckCategory::Flake8Bandit => Some("https://pypi.org/project/flake8-bandit/4.1.1/"),
|
||||
CheckCategory::Flake8BlindExcept => {
|
||||
Some("https://pypi.org/project/flake8-blind-except/0.2.1/")
|
||||
CheckCategory::Flake82020 => Some((
|
||||
"https://pypi.org/project/flake8-2020/1.7.0/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8Annotations => Some((
|
||||
"https://pypi.org/project/flake8-annotations/2.9.1/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8Bandit => Some((
|
||||
"https://pypi.org/project/flake8-bandit/4.1.1/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8BlindExcept => Some((
|
||||
"https://pypi.org/project/flake8-blind-except/0.2.1/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8BooleanTrap => Some((
|
||||
"https://pypi.org/project/flake8-boolean-trap/0.1.0/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8Bugbear => Some((
|
||||
"https://pypi.org/project/flake8-bugbear/22.10.27/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8Builtins => Some((
|
||||
"https://pypi.org/project/flake8-builtins/2.0.1/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8Comprehensions => Some((
|
||||
"https://pypi.org/project/flake8-comprehensions/3.10.1/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8Debugger => Some((
|
||||
"https://pypi.org/project/flake8-debugger/4.1.2/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8Print => Some((
|
||||
"https://pypi.org/project/flake8-print/5.0.0/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8Quotes => Some((
|
||||
"https://pypi.org/project/flake8-quotes/3.3.1/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8TidyImports => Some((
|
||||
"https://pypi.org/project/flake8-tidy-imports/4.8.0/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Isort => {
|
||||
Some(("https://pypi.org/project/isort/5.10.1/", &Platform::PyPI))
|
||||
}
|
||||
CheckCategory::Flake8BooleanTrap => {
|
||||
Some("https://pypi.org/project/flake8-boolean-trap/0.1.0/")
|
||||
CheckCategory::McCabe => {
|
||||
Some(("https://pypi.org/project/mccabe/0.7.0/", &Platform::PyPI))
|
||||
}
|
||||
CheckCategory::Flake8Bugbear => {
|
||||
Some("https://pypi.org/project/flake8-bugbear/22.10.27/")
|
||||
}
|
||||
CheckCategory::Flake8Builtins => {
|
||||
Some("https://pypi.org/project/flake8-builtins/2.0.1/")
|
||||
}
|
||||
CheckCategory::Flake8Comprehensions => {
|
||||
Some("https://pypi.org/project/flake8-comprehensions/3.10.1/")
|
||||
}
|
||||
CheckCategory::Flake8Debugger => {
|
||||
Some("https://pypi.org/project/flake8-debugger/4.1.2/")
|
||||
}
|
||||
CheckCategory::Flake8Print => Some("https://pypi.org/project/flake8-print/5.0.0/"),
|
||||
CheckCategory::Flake8Quotes => Some("https://pypi.org/project/flake8-quotes/3.3.1/"),
|
||||
CheckCategory::Flake8TidyImports => {
|
||||
Some("https://pypi.org/project/flake8-tidy-imports/4.8.0/")
|
||||
}
|
||||
CheckCategory::Isort => Some("https://pypi.org/project/isort/5.10.1/"),
|
||||
CheckCategory::McCabe => Some("https://pypi.org/project/mccabe/0.7.0/"),
|
||||
CheckCategory::Meta => None,
|
||||
CheckCategory::PEP8Naming => Some("https://pypi.org/project/pep8-naming/0.13.2/"),
|
||||
CheckCategory::Pycodestyle => Some("https://pypi.org/project/pycodestyle/2.9.1/"),
|
||||
CheckCategory::Pydocstyle => Some("https://pypi.org/project/pydocstyle/6.1.1/"),
|
||||
CheckCategory::Pyflakes => Some("https://pypi.org/project/pyflakes/2.5.0/"),
|
||||
CheckCategory::Pylint => Some("https://pypi.org/project/pylint/2.15.7/"),
|
||||
CheckCategory::Pyupgrade => Some("https://pypi.org/project/pyupgrade/3.2.0/"),
|
||||
CheckCategory::PEP8Naming => Some((
|
||||
"https://pypi.org/project/pep8-naming/0.13.2/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Pycodestyle => Some((
|
||||
"https://pypi.org/project/pycodestyle/2.9.1/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Pydocstyle => Some((
|
||||
"https://pypi.org/project/pydocstyle/6.1.1/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Pyflakes => {
|
||||
Some(("https://pypi.org/project/pyflakes/2.5.0/", &Platform::PyPI))
|
||||
}
|
||||
CheckCategory::Pylint => {
|
||||
Some(("https://pypi.org/project/pylint/2.15.7/", &Platform::PyPI))
|
||||
}
|
||||
CheckCategory::PygrepHooks => Some((
|
||||
"https://github.com/pre-commit/pygrep-hooks",
|
||||
&Platform::GitHub,
|
||||
)),
|
||||
CheckCategory::Pyupgrade => {
|
||||
Some(("https://pypi.org/project/pyupgrade/3.2.0/", &Platform::PyPI))
|
||||
}
|
||||
CheckCategory::Ruff => None,
|
||||
}
|
||||
}
|
||||
|
@ -657,6 +720,8 @@ pub enum CheckKind {
|
|||
BooleanPositionalArgInFunctionDefinition,
|
||||
BooleanDefaultValueInFunctionDefinition,
|
||||
BooleanPositionalValueInFunctionCall,
|
||||
// pygrep-hooks
|
||||
NoEval,
|
||||
// Ruff
|
||||
AmbiguousUnicodeCharacterString(char, char),
|
||||
AmbiguousUnicodeCharacterDocstring(char, char),
|
||||
|
@ -975,6 +1040,8 @@ impl CheckCode {
|
|||
CheckCode::FBT001 => CheckKind::BooleanPositionalArgInFunctionDefinition,
|
||||
CheckCode::FBT002 => CheckKind::BooleanDefaultValueInFunctionDefinition,
|
||||
CheckCode::FBT003 => CheckKind::BooleanPositionalValueInFunctionCall,
|
||||
// pygrep-hooks
|
||||
CheckCode::PGH001 => CheckKind::NoEval,
|
||||
// Ruff
|
||||
CheckCode::RUF001 => CheckKind::AmbiguousUnicodeCharacterString('𝐁', 'B'),
|
||||
CheckCode::RUF002 => CheckKind::AmbiguousUnicodeCharacterDocstring('𝐁', 'B'),
|
||||
|
@ -1169,6 +1236,7 @@ impl CheckCode {
|
|||
CheckCode::N816 => CheckCategory::PEP8Naming,
|
||||
CheckCode::N817 => CheckCategory::PEP8Naming,
|
||||
CheckCode::N818 => CheckCategory::PEP8Naming,
|
||||
CheckCode::PGH001 => CheckCategory::PygrepHooks,
|
||||
CheckCode::PLE1142 => CheckCategory::Pylint,
|
||||
CheckCode::Q000 => CheckCategory::Flake8Quotes,
|
||||
CheckCode::Q001 => CheckCategory::Flake8Quotes,
|
||||
|
@ -1456,12 +1524,14 @@ impl CheckKind {
|
|||
CheckKind::HardcodedPasswordString(..) => &CheckCode::S105,
|
||||
CheckKind::HardcodedPasswordFuncArg(..) => &CheckCode::S106,
|
||||
CheckKind::HardcodedPasswordDefault(..) => &CheckCode::S107,
|
||||
// McCabe
|
||||
// mccabe
|
||||
CheckKind::FunctionIsTooComplex(..) => &CheckCode::C901,
|
||||
// flake8-boolean-trap
|
||||
CheckKind::BooleanPositionalArgInFunctionDefinition => &CheckCode::FBT001,
|
||||
CheckKind::BooleanDefaultValueInFunctionDefinition => &CheckCode::FBT002,
|
||||
CheckKind::BooleanPositionalValueInFunctionCall => &CheckCode::FBT003,
|
||||
// pygrep-hooks
|
||||
CheckKind::NoEval => &CheckCode::PGH001,
|
||||
// Ruff
|
||||
CheckKind::AmbiguousUnicodeCharacterString(..) => &CheckCode::RUF001,
|
||||
CheckKind::AmbiguousUnicodeCharacterDocstring(..) => &CheckCode::RUF002,
|
||||
|
@ -2183,7 +2253,7 @@ impl CheckKind {
|
|||
}
|
||||
// flake8-blind-except
|
||||
CheckKind::BlindExcept => "Blind except Exception: statement".to_string(),
|
||||
// McCabe
|
||||
// mccabe
|
||||
CheckKind::FunctionIsTooComplex(name, complexity) => {
|
||||
format!("`{name}` is too complex ({complexity})")
|
||||
}
|
||||
|
@ -2197,6 +2267,8 @@ impl CheckKind {
|
|||
CheckKind::BooleanPositionalValueInFunctionCall => {
|
||||
"Boolean positional value in function call".to_string()
|
||||
}
|
||||
// pygrep-hooks
|
||||
CheckKind::NoEval => "No builtin `eval()` allowed".to_string(),
|
||||
// Ruff
|
||||
CheckKind::AmbiguousUnicodeCharacterString(confusable, representant) => {
|
||||
format!(
|
||||
|
|
|
@ -278,6 +278,10 @@ pub enum CheckCodePrefix {
|
|||
N816,
|
||||
N817,
|
||||
N818,
|
||||
PGH,
|
||||
PGH0,
|
||||
PGH00,
|
||||
PGH001,
|
||||
PLE,
|
||||
PLE1,
|
||||
PLE11,
|
||||
|
@ -1148,6 +1152,10 @@ impl CheckCodePrefix {
|
|||
CheckCodePrefix::N816 => vec![CheckCode::N816],
|
||||
CheckCodePrefix::N817 => vec![CheckCode::N817],
|
||||
CheckCodePrefix::N818 => vec![CheckCode::N818],
|
||||
CheckCodePrefix::PGH => vec![CheckCode::PGH001],
|
||||
CheckCodePrefix::PGH0 => vec![CheckCode::PGH001],
|
||||
CheckCodePrefix::PGH00 => vec![CheckCode::PGH001],
|
||||
CheckCodePrefix::PGH001 => vec![CheckCode::PGH001],
|
||||
CheckCodePrefix::PLE => vec![CheckCode::PLE1142],
|
||||
CheckCodePrefix::PLE1 => vec![CheckCode::PLE1142],
|
||||
CheckCodePrefix::PLE11 => vec![CheckCode::PLE1142],
|
||||
|
@ -1615,6 +1623,10 @@ impl CheckCodePrefix {
|
|||
CheckCodePrefix::N816 => SuffixLength::Three,
|
||||
CheckCodePrefix::N817 => SuffixLength::Three,
|
||||
CheckCodePrefix::N818 => SuffixLength::Three,
|
||||
CheckCodePrefix::PGH => SuffixLength::Zero,
|
||||
CheckCodePrefix::PGH0 => SuffixLength::One,
|
||||
CheckCodePrefix::PGH00 => SuffixLength::Two,
|
||||
CheckCodePrefix::PGH001 => SuffixLength::Three,
|
||||
CheckCodePrefix::PLE => SuffixLength::Zero,
|
||||
CheckCodePrefix::PLE1 => SuffixLength::One,
|
||||
CheckCodePrefix::PLE11 => SuffixLength::Two,
|
||||
|
@ -1713,6 +1725,7 @@ pub const CATEGORIES: &[CheckCodePrefix] = &[
|
|||
CheckCodePrefix::I,
|
||||
CheckCodePrefix::M,
|
||||
CheckCodePrefix::N,
|
||||
CheckCodePrefix::PGH,
|
||||
CheckCodePrefix::PLE,
|
||||
CheckCodePrefix::Q,
|
||||
CheckCodePrefix::RUF,
|
||||
|
|
|
@ -65,6 +65,7 @@ pub mod printer;
|
|||
mod pycodestyle;
|
||||
mod pydocstyle;
|
||||
mod pyflakes;
|
||||
mod pygrep_hooks;
|
||||
mod pylint;
|
||||
mod python;
|
||||
mod pyupgrade;
|
||||
|
|
15
src/pygrep_hooks/checks.rs
Normal file
15
src/pygrep_hooks/checks.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
use rustpython_ast::{Expr, ExprKind};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::check_ast::Checker;
|
||||
use crate::checks::{Check, CheckKind};
|
||||
|
||||
pub fn no_eval(checker: &mut Checker, func: &Expr) {
|
||||
if let ExprKind::Name { id, .. } = &func.node {
|
||||
if id == "eval" {
|
||||
if checker.is_builtin("eval") {
|
||||
checker.add_check(Check::new(CheckKind::NoEval, Range::from_located(func)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
30
src/pygrep_hooks/mod.rs
Normal file
30
src/pygrep_hooks/mod.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
pub mod checks;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::convert::AsRef;
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Result;
|
||||
use test_case::test_case;
|
||||
|
||||
use crate::checks::CheckCode;
|
||||
use crate::linter::test_path;
|
||||
use crate::settings;
|
||||
|
||||
#[test_case(CheckCode::PGH001, Path::new("PGH001_0.py"); "PGH001_0")]
|
||||
#[test_case(CheckCode::PGH001, Path::new("PGH001_1.py"); "PGH001_1")]
|
||||
fn checks(check_code: CheckCode, path: &Path) -> Result<()> {
|
||||
let snapshot = format!("{}_{}", check_code.as_ref(), path.to_string_lossy());
|
||||
let mut checks = test_path(
|
||||
Path::new("./resources/test/fixtures/pygrep-hooks")
|
||||
.join(path)
|
||||
.as_path(),
|
||||
&settings::Settings::for_rule(check_code),
|
||||
true,
|
||||
)?;
|
||||
checks.sort_by_key(|check| check.location);
|
||||
insta::assert_yaml_snapshot!(snapshot, checks);
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
source: src/pygrep_hooks/mod.rs
|
||||
expression: checks
|
||||
---
|
||||
- kind: NoEval
|
||||
location:
|
||||
row: 3
|
||||
column: 0
|
||||
end_location:
|
||||
row: 3
|
||||
column: 4
|
||||
fix: ~
|
||||
- kind: NoEval
|
||||
location:
|
||||
row: 9
|
||||
column: 4
|
||||
end_location:
|
||||
row: 9
|
||||
column: 8
|
||||
fix: ~
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
source: src/pygrep_hooks/mod.rs
|
||||
expression: checks
|
||||
---
|
||||
[]
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue