Skip to content

Commit c55b098

Browse files
authored
Merge pull request #13819 from yoff/python/relax-module-resolution
Python: Relax module resolution
2 parents 365b101 + 6614e03 commit c55b098

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Support analyzing packages (folders with python code) that do not have `__init__.py` files, although this is technically required, we see real world projects that don't have this.

python/ql/lib/semmle/python/Module.qll

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,22 @@ private predicate isPotentialPackage(Folder f) {
195195
}
196196

197197
private string moduleNameFromBase(Container file) {
198-
isPotentialPackage(file) and result = file.getBaseName()
198+
// We used to also require `isPotentialPackage(f)` to hold in this case,
199+
// but we saw modules not getting resolved because their folder did not
200+
// contain an `__init__.py` file.
201+
//
202+
// This makes the folder not be a package but a namespace package instead.
203+
// In most cases this is a mistake :| See following links for more details
204+
// - https://dev.to/methane/don-t-omit-init-py-3hga
205+
// - https://packaging.python.org/en/latest/guides/packaging-namespace-packages/
206+
// - https://discuss.python.org/t/init-py-pep-420-and-iter-modules-confusion/9642
207+
//
208+
// It is possible that we can keep the original requirement on
209+
// `isPotentialPackage(f)` here, but relax `isPotentialPackage` itself to allow
210+
// for this behavior of missing `__init__.py` files. However, doing so involves
211+
// cascading changes (for example to `moduleNameFromFile`), and was a more involved
212+
// task than we wanted to take on.
213+
result = file.getBaseName()
199214
or
200215
file instanceof File and result = file.getStem()
201216
}

python/ql/test/experimental/library-tests/CallGraph-implicit-init/example.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@
1717
from foo.bar.a import afunc
1818
from foo_explicit.bar.a import explicit_afunc
1919

20-
afunc() # $ MISSING: pt,tt=afunc
20+
afunc() # $ pt,tt="foo/bar/a.py:afunc"
2121

2222
explicit_afunc() # $ pt,tt="foo_explicit/bar/a.py:explicit_afunc"

0 commit comments

Comments
 (0)