Python: Add test for overloaded __init__ resolution

Adds a test showing that `@typing.overload` stubs are spuriously
resolved as call targets alongside the actual `__init__` implementation.
This commit is contained in:
Taus
2026-03-05 16:16:33 +00:00
parent c9fa7fa283
commit 0561a63003
3 changed files with 65 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
/**
* Test that `@typing.overload` stubs are not resolved as call targets.
*/
import python
import semmle.python.dataflow.new.internal.DataFlowDispatch as DataFlowDispatch
import utils.test.InlineExpectationsTest
module OverloadCallTest implements TestSig {
string getARelevantTag() { result = "init" }
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(DataFlowDispatch::DataFlowCall call, Function target |
location = call.getLocation() and
element = call.toString() and
DataFlowDispatch::resolveCall(call.getNode(), target, _) and
target.getName() = "__init__"
|
value = target.getQualifiedName() + ":" + target.getLocation().getStartLine().toString() and
tag = "init"
)
}
}
import MakeTest<OverloadCallTest>

View File

@@ -0,0 +1,39 @@
import typing
class OverloadedInit:
@typing.overload
def __init__(self, x: int) -> None: ...
@typing.overload
def __init__(self, x: str, y: str) -> None: ...
def __init__(self, x, y=None):
pass
OverloadedInit(1) # $ init=OverloadedInit.__init__:11 SPURIOUS: init=OverloadedInit.__init__:6 init=OverloadedInit.__init__:9
OverloadedInit("a", "b") # $ init=OverloadedInit.__init__:11 SPURIOUS: init=OverloadedInit.__init__:6 init=OverloadedInit.__init__:9
from typing import overload
class OverloadedInitFromImport:
@overload
def __init__(self, x: int) -> None: ...
@overload
def __init__(self, x: str, y: str) -> None: ...
def __init__(self, x, y=None):
pass
OverloadedInitFromImport(1) # $ init=OverloadedInitFromImport.__init__:28 SPURIOUS: init=OverloadedInitFromImport.__init__:23 init=OverloadedInitFromImport.__init__:26
OverloadedInitFromImport("a", "b") # $ init=OverloadedInitFromImport.__init__:28 SPURIOUS: init=OverloadedInitFromImport.__init__:23 init=OverloadedInitFromImport.__init__:26
class NoOverloads:
def __init__(self, x):
pass
NoOverloads(1) # $ init=NoOverloads.__init__:36