From 4289e358bf0883e7fe0f40cbf82f6f4fe2e2a617 Mon Sep 17 00:00:00 2001 From: Taus Brock-Nannestad Date: Tue, 23 Mar 2021 18:13:20 +0100 Subject: [PATCH 1/5] Python: Add module import test case This one will require some explanation... First, the file structure. This commit adds a test consisting representing a few different kinds of imports. - Absolute imports, from `module.py` to `main.py` when the latter is executed directly. - A package (contained in the `package` folder) - A namespace package (contained in the `namespace_package` folder) All of these are inside a folder called `code` for reasons I will detail later. The file `main.py` is identified as a script, by the presence of the `!#` comment in its first line. The files themselves are executable, and `python3 main.py` will print out all modules in the order they are imported. The test itself is very simple. It simply lists all modules and their corresponding names. As is plainly visible, without modification we only pick up `package` and its component modules as having names. This is the bit that needs to be fixed. Convincing the test runner to extract this test in a way that mimics reality is, unfortunately, a bit complicated. By default, the test runner itself includes any Python files in the test directory as modules in the invocation of the extractor, and so we must hide everything in the `code` subdirectory. Secondly, a `--path` argument (set to the test directory) is automatically added, and this would also interfere with extraction, and hence we must prevent this. Luckily, if we supply our own `--path` argument -- even if it doesn't make any sense -- then the other argument is left out. Finally, we must actually tell the extractor to extract the files (or it would just happily pass the test with zero files extracted), so the `-R .` argument ensures that we recurse over the files in the test directory after all. --- .../test/3/library-tests/modules/entry_point/code/main.py | 7 +++++++ .../3/library-tests/modules/entry_point/code/module.py | 2 ++ .../code/namespace_package/namespace_package_main.py | 2 ++ .../code/namespace_package/namespace_package_module.py | 1 + .../modules/entry_point/code/package/__init__.py | 2 ++ .../modules/entry_point/code/package/package_main.py | 2 ++ .../modules/entry_point/code/package/package_module.py | 1 + .../3/library-tests/modules/entry_point/modules.expected | 4 ++++ .../ql/test/3/library-tests/modules/entry_point/modules.ql | 4 ++++ python/ql/test/3/library-tests/modules/entry_point/options | 1 + 10 files changed, 26 insertions(+) create mode 100755 python/ql/test/3/library-tests/modules/entry_point/code/main.py create mode 100644 python/ql/test/3/library-tests/modules/entry_point/code/module.py create mode 100644 python/ql/test/3/library-tests/modules/entry_point/code/namespace_package/namespace_package_main.py create mode 100644 python/ql/test/3/library-tests/modules/entry_point/code/namespace_package/namespace_package_module.py create mode 100644 python/ql/test/3/library-tests/modules/entry_point/code/package/__init__.py create mode 100644 python/ql/test/3/library-tests/modules/entry_point/code/package/package_main.py create mode 100644 python/ql/test/3/library-tests/modules/entry_point/code/package/package_module.py create mode 100644 python/ql/test/3/library-tests/modules/entry_point/modules.expected create mode 100644 python/ql/test/3/library-tests/modules/entry_point/modules.ql create mode 100644 python/ql/test/3/library-tests/modules/entry_point/options diff --git a/python/ql/test/3/library-tests/modules/entry_point/code/main.py b/python/ql/test/3/library-tests/modules/entry_point/code/main.py new file mode 100755 index 000000000000..ad619e5cbd83 --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/code/main.py @@ -0,0 +1,7 @@ +#! /usr/bin/python3 +print(__file__) +import module +import package +import namespace_package +import namespace_package.namespace_package_main +print(module.message) diff --git a/python/ql/test/3/library-tests/modules/entry_point/code/module.py b/python/ql/test/3/library-tests/modules/entry_point/code/module.py new file mode 100644 index 000000000000..36206ca60b75 --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/code/module.py @@ -0,0 +1,2 @@ +print(__file__.split("entry_point")[1]) +message = "Hello world!" diff --git a/python/ql/test/3/library-tests/modules/entry_point/code/namespace_package/namespace_package_main.py b/python/ql/test/3/library-tests/modules/entry_point/code/namespace_package/namespace_package_main.py new file mode 100644 index 000000000000..5db80f18a278 --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/code/namespace_package/namespace_package_main.py @@ -0,0 +1,2 @@ +print(__file__.split("entry_point")[1]) +import namespace_package.namespace_package_module diff --git a/python/ql/test/3/library-tests/modules/entry_point/code/namespace_package/namespace_package_module.py b/python/ql/test/3/library-tests/modules/entry_point/code/namespace_package/namespace_package_module.py new file mode 100644 index 000000000000..567a23d59ce3 --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/code/namespace_package/namespace_package_module.py @@ -0,0 +1 @@ +print(__file__.split("entry_point")[1]) diff --git a/python/ql/test/3/library-tests/modules/entry_point/code/package/__init__.py b/python/ql/test/3/library-tests/modules/entry_point/code/package/__init__.py new file mode 100644 index 000000000000..ca14a9f5804e --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/code/package/__init__.py @@ -0,0 +1,2 @@ +print(__file__.split("entry_point")[1]) +from . import package_main diff --git a/python/ql/test/3/library-tests/modules/entry_point/code/package/package_main.py b/python/ql/test/3/library-tests/modules/entry_point/code/package/package_main.py new file mode 100644 index 000000000000..158b12678e3b --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/code/package/package_main.py @@ -0,0 +1,2 @@ +print(__file__.split("entry_point")[1]) +from . import package_module diff --git a/python/ql/test/3/library-tests/modules/entry_point/code/package/package_module.py b/python/ql/test/3/library-tests/modules/entry_point/code/package/package_module.py new file mode 100644 index 000000000000..567a23d59ce3 --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/code/package/package_module.py @@ -0,0 +1 @@ +print(__file__.split("entry_point")[1]) diff --git a/python/ql/test/3/library-tests/modules/entry_point/modules.expected b/python/ql/test/3/library-tests/modules/entry_point/modules.expected new file mode 100644 index 000000000000..4ec912437826 --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/modules.expected @@ -0,0 +1,4 @@ +| package | code/package:0:0:0:0 | Package package | +| package.__init__ | code/package/__init__.py:0:0:0:0 | Module package.__init__ | +| package.package_main | code/package/package_main.py:0:0:0:0 | Module package.package_main | +| package.package_module | code/package/package_module.py:0:0:0:0 | Module package.package_module | diff --git a/python/ql/test/3/library-tests/modules/entry_point/modules.ql b/python/ql/test/3/library-tests/modules/entry_point/modules.ql new file mode 100644 index 000000000000..10c390e8616c --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/modules.ql @@ -0,0 +1,4 @@ +import python + +from Module m +select m.getName(), m diff --git a/python/ql/test/3/library-tests/modules/entry_point/options b/python/ql/test/3/library-tests/modules/entry_point/options new file mode 100644 index 000000000000..619afd242ed5 --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/options @@ -0,0 +1 @@ +semmle-extractor-options: --lang=3 --path bogus -R . From 17d17682597bc6f7f495b100263d24d5e99da88b Mon Sep 17 00:00:00 2001 From: Taus Brock-Nannestad Date: Tue, 23 Mar 2021 18:20:53 +0100 Subject: [PATCH 2/5] Python: Allow absolute imports in directories with scripts Fixes the import logic to account for absolute imports. We do this by classifying which files and folders may serve as the entry point for execution, based on a few simple heuristics. If the file `module.py` is in the same folder as a file `main.py` that may be executed directly, then we allow `module` to be a valid name for `module.py` so that `import module` will work as expected. --- python/ql/src/semmle/python/Files.qll | 30 +++++++++++++++++++ python/ql/src/semmle/python/Module.qll | 7 ++++- .../modules/entry_point/modules.expected | 2 ++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/python/ql/src/semmle/python/Files.qll b/python/ql/src/semmle/python/Files.qll index ef6484fbdc6e..07bbbed21548 100644 --- a/python/ql/src/semmle/python/Files.qll +++ b/python/ql/src/semmle/python/Files.qll @@ -72,6 +72,33 @@ class File extends Container { * are specified to be extracted. */ string getContents() { file_contents(this, result) } + + /** Holds if this file is likely to get executed directly, and thus act as an entry point for execution. */ + predicate maybeExecutedDirectly() { + // Only consider files in the source code, and not things like the standard library + exists(this.getRelativePath()) and + ( + // The file doesn't have the extension `.py` but still contains Python statements + not this.getExtension() = "py" and + exists(Stmt s | s.getLocation().getFile() = this) + or + // The file contains the usual `if __name__ == '__main__':` construction + exists(If i, Name name, StrConst main, Cmpop op | + i.getScope().(Module).getFile() = this and + op instanceof Eq and + i.getTest().(Compare).compares(name, op, main) and + name.getId() = "__name__" and + main.getText() = "__main__" + ) + or + // The file contains a `#!` line referencing the python interpreter + exists(Comment c | + c.getLocation().getFile() = this and + c.getLocation().getStartLine() = 1 and + c.getText().regexpMatch("^#! */.*python(2|3)?[ \\\\t]*$") + ) + ) + } } private predicate occupied_line(File f, int n) { @@ -121,6 +148,9 @@ class Folder extends Container { this.getBaseName().regexpMatch("[^\\d\\W]\\w*") and result = this.getParent().getImportRoot(n) } + + /** Holds if execution may start in a file in this directory. */ + predicate mayContainEntryPoint() { any(File f | f.getParent() = this).maybeExecutedDirectly() } } /** diff --git a/python/ql/src/semmle/python/Module.qll b/python/ql/src/semmle/python/Module.qll index fcf1c0b29252..8a420a800ea6 100644 --- a/python/ql/src/semmle/python/Module.qll +++ b/python/ql/src/semmle/python/Module.qll @@ -204,8 +204,13 @@ private string moduleNameFromBase(Container file) { string moduleNameFromFile(Container file) { exists(string basename | basename = moduleNameFromBase(file) and - legalShortName(basename) and + legalShortName(basename) + | result = moduleNameFromFile(file.getParent()) + "." + basename + or + // If execution can start in the folder containing this module, then we will assume `file` can + // be imported as an absolute import, and hence return `basename` as a possible name. + file.getParent().(Folder).mayContainEntryPoint() and result = basename ) or isPotentialSourcePackage(file) and diff --git a/python/ql/test/3/library-tests/modules/entry_point/modules.expected b/python/ql/test/3/library-tests/modules/entry_point/modules.expected index 4ec912437826..8c96490597c0 100644 --- a/python/ql/test/3/library-tests/modules/entry_point/modules.expected +++ b/python/ql/test/3/library-tests/modules/entry_point/modules.expected @@ -1,3 +1,5 @@ +| main | code/main.py:0:0:0:0 | Script main | +| module | code/module.py:0:0:0:0 | Module module | | package | code/package:0:0:0:0 | Package package | | package.__init__ | code/package/__init__.py:0:0:0:0 | Module package.__init__ | | package.package_main | code/package/package_main.py:0:0:0:0 | Module package.package_main | From 6d86239929dda58bdb3b0dfe226d88902c7422d0 Mon Sep 17 00:00:00 2001 From: Taus Brock-Nannestad Date: Wed, 24 Mar 2021 13:14:46 +0100 Subject: [PATCH 3/5] Python: Test all cases Note that the test in `no_py_extension` isn't complete, since we're not extracting the `main` file there. --- .../entry_point/{code => hash_bang}/main.py | 0 .../entry_point/{code => hash_bang}/module.py | 0 .../namespace_package_main.py | 0 .../namespace_package_module.py | 0 .../{code => hash_bang}/package/__init__.py | 0 .../package/package_main.py | 0 .../package/package_module.py | 0 .../modules/entry_point/modules.expected | 22 ++++++++++++++----- .../modules/entry_point/name_main/main.py | 8 +++++++ .../modules/entry_point/name_main/module.py | 2 ++ .../namespace_package_main.py | 2 ++ .../namespace_package_module.py | 1 + .../entry_point/name_main/package/__init__.py | 2 ++ .../name_main/package/package_main.py | 2 ++ .../name_main/package/package_module.py | 1 + .../modules/entry_point/no_py_extension/main | 6 +++++ .../entry_point/no_py_extension/module.py | 2 ++ .../namespace_package_main.py | 2 ++ .../namespace_package_module.py | 1 + .../no_py_extension/package/__init__.py | 2 ++ .../no_py_extension/package/package_main.py | 2 ++ .../no_py_extension/package/package_module.py | 1 + 22 files changed, 50 insertions(+), 6 deletions(-) rename python/ql/test/3/library-tests/modules/entry_point/{code => hash_bang}/main.py (100%) rename python/ql/test/3/library-tests/modules/entry_point/{code => hash_bang}/module.py (100%) rename python/ql/test/3/library-tests/modules/entry_point/{code => hash_bang}/namespace_package/namespace_package_main.py (100%) rename python/ql/test/3/library-tests/modules/entry_point/{code => hash_bang}/namespace_package/namespace_package_module.py (100%) rename python/ql/test/3/library-tests/modules/entry_point/{code => hash_bang}/package/__init__.py (100%) rename python/ql/test/3/library-tests/modules/entry_point/{code => hash_bang}/package/package_main.py (100%) rename python/ql/test/3/library-tests/modules/entry_point/{code => hash_bang}/package/package_module.py (100%) create mode 100755 python/ql/test/3/library-tests/modules/entry_point/name_main/main.py create mode 100644 python/ql/test/3/library-tests/modules/entry_point/name_main/module.py create mode 100644 python/ql/test/3/library-tests/modules/entry_point/name_main/namespace_package/namespace_package_main.py create mode 100644 python/ql/test/3/library-tests/modules/entry_point/name_main/namespace_package/namespace_package_module.py create mode 100644 python/ql/test/3/library-tests/modules/entry_point/name_main/package/__init__.py create mode 100644 python/ql/test/3/library-tests/modules/entry_point/name_main/package/package_main.py create mode 100644 python/ql/test/3/library-tests/modules/entry_point/name_main/package/package_module.py create mode 100755 python/ql/test/3/library-tests/modules/entry_point/no_py_extension/main create mode 100644 python/ql/test/3/library-tests/modules/entry_point/no_py_extension/module.py create mode 100644 python/ql/test/3/library-tests/modules/entry_point/no_py_extension/namespace_package/namespace_package_main.py create mode 100644 python/ql/test/3/library-tests/modules/entry_point/no_py_extension/namespace_package/namespace_package_module.py create mode 100644 python/ql/test/3/library-tests/modules/entry_point/no_py_extension/package/__init__.py create mode 100644 python/ql/test/3/library-tests/modules/entry_point/no_py_extension/package/package_main.py create mode 100644 python/ql/test/3/library-tests/modules/entry_point/no_py_extension/package/package_module.py diff --git a/python/ql/test/3/library-tests/modules/entry_point/code/main.py b/python/ql/test/3/library-tests/modules/entry_point/hash_bang/main.py similarity index 100% rename from python/ql/test/3/library-tests/modules/entry_point/code/main.py rename to python/ql/test/3/library-tests/modules/entry_point/hash_bang/main.py diff --git a/python/ql/test/3/library-tests/modules/entry_point/code/module.py b/python/ql/test/3/library-tests/modules/entry_point/hash_bang/module.py similarity index 100% rename from python/ql/test/3/library-tests/modules/entry_point/code/module.py rename to python/ql/test/3/library-tests/modules/entry_point/hash_bang/module.py diff --git a/python/ql/test/3/library-tests/modules/entry_point/code/namespace_package/namespace_package_main.py b/python/ql/test/3/library-tests/modules/entry_point/hash_bang/namespace_package/namespace_package_main.py similarity index 100% rename from python/ql/test/3/library-tests/modules/entry_point/code/namespace_package/namespace_package_main.py rename to python/ql/test/3/library-tests/modules/entry_point/hash_bang/namespace_package/namespace_package_main.py diff --git a/python/ql/test/3/library-tests/modules/entry_point/code/namespace_package/namespace_package_module.py b/python/ql/test/3/library-tests/modules/entry_point/hash_bang/namespace_package/namespace_package_module.py similarity index 100% rename from python/ql/test/3/library-tests/modules/entry_point/code/namespace_package/namespace_package_module.py rename to python/ql/test/3/library-tests/modules/entry_point/hash_bang/namespace_package/namespace_package_module.py diff --git a/python/ql/test/3/library-tests/modules/entry_point/code/package/__init__.py b/python/ql/test/3/library-tests/modules/entry_point/hash_bang/package/__init__.py similarity index 100% rename from python/ql/test/3/library-tests/modules/entry_point/code/package/__init__.py rename to python/ql/test/3/library-tests/modules/entry_point/hash_bang/package/__init__.py diff --git a/python/ql/test/3/library-tests/modules/entry_point/code/package/package_main.py b/python/ql/test/3/library-tests/modules/entry_point/hash_bang/package/package_main.py similarity index 100% rename from python/ql/test/3/library-tests/modules/entry_point/code/package/package_main.py rename to python/ql/test/3/library-tests/modules/entry_point/hash_bang/package/package_main.py diff --git a/python/ql/test/3/library-tests/modules/entry_point/code/package/package_module.py b/python/ql/test/3/library-tests/modules/entry_point/hash_bang/package/package_module.py similarity index 100% rename from python/ql/test/3/library-tests/modules/entry_point/code/package/package_module.py rename to python/ql/test/3/library-tests/modules/entry_point/hash_bang/package/package_module.py diff --git a/python/ql/test/3/library-tests/modules/entry_point/modules.expected b/python/ql/test/3/library-tests/modules/entry_point/modules.expected index 8c96490597c0..e5f6b300074c 100644 --- a/python/ql/test/3/library-tests/modules/entry_point/modules.expected +++ b/python/ql/test/3/library-tests/modules/entry_point/modules.expected @@ -1,6 +1,16 @@ -| main | code/main.py:0:0:0:0 | Script main | -| module | code/module.py:0:0:0:0 | Module module | -| package | code/package:0:0:0:0 | Package package | -| package.__init__ | code/package/__init__.py:0:0:0:0 | Module package.__init__ | -| package.package_main | code/package/package_main.py:0:0:0:0 | Module package.package_main | -| package.package_module | code/package/package_module.py:0:0:0:0 | Module package.package_module | +| main | hash_bang/main.py:0:0:0:0 | Script main | +| main | name_main/main.py:0:0:0:0 | Module main | +| module | hash_bang/module.py:0:0:0:0 | Module module | +| module | name_main/module.py:0:0:0:0 | Module module | +| package | hash_bang/package:0:0:0:0 | Package package | +| package | name_main/package:0:0:0:0 | Package package | +| package | no_py_extension/package:0:0:0:0 | Package package | +| package.__init__ | hash_bang/package/__init__.py:0:0:0:0 | Module package.__init__ | +| package.__init__ | name_main/package/__init__.py:0:0:0:0 | Module package.__init__ | +| package.__init__ | no_py_extension/package/__init__.py:0:0:0:0 | Module package.__init__ | +| package.package_main | hash_bang/package/package_main.py:0:0:0:0 | Module package.package_main | +| package.package_main | name_main/package/package_main.py:0:0:0:0 | Module package.package_main | +| package.package_main | no_py_extension/package/package_main.py:0:0:0:0 | Module package.package_main | +| package.package_module | hash_bang/package/package_module.py:0:0:0:0 | Module package.package_module | +| package.package_module | name_main/package/package_module.py:0:0:0:0 | Module package.package_module | +| package.package_module | no_py_extension/package/package_module.py:0:0:0:0 | Module package.package_module | diff --git a/python/ql/test/3/library-tests/modules/entry_point/name_main/main.py b/python/ql/test/3/library-tests/modules/entry_point/name_main/main.py new file mode 100755 index 000000000000..08ec212383bb --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/name_main/main.py @@ -0,0 +1,8 @@ +print(__file__) +import module +import package +import namespace_package +import namespace_package.namespace_package_main + +if __name__ == '__main__': + print(module.message) diff --git a/python/ql/test/3/library-tests/modules/entry_point/name_main/module.py b/python/ql/test/3/library-tests/modules/entry_point/name_main/module.py new file mode 100644 index 000000000000..36206ca60b75 --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/name_main/module.py @@ -0,0 +1,2 @@ +print(__file__.split("entry_point")[1]) +message = "Hello world!" diff --git a/python/ql/test/3/library-tests/modules/entry_point/name_main/namespace_package/namespace_package_main.py b/python/ql/test/3/library-tests/modules/entry_point/name_main/namespace_package/namespace_package_main.py new file mode 100644 index 000000000000..5db80f18a278 --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/name_main/namespace_package/namespace_package_main.py @@ -0,0 +1,2 @@ +print(__file__.split("entry_point")[1]) +import namespace_package.namespace_package_module diff --git a/python/ql/test/3/library-tests/modules/entry_point/name_main/namespace_package/namespace_package_module.py b/python/ql/test/3/library-tests/modules/entry_point/name_main/namespace_package/namespace_package_module.py new file mode 100644 index 000000000000..567a23d59ce3 --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/name_main/namespace_package/namespace_package_module.py @@ -0,0 +1 @@ +print(__file__.split("entry_point")[1]) diff --git a/python/ql/test/3/library-tests/modules/entry_point/name_main/package/__init__.py b/python/ql/test/3/library-tests/modules/entry_point/name_main/package/__init__.py new file mode 100644 index 000000000000..ca14a9f5804e --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/name_main/package/__init__.py @@ -0,0 +1,2 @@ +print(__file__.split("entry_point")[1]) +from . import package_main diff --git a/python/ql/test/3/library-tests/modules/entry_point/name_main/package/package_main.py b/python/ql/test/3/library-tests/modules/entry_point/name_main/package/package_main.py new file mode 100644 index 000000000000..158b12678e3b --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/name_main/package/package_main.py @@ -0,0 +1,2 @@ +print(__file__.split("entry_point")[1]) +from . import package_module diff --git a/python/ql/test/3/library-tests/modules/entry_point/name_main/package/package_module.py b/python/ql/test/3/library-tests/modules/entry_point/name_main/package/package_module.py new file mode 100644 index 000000000000..567a23d59ce3 --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/name_main/package/package_module.py @@ -0,0 +1 @@ +print(__file__.split("entry_point")[1]) diff --git a/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/main b/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/main new file mode 100755 index 000000000000..e2673d4da786 --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/main @@ -0,0 +1,6 @@ +print(__file__) +import module +import package +import namespace_package +import namespace_package.namespace_package_main +print(module.message) diff --git a/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/module.py b/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/module.py new file mode 100644 index 000000000000..36206ca60b75 --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/module.py @@ -0,0 +1,2 @@ +print(__file__.split("entry_point")[1]) +message = "Hello world!" diff --git a/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/namespace_package/namespace_package_main.py b/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/namespace_package/namespace_package_main.py new file mode 100644 index 000000000000..5db80f18a278 --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/namespace_package/namespace_package_main.py @@ -0,0 +1,2 @@ +print(__file__.split("entry_point")[1]) +import namespace_package.namespace_package_module diff --git a/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/namespace_package/namespace_package_module.py b/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/namespace_package/namespace_package_module.py new file mode 100644 index 000000000000..567a23d59ce3 --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/namespace_package/namespace_package_module.py @@ -0,0 +1 @@ +print(__file__.split("entry_point")[1]) diff --git a/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/package/__init__.py b/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/package/__init__.py new file mode 100644 index 000000000000..ca14a9f5804e --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/package/__init__.py @@ -0,0 +1,2 @@ +print(__file__.split("entry_point")[1]) +from . import package_main diff --git a/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/package/package_main.py b/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/package/package_main.py new file mode 100644 index 000000000000..158b12678e3b --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/package/package_main.py @@ -0,0 +1,2 @@ +print(__file__.split("entry_point")[1]) +from . import package_module diff --git a/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/package/package_module.py b/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/package/package_module.py new file mode 100644 index 000000000000..567a23d59ce3 --- /dev/null +++ b/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/package/package_module.py @@ -0,0 +1 @@ +print(__file__.split("entry_point")[1]) From 8d30ee5c3cb1193ec464c6bb8d5632c72d304f5c Mon Sep 17 00:00:00 2001 From: Taus Brock-Nannestad Date: Wed, 24 Mar 2021 14:01:13 +0100 Subject: [PATCH 4/5] Python: Include unmarked Python file in snapshot Sadly, it seems we're not interpreting this as Python code, even if we explicitly ask to have it included. --- .../modules/entry_point/no_py_extension/{main => main.secretpy} | 0 python/ql/test/3/library-tests/modules/entry_point/options | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename python/ql/test/3/library-tests/modules/entry_point/no_py_extension/{main => main.secretpy} (100%) diff --git a/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/main b/python/ql/test/3/library-tests/modules/entry_point/no_py_extension/main.secretpy similarity index 100% rename from python/ql/test/3/library-tests/modules/entry_point/no_py_extension/main rename to python/ql/test/3/library-tests/modules/entry_point/no_py_extension/main.secretpy diff --git a/python/ql/test/3/library-tests/modules/entry_point/options b/python/ql/test/3/library-tests/modules/entry_point/options index 619afd242ed5..6beceeb08ed0 100644 --- a/python/ql/test/3/library-tests/modules/entry_point/options +++ b/python/ql/test/3/library-tests/modules/entry_point/options @@ -1 +1 @@ -semmle-extractor-options: --lang=3 --path bogus -R . +semmle-extractor-options: --lang=3 --path bogus -R . --filter=include:**/*.secretpy From 47686a6e4ccd67dab5e7862662ef7dab5168ce38 Mon Sep 17 00:00:00 2001 From: Taus Brock-Nannestad Date: Wed, 24 Mar 2021 14:03:00 +0100 Subject: [PATCH 5/5] Python: Disregard all files matching `.py%` --- python/ql/src/semmle/python/Files.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/semmle/python/Files.qll b/python/ql/src/semmle/python/Files.qll index 07bbbed21548..83ba92f0abcc 100644 --- a/python/ql/src/semmle/python/Files.qll +++ b/python/ql/src/semmle/python/Files.qll @@ -79,7 +79,7 @@ class File extends Container { exists(this.getRelativePath()) and ( // The file doesn't have the extension `.py` but still contains Python statements - not this.getExtension() = "py" and + not this.getExtension().matches("py%") and exists(Stmt s | s.getLocation().getFile() = this) or // The file contains the usual `if __name__ == '__main__':` construction