For whatever reason, the CFG node for exceptions and exception groups
was placed with the points-to code. (Probably because a lot of the
predicates depended on points-to.)
However, as it turned out, two of the SSA modules only depended on
non-points-to properties of these nodes, and so it was fairly
straightforward to remove the imports of `LegacyPointsTo` for those
modules.
In the process, I moved the aforementioned CFG node types into
`Flow.qll`, and changed the classes in the `Exceptions` module to the
`...WithPointsTo` form that we introduced elsewhere.
Moves the existing points-to predicates to the newly added class
`ControlFlowNodeWithPointsTo` which resides in the `LegacyPointsTo`
module.
(Existing code that uses these predicates should import this module, and
references to `ControlFlowNode` should be changed to
`ControlFlowNodeWithPointsTo`.)
Also updates all existing points-to based code to do just this.
I'm beginning to realise why I didn't do the `toString` overriding way
back when. Thankfully, now that all of our tests are in the same place,
this is actually not a terrible ordeal.
I reckon this is due to the Python 3 version used by the Python 2 tests
is different from 3.12, so even with --lang=3 the tests are still using
an incompatible version :(
You might wonder why the number of lines changed, but it's due to `tty`
module receiving its' first update since 2001, so the actual number of
lines DID change :phew:
https://github.com/python/cpython/commits/3.12/Lib/tty.py
Since there is now a difference between Python 2 and Python 3, we need to restrict the lines of code test to only run as Python 3.
These are semantic differences.
They generally look good, except perhaps
we should exclude illegal package names?
(It passes `legalShortName`, though).
Depends on an internal PR. The two lines in question were caused by
the insertion of an extra node due to the failure to parse a trailing
comma corrcetly.
Since `python.qll` has `private import
semmle.python.dataflow.new.DataFlow`, that means that all tests now
implicitly imports the frameworks modeling, and therefore any python
class is part of the DjangoViewClassHelper ql class.
de8ecb214f/python/ql/lib/python.qll (L44)
This reverts commit 8d15680af4, reversing
changes made to 63831cc62b.
This PR caused performance problems, so reverting now to clear up immediate
problems.
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.
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.
Default values for positional arugments follow a rule, so if an argument has a
default value, later positional arguments must also have default values.
The database only stores the actual default values, and nothing about the
arguments that doesn't have default values.
This turns out to be a major problem for Argument.getKwDefault(i), since default
values for keyword-only arguments doesn't have the same rule. So if you know
there is one default value, you can't tell if it is associated with `foo` or
`bar`, as in the examples below:
```
def a(*, foo=None, bar):
pass
def b(*, foo, bar=None):
pass
```