Allow unused arguments for empty methods with docstrings (#1742)

Resolves #1741.
This commit is contained in:
Charlie Marsh 2023-01-09 00:34:07 -05:00 committed by GitHub
parent fe4eb13601
commit f18078a1eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 83 additions and 11 deletions

View File

@ -77,6 +77,34 @@ class C:
def f(x):
...
def f(self, x):
"""Docstring."""
def f(self, x):
"""Docstring."""
...
def f(self, x):
pass
def f(self, x):
raise NotImplementedError
def f(self, x):
raise NotImplementedError()
def f(self, x):
raise NotImplementedError("...")
def f(self, x):
raise NotImplemented
def f(self, x):
raise NotImplemented()
def f(self, x):
raise NotImplemented("...")
###
# Unused functions attached to abstract methods (OK).
###

View File

@ -1,19 +1,63 @@
use rustpython_ast::{Constant, ExprKind, Stmt, StmtKind};
/// Return `true` if a `Stmt` is a docstring.
fn is_docstring_stmt(stmt: &Stmt) -> bool {
if let StmtKind::Expr { value } = &stmt.node {
matches!(
value.node,
ExprKind::Constant {
value: Constant::Str { .. },
..
}
)
} else {
false
}
}
/// Return `true` if a `Stmt` is a "empty": a `pass`, `...`, `raise
/// NotImplementedError`, or `raise NotImplemented` (with or without arguments).
fn is_empty_stmt(stmt: &Stmt) -> bool {
match &stmt.node {
StmtKind::Pass => return true,
StmtKind::Expr { value } => {
return matches!(
value.node,
ExprKind::Constant {
value: Constant::Ellipsis,
..
}
)
}
StmtKind::Raise { exc, cause } => {
if cause.is_none() {
if let Some(exc) = exc {
match &exc.node {
ExprKind::Name { id, .. } => {
return id.as_str() == "NotImplementedError"
|| id.as_str() == "NotImplemented";
}
ExprKind::Call { func, .. } => {
if let ExprKind::Name { id, .. } = &func.node {
return id.as_str() == "NotImplementedError"
|| id.as_str() == "NotImplemented";
}
}
_ => {}
}
}
}
}
_ => {}
}
false
}
pub fn is_empty(body: &[Stmt]) -> bool {
match &body {
[] => true,
// Also allow: raise NotImplementedError, raise NotImplemented
[stmt] => match &stmt.node {
StmtKind::Pass => true,
StmtKind::Expr { value } => match &value.node {
ExprKind::Constant { value, .. } => {
matches!(value, Constant::Str(_) | Constant::Ellipsis)
}
_ => false,
},
_ => false,
},
[stmt] => is_docstring_stmt(stmt) || is_empty_stmt(stmt),
[docstring, stmt] => is_docstring_stmt(docstring) && is_empty_stmt(stmt),
_ => false,
}
}