Use ruff_python_semantic abstract utility in flake8-pytest-style (#4299)

This commit is contained in:
Charlie Marsh
2023-05-08 22:12:28 -04:00
committed by GitHub
parent d365dab904
commit 8be51942dd
4 changed files with 23 additions and 48 deletions

View File

@@ -19,7 +19,7 @@ impl Violation for PytestFailWithoutMessage {
}
pub fn fail_call(checker: &mut Checker, func: &Expr, args: &[Expr], keywords: &[Keyword]) {
if is_pytest_fail(func, checker) {
if is_pytest_fail(&checker.ctx, func) {
let call_args = SimpleCallArgs::new(args, keywords);
let msg = call_args.argument("msg", 0);

View File

@@ -10,14 +10,15 @@ use ruff_python_ast::helpers::collect_arg_names;
use ruff_python_ast::source_code::Locator;
use ruff_python_ast::visitor::Visitor;
use ruff_python_ast::{helpers, visitor};
use ruff_python_semantic::analyze::visibility::is_abstract;
use ruff_python_semantic::context::Context;
use crate::autofix::actions::remove_argument;
use crate::checkers::ast::Checker;
use crate::registry::{AsRule, Rule};
use super::helpers::{
get_mark_decorators, is_abstractmethod_decorator, is_pytest_fixture, is_pytest_yield_fixture,
keyword_is_literal,
get_mark_decorators, is_pytest_fixture, is_pytest_yield_fixture, keyword_is_literal,
};
#[violation]
@@ -224,18 +225,12 @@ where
}
}
fn get_fixture_decorator<'a>(checker: &Checker, decorators: &'a [Expr]) -> Option<&'a Expr> {
fn get_fixture_decorator<'a>(context: &Context, decorators: &'a [Expr]) -> Option<&'a Expr> {
decorators.iter().find(|decorator| {
is_pytest_fixture(decorator, checker) || is_pytest_yield_fixture(decorator, checker)
is_pytest_fixture(context, decorator) || is_pytest_yield_fixture(context, decorator)
})
}
fn has_abstractmethod_decorator(decorators: &[Expr], checker: &Checker) -> bool {
decorators
.iter()
.any(|decorator| is_abstractmethod_decorator(decorator, checker))
}
fn pytest_fixture_parentheses(
checker: &mut Checker,
decorator: &Expr,
@@ -429,7 +424,7 @@ fn check_test_function_args(checker: &mut Checker, args: &Arguments) {
/// PT020
fn check_fixture_decorator_name(checker: &mut Checker, decorator: &Expr) {
if is_pytest_yield_fixture(decorator, checker) {
if is_pytest_yield_fixture(&checker.ctx, decorator) {
checker.diagnostics.push(Diagnostic::new(
PytestDeprecatedYieldFixture,
decorator.range(),
@@ -503,7 +498,7 @@ pub fn fixture(
decorators: &[Expr],
body: &[Stmt],
) {
let decorator = get_fixture_decorator(checker, decorators);
let decorator = get_fixture_decorator(&checker.ctx, decorators);
if let Some(decorator) = decorator {
if checker
.settings
@@ -542,7 +537,7 @@ pub fn fixture(
.settings
.rules
.enabled(Rule::PytestUselessYieldFixture))
&& !has_abstractmethod_decorator(decorators, checker)
&& !is_abstract(&checker.ctx, decorators)
{
check_fixture_returns(checker, stmt, name, body);
}

View File

@@ -1,9 +1,8 @@
use ruff_python_ast::call_path::{collect_call_path, CallPath};
use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword};
use ruff_python_ast::call_path::{collect_call_path, CallPath};
use ruff_python_ast::helpers::map_callable;
use crate::checkers::ast::Checker;
use ruff_python_semantic::context::Context;
pub(super) fn get_mark_decorators(decorators: &[Expr]) -> impl Iterator<Item = (&Expr, CallPath)> {
decorators.iter().filter_map(|decorator| {
@@ -18,49 +17,30 @@ pub(super) fn get_mark_decorators(decorators: &[Expr]) -> impl Iterator<Item = (
})
}
pub(super) fn is_pytest_fail(call: &Expr, checker: &Checker) -> bool {
checker
.ctx
.resolve_call_path(call)
.map_or(false, |call_path| {
call_path.as_slice() == ["pytest", "fail"]
})
pub(super) fn is_pytest_fail(context: &Context, call: &Expr) -> bool {
context.resolve_call_path(call).map_or(false, |call_path| {
call_path.as_slice() == ["pytest", "fail"]
})
}
pub(super) fn is_pytest_fixture(decorator: &Expr, checker: &Checker) -> bool {
checker
.ctx
.resolve_call_path(if let ExprKind::Call { func, .. } = &decorator.node {
func
} else {
decorator
})
pub(super) fn is_pytest_fixture(context: &Context, decorator: &Expr) -> bool {
context
.resolve_call_path(map_callable(decorator))
.map_or(false, |call_path| {
call_path.as_slice() == ["pytest", "fixture"]
})
}
pub(super) fn is_pytest_yield_fixture(decorator: &Expr, checker: &Checker) -> bool {
checker
.ctx
pub(super) fn is_pytest_yield_fixture(context: &Context, decorator: &Expr) -> bool {
context
.resolve_call_path(map_callable(decorator))
.map_or(false, |call_path| {
call_path.as_slice() == ["pytest", "yield_fixture"]
})
}
pub(super) fn is_abstractmethod_decorator(decorator: &Expr, checker: &Checker) -> bool {
checker
.ctx
.resolve_call_path(decorator)
.map_or(false, |call_path| {
call_path.as_slice() == ["abc", "abstractmethod"]
})
}
pub(super) fn is_pytest_parametrize(decorator: &Expr, checker: &Checker) -> bool {
checker
.ctx
pub(super) fn is_pytest_parametrize(context: &Context, decorator: &Expr) -> bool {
context
.resolve_call_path(map_callable(decorator))
.map_or(false, |call_path| {
call_path.as_slice() == ["pytest", "mark", "parametrize"]

View File

@@ -417,7 +417,7 @@ fn handle_value_rows(
pub fn parametrize(checker: &mut Checker, decorators: &[Expr]) {
for decorator in decorators {
if is_pytest_parametrize(decorator, checker) {
if is_pytest_parametrize(&checker.ctx, decorator) {
if let ExprKind::Call { args, .. } = &decorator.node {
if checker
.settings