diff --git a/python/ql/lib/semmle/python/objects/TObject.qll b/python/ql/lib/semmle/python/objects/TObject.qll index dd191467c19f..a6214e1a7aa9 100644 --- a/python/ql/lib/semmle/python/objects/TObject.qll +++ b/python/ql/lib/semmle/python/objects/TObject.qll @@ -216,7 +216,9 @@ private predicate scope_loads_tuplenode(Scope s, TupleNode origin) { predicate isType(ObjectInternal t) { t.isClass() = true or - t.getOrigin().getEnclosingModule().getName().matches("%typing") + exists(string name | name = t.getOrigin().getEnclosingModule().getName() | + name = "typing" or name = "typing_extensions" or name.matches("typing.%") + ) } private predicate is_power_2(int n) { diff --git a/python/ql/test/library-tests/PointsTo/regressions/typing-filename/Test.expected b/python/ql/test/library-tests/PointsTo/regressions/typing-filename/Test.expected new file mode 100644 index 000000000000..277ed0f0add6 --- /dev/null +++ b/python/ql/test/library-tests/PointsTo/regressions/typing-filename/Test.expected @@ -0,0 +1 @@ +| main.py:6:1:6:13 | ControlFlowNode for InTyping() | resolved: InTyping() | diff --git a/python/ql/test/library-tests/PointsTo/regressions/typing-filename/Test.ql b/python/ql/test/library-tests/PointsTo/regressions/typing-filename/Test.ql new file mode 100644 index 000000000000..d3245a7d5180 --- /dev/null +++ b/python/ql/test/library-tests/PointsTo/regressions/typing-filename/Test.ql @@ -0,0 +1,12 @@ +import python +private import LegacyPointsTo + +from ControlFlowNodeWithPointsTo use, string outcome +where + exists(CallNode call | call.getFunction().(NameNode).getId() = "InTyping" and use = call) and + ( + if exists(use.pointsTo()) + then outcome = "resolved: " + use.pointsTo().toString() + else outcome = "no points-to info" + ) +select use, outcome \ No newline at end of file diff --git a/python/ql/test/library-tests/PointsTo/regressions/typing-filename/main.py b/python/ql/test/library-tests/PointsTo/regressions/typing-filename/main.py new file mode 100644 index 000000000000..9a750dcda609 --- /dev/null +++ b/python/ql/test/library-tests/PointsTo/regressions/typing-filename/main.py @@ -0,0 +1,10 @@ +from typing import Optional + +from pkg.other import InOther +from pkg.typing import InTyping + +InTyping("a") +Optional[InTyping] + +InOther("b") +Optional[InOther] \ No newline at end of file diff --git a/python/ql/test/library-tests/PointsTo/regressions/typing-filename/pkg/__init__.py b/python/ql/test/library-tests/PointsTo/regressions/typing-filename/pkg/__init__.py new file mode 100644 index 000000000000..a22bbb470645 --- /dev/null +++ b/python/ql/test/library-tests/PointsTo/regressions/typing-filename/pkg/__init__.py @@ -0,0 +1,15 @@ +registry = {} + + +def make_type(name): + if name in registry: + return registry[name] + + class Created(str): + pass + + registry[name] = Created + return Created + + +InTyping = make_type("InTyping") \ No newline at end of file diff --git a/python/ql/test/library-tests/PointsTo/regressions/typing-filename/pkg/other.py b/python/ql/test/library-tests/PointsTo/regressions/typing-filename/pkg/other.py new file mode 100644 index 000000000000..42cf36016a09 --- /dev/null +++ b/python/ql/test/library-tests/PointsTo/regressions/typing-filename/pkg/other.py @@ -0,0 +1,15 @@ +registry = {} + + +def make_type(name): + if name in registry: + return registry[name] + + class Created(str): + pass + + registry[name] = Created + return Created + + +InOther = make_type("InOther") \ No newline at end of file diff --git a/python/ql/test/library-tests/PointsTo/regressions/typing-filename/pkg/typing.py b/python/ql/test/library-tests/PointsTo/regressions/typing-filename/pkg/typing.py new file mode 100644 index 000000000000..a22bbb470645 --- /dev/null +++ b/python/ql/test/library-tests/PointsTo/regressions/typing-filename/pkg/typing.py @@ -0,0 +1,15 @@ +registry = {} + + +def make_type(name): + if name in registry: + return registry[name] + + class Created(str): + pass + + registry[name] = Created + return Created + + +InTyping = make_type("InTyping") \ No newline at end of file