Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions python/ql/src/semmle/python/Module.qll
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ class Module extends Module_, Scope, AstNode {

}


bindingset[name]
private predicate legalDottedName(string name) {
name.regexpMatch("(\\p{L}|_)(\\p{L}|\\d|_)*(\\.(\\p{L}|_)(\\p{L}|\\d|_)*)*")
Expand Down Expand Up @@ -244,3 +245,30 @@ private predicate isStubRoot(Folder f) {
f.getAbsolutePath().matches("%/data/python/stubs")
}


/** Holds if the Container `c` should be the preferred file or folder for
* the given name when performing imports.
* Trivially true for any container if it is the only one with its name.
* However, if there are several modules with the same name, then
* this is the module most likely to be imported under that name.
*/
predicate isPreferredModuleForName(Container c, string name) {
exists(int p |
p = min(int x | x = priorityForName(_, name)) and
p = priorityForName(c, name)
)
}

private int priorityForName(Container c, string name) {
name = moduleNameFromFile(c) and
(
// In the source
exists(c.getRelativePath()) and result = -1
or
// On an import path
exists(c.getImportRoot(result))
or
// Otherwise
result = 10000
)
}
5 changes: 3 additions & 2 deletions python/ql/src/semmle/python/objects/TObject.qll
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,13 @@ cached newtype TObject =
or
/* Package objects */
TPackageObject(Folder f) {
exists(moduleNameFromFile(f))
isPreferredModuleForName(f, _)
}
or
/* Python module objects */
TPythonModule(Module m) {
not m.isPackage() and not exists(SyntaxError se | se.getFile() = m.getFile())
not m.isPackage() and isPreferredModuleForName(m.getFile(), _) and
not exists(SyntaxError se | se.getFile() = m.getFile())
}
or
/* `True` */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
| sqlite3 | 2 | 1 |
| sqlite3.__init__ | 2 | 1 |
| sqlite3.dump | 2 | 1 |
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

import python

from string name, int mcnt
where mcnt = strictcount(Module m | m.getName() = name) and mcnt > 1
select name, mcnt, strictcount(ModuleValue val | val.getName() = name)

2 changes: 2 additions & 0 deletions python/ql/test/library-tests/modules/duplicate_name/options
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
semmle-extractor-options: -R .
optimize: true
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import sqlite3.dump
Empty file.