Merge pull request #6312 from tausbn/python-deprecate-importnode

Python: Deprecate `importNode`
This commit is contained in:
Rasmus Wriedt Larsen
2021-09-10 13:12:56 +02:00
committed by GitHub
20 changed files with 15 additions and 82 deletions

View File

@@ -18,6 +18,10 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) { simpleLocalFlowStep(nodeFr
predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) }
/**
* DEPRECATED. Use the API graphs library (`semmle.python.ApiGraphs`) instead.
*
* For a drop-in replacement, use `API::moduleImport(name).getAUse()`.
*
* Gets a `Node` that refers to the module referenced by `name`.
* Note that for the statement `import pkg.mod`, the new variable introduced is `pkg` that is a
* reference to the module `pkg`.
@@ -37,7 +41,7 @@ predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) }
* `mypkg/foo.py` but the variable `foo` containing `42` -- however, `import mypkg.foo` will always cause `mypkg.foo`
* to refer to the module.
*/
Node importNode(string name) {
deprecated Node importNode(string name) {
exists(Variable var, Import imp, Alias alias |
alias = imp.getAName() and
alias.getAsname() = var.getAStore() and

View File

@@ -1,23 +0,0 @@
| test1.py:1:8:1:12 | ControlFlowNode for ImportExpr | mypkg |
| test2.py:1:6:1:10 | ControlFlowNode for ImportExpr | mypkg |
| test2.py:1:6:1:10 | ControlFlowNode for ImportExpr | mypkg |
| test2.py:1:19:1:21 | ControlFlowNode for ImportMember | mypkg.foo |
| test2.py:1:24:1:26 | ControlFlowNode for ImportMember | mypkg.bar |
| test3.py:1:8:1:16 | ControlFlowNode for ImportExpr | mypkg |
| test3.py:2:8:2:16 | ControlFlowNode for ImportExpr | mypkg |
| test4.py:1:8:1:16 | ControlFlowNode for ImportExpr | mypkg.foo |
| test4.py:2:8:2:16 | ControlFlowNode for ImportExpr | mypkg.bar |
| test5.py:1:8:1:12 | ControlFlowNode for ImportExpr | mypkg |
| test5.py:9:6:9:10 | ControlFlowNode for ImportExpr | mypkg |
| test5.py:9:19:9:29 | ControlFlowNode for ImportMember | mypkg.bar |
| test6.py:1:8:1:12 | ControlFlowNode for ImportExpr | mypkg |
| test6.py:5:8:5:16 | ControlFlowNode for ImportExpr | mypkg |
| test7.py:1:6:1:10 | ControlFlowNode for ImportExpr | mypkg |
| test7.py:1:19:1:21 | ControlFlowNode for ImportMember | mypkg.foo |
| test7.py:5:8:5:16 | ControlFlowNode for ImportExpr | mypkg |
| test7.py:9:6:9:10 | ControlFlowNode for ImportExpr | mypkg |
| test7.py:9:19:9:21 | ControlFlowNode for ImportMember | mypkg.foo |
| test_deep.py:1:6:1:21 | ControlFlowNode for ImportExpr | start.middle.end |
| test_deep.py:1:6:1:21 | ControlFlowNode for ImportExpr | start.middle.end |
| test_deep.py:1:30:1:32 | ControlFlowNode for ImportMember | start.middle.end.foo |
| test_deep.py:1:35:1:37 | ControlFlowNode for ImportMember | start.middle.end.bar |

View File

@@ -1,4 +0,0 @@
import python
import semmle.python.dataflow.new.DataFlow
query predicate importNode(DataFlow::Node res, string name) { res = DataFlow::importNode(name) }

View File

@@ -1 +0,0 @@
Small tests that explore difference between `import mypkg.foo` and `from mypkg import foo`.

View File

@@ -1,6 +0,0 @@
import mypkg
print(mypkg.foo) # 42
try:
print(mypkg.bar)
except AttributeError as e:
print(e) # module 'mypkg' has no attribute 'bar'

View File

@@ -1,3 +0,0 @@
from mypkg import foo, bar
print(foo)
print(bar)

View File

@@ -1,4 +0,0 @@
import mypkg.foo
import mypkg.bar
print(mypkg.foo) # <module 'mypkg.foo' ...
print(mypkg.bar) # <module 'mypkg.bar' ...

View File

@@ -1,4 +0,0 @@
import mypkg.foo as _foo
import mypkg.bar as _bar
print(_foo) # <module 'mypkg.foo' ...
print(_bar) # <module 'mypkg.bar' ...

View File

@@ -1,10 +0,0 @@
import mypkg
print(mypkg.foo) # 42
try:
print(mypkg.bar)
except AttributeError as e:
print(e) # module 'mypkg' has no attribute 'bar'
from mypkg import bar as _bar
print(mypkg.bar) # <module 'mypkg.bar' ...

View File

@@ -1,6 +0,0 @@
import mypkg
print(mypkg.foo) # 42
import mypkg.foo
print(mypkg.foo) # <module 'mypkg.foo' ...

View File

@@ -1,10 +0,0 @@
from mypkg import foo
print(foo) # 42
import mypkg.foo
print(foo) # 42
print(mypkg.foo) # <module 'mypkg.foo' ...
from mypkg import foo
print(foo) # <module 'mypkg.foo' ...

View File

@@ -1,3 +0,0 @@
from start.middle.end import foo, bar
print(foo)
print(bar)

View File

@@ -1,10 +1,11 @@
import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TypeTracker
import semmle.python.ApiGraphs
private DataFlow::TypeTrackingNode module_tracker(TypeTracker t) {
t.start() and
result = DataFlow::importNode("module")
result = API::moduleImport("module").getAUse()
or
exists(TypeTracker t2 | result = module_tracker(t2).track(t2, t))
}

View File

@@ -2,6 +2,7 @@ import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TypeTracker
import TestUtilities.InlineExpectationsTest
import semmle.python.ApiGraphs
// -----------------------------------------------------------------------------
// tracked
@@ -119,7 +120,7 @@ class TrackedSelfTest extends InlineExpectationsTest {
/** Gets a reference to `foo` (fictive module). */
private DataFlow::TypeTrackingNode foo(DataFlow::TypeTracker t) {
t.start() and
result = DataFlow::importNode("foo")
result = API::moduleImport("foo").getAUse()
or
exists(DataFlow::TypeTracker t2 | result = foo(t2).track(t2, t))
}
@@ -130,7 +131,7 @@ DataFlow::Node foo() { foo(DataFlow::TypeTracker::end()).flowsTo(result) }
/** Gets a reference to `foo.bar` (fictive module). */
private DataFlow::TypeTrackingNode foo_bar(DataFlow::TypeTracker t) {
t.start() and
result = DataFlow::importNode("foo.bar")
result = API::moduleImport("foo.bar").getAUse()
or
t.startInAttr("bar") and
result = foo()
@@ -144,7 +145,7 @@ DataFlow::Node foo_bar() { foo_bar(DataFlow::TypeTracker::end()).flowsTo(result)
/** Gets a reference to `foo.bar.baz` (fictive attribute on `foo.bar` module). */
private DataFlow::TypeTrackingNode foo_bar_baz(DataFlow::TypeTracker t) {
t.start() and
result = DataFlow::importNode("foo.bar.baz")
result = API::moduleImport("foo.bar.baz").getAUse()
or
t.startInAttr("baz") and
result = foo_bar()