PY-80627 At least two @overload-decorated definitions must be present

GitOrigin-RevId: c40090f12631d61cfbb151f52cf709a8a2cd2383
This commit is contained in:
Petr
2025-05-15 19:58:11 +02:00
committed by intellij-monorepo-bot
parent 8abfc73b15
commit 58cd6bb893
4 changed files with 55 additions and 6 deletions

View File

@@ -1047,6 +1047,8 @@ INSP.overloads.series.overload.decorated.methods.should.always.be.followed.by.im
INSP.overloads.series.overload.decorated.functions.should.always.be.followed.by.implementation=A series of @overload-decorated functions should always be followed by an implementation that is not @overload-ed
INSP.overloads.this.method.overload.signature.not.compatible.with.implementation=Signature of this @overload-decorated method is not compatible with the implementation
INSP.overloads.this.function.overload.signature.not.compatible.with.implementation=Signature of this @overload-decorated function is not compatible with the implementation
INSP.overloads.at.least.two.overload.decorated.methods.must.be.present=At least two @overload-decorated methods must be present
INSP.overloads.at.least.two.overload.decorated.functions.must.be.present=At least two @overload-decorated functions must be present
# PyOverridesInspection
INSP.NAME.invalid.usages.of.override.decorator=Invalid usages of @override decorator

View File

@@ -55,6 +55,15 @@ class PyOverloadsInspection : PyInspection() {
if (overloads.isEmpty()) return
if (overloads.size == 1) {
registerProblem(overloads[0].nameIdentifier, if (owner is PyClass) {
PyPsiBundle.message("INSP.overloads.at.least.two.overload.decorated.methods.must.be.present")
}
else {
PyPsiBundle.message("INSP.overloads.at.least.two.overload.decorated.functions.must.be.present")
})
}
var requiresImplementation = true
if (owner is PyClass) {
if (isProtocol(owner, myTypeEvalContext)) {

View File

@@ -0,0 +1,40 @@
from typing import overload
@overload
def <warning descr="At least two @overload-decorated functions must be present">foo</warning>() -> None: ...
def foo() -> None:
pass
class A:
@overload
def <warning descr="At least two @overload-decorated methods must be present">foo</warning>() -> None: ...
def foo() -> None:
pass
@overload
def bar(x: int) -> None: ...
@overload
def bar(x: str) -> None: ...
def bar(x: int | str) -> None:
pass
class B:
@overload
def bar(x: int) -> None: ...
@overload
def bar(x: str) -> None: ...
def bar(x: int | str) -> None:
pass

View File

@@ -16,7 +16,6 @@
package com.jetbrains.python.inspections;
import com.jetbrains.python.fixtures.PyInspectionTestCase;
import com.jetbrains.python.psi.LanguageLevel;
import org.jetbrains.annotations.NotNull;
public class PyOverloadsInspectionTest extends PyInspectionTestCase {
@@ -41,14 +40,13 @@ public class PyOverloadsInspectionTest extends PyInspectionTestCase {
doTest();
}
public void testSingleOverload() {
doTest();
}
@NotNull
@Override
protected Class<? extends PyInspection> getInspectionClass() {
return PyOverloadsInspection.class;
}
@Override
protected void doTest() {
runWithLanguageLevel(LanguageLevel.PYTHON35, () -> super.doTest());
}
}