File tree Expand file tree Collapse file tree 3 files changed +39
-12
lines changed
lib/semmle/python/dataflow/new/internal
test/query-tests/Imports/PyCheckerTests Expand file tree Collapse file tree 3 files changed +39
-12
lines changed Original file line number Diff line number Diff line change @@ -377,4 +377,30 @@ module ImportResolution {
377377 }
378378
379379 Module getModule ( DataFlow:: CfgNode node ) { node = getModuleReference ( result ) }
380+
381+ /** Holds if module `importer` directly imports module `imported`. */
382+ predicate imports ( Module importer , Module imported ) {
383+ getImmediateModuleReference ( imported ) .getScope ( ) = importer
384+ }
385+
386+ /**
387+ * Holds if the import statement `i` causes module `imported` to be imported.
388+ * For `from pkg import submodule`, both `pkg` and `pkg.submodule` are considered imported.
389+ */
390+ predicate importedBy ( ImportingStmt i , Module imported ) {
391+ exists ( Alias a | a = i .( Import ) .getAName ( ) |
392+ getImmediateModuleReference ( imported ) .asExpr ( ) = a .getAsname ( )
393+ )
394+ or
395+ exists ( ImportMember im | im = i .( Import ) .getAName ( ) .getValue ( ) |
396+ getImmediateModuleReference ( imported ) .asExpr ( ) = im .getModule ( )
397+ )
398+ or
399+ getImmediateModuleReference ( imported ) .asExpr ( ) = i .( ImportStar ) .getModule ( ) .( ImportExpr )
400+ }
401+
402+ /** Gets a user-friendly name for module `m`, using the package name for `__init__` modules. */
403+ string moduleName ( Module m ) {
404+ if m .isPackageInit ( ) then result = m .getPackageName ( ) else result = m .getName ( )
405+ }
380406}
Original file line number Diff line number Diff line change 1212 */
1313
1414import python
15- private import LegacyPointsTo
15+ import semmle.python.dataflow.new.DataFlow
16+ private import semmle.python.dataflow.new.internal.ImportResolution
1617
17- predicate modules_imports_itself ( ImportingStmt i , ModuleValue m ) {
18- i .getEnclosingModule ( ) = m .getScope ( ) and
19- m =
20- max ( string s , ModuleValue m_ |
21- s = i .getAnImportedModuleName ( ) and
22- m_ .importedAs ( s )
23- |
24- m_ order by s .length ( )
25- )
18+ predicate modules_imports_itself ( ImportingStmt i , Module m ) {
19+ m = i .getEnclosingModule ( ) and
20+ ImportResolution:: importedBy ( i , m ) and
21+ // Exclude `from m import submodule` where the imported member is a submodule of m
22+ not exists ( ImportMember im | im = i .( Import ) .getAName ( ) .getValue ( ) |
23+ ImportResolution:: getImmediateModuleReference ( m ) .asExpr ( ) = im .getModule ( ) and
24+ ImportResolution:: importedBy ( i , any ( Module sub | sub != m ) )
25+ )
2626}
2727
28- from ImportingStmt i , ModuleValue m
28+ from ImportingStmt i , Module m
2929where modules_imports_itself ( i , m )
30- select i , "The module '" + m . getName ( ) + "' imports itself."
30+ select i , "The module '" + ImportResolution :: moduleName ( m ) + "' imports itself."
Original file line number Diff line number Diff line change 11| imports_test.py:8:1:8:19 | Import | The module 'imports_test' imports itself. |
22| pkg_notok/__init__.py:4:1:4:16 | Import | The module 'pkg_notok' imports itself. |
3+ | pkg_notok/__init__.py:10:1:10:20 | Import | The module 'pkg_notok' imports itself. |
34| pkg_notok/__init__.py:12:1:12:25 | Import | The module 'pkg_notok' imports itself. |
45| pkg_notok/__init__.py:13:1:13:37 | Import | The module 'pkg_notok' imports itself. |
56| pkg_notok/__init__.py:14:1:14:23 | from pkg_notok import * | The module 'pkg_notok' imports itself. |
You can’t perform that action at this time.
0 commit comments