diff --git a/change-notes/1.23/analysis-python.md b/change-notes/1.23/analysis-python.md index 6cea1745284..5320567af85 100644 --- a/change-notes/1.23/analysis-python.md +++ b/change-notes/1.23/analysis-python.md @@ -3,7 +3,19 @@ ## General improvements +### Python 3.8 support +Python 3.8 syntax is now supported. In particular, the following constructs are parsed correctly: + +- Assignment expressions using the "walrus" operator, such as `while chunk := file.read(1024): ...`. +- The positional argument separator `/`, such as in `def foo(a, /, b, *, c): ...`. +- Self-documenting expressions in f-strings, such as `f"{var=}"`. + +### General query improvements + +Following the replacement of the `Object` API (for example, `ClassObject`) in favor of the +`Value` API (for example, `ClassValue`) in the 1.21 release, many of the standard queries have been updated +to use the `Value` API. This should result in more precise results. ## New queries @@ -18,10 +30,23 @@ | **Query** | **Expected impact** | **Change** | |----------------------------|------------------------|------------| -| Unreachable code | Fewer false positives | Analysis now accounts for uses of `contextlib.suppress` to suppress exceptions. | -| `__iter__` method returns a non-iterator | Better alert message | Alert now highlights which class is expected to be an iterator. | - +| Explicit export is undefined (`py/undefined-export`) | Fewer false positive results | Instances where an exported value may be defined in a module that lacks points-to information are no longer flagged. | +| Module-level cyclic import (`py/unsafe-cyclic-import`) | Fewer false positive results | Instances where one of the links in an import cycle is never actually executed are no longer flagged. | +| Non-iterable used in for loop (`py/non-iterable-in-for-loop`) | Fewer false positive results | `__aiter__` is now recognized as an iterator method. | +| Unreachable code (`py/unreachable-statement`) | Fewer false positive results | Analysis now accounts for uses of `contextlib.suppress` to suppress exceptions. | +| Unreachable code (`py/unreachable-statement`) | Fewer false positive results | Unreachable `else` branches that do nothing but `assert` their non-reachability are no longer flagged. | +| Unused import (`py/unused-import`) | Fewer false positive results | Instances where a module is used in a forward-referenced type annotation, or only during type checking are no longer flagged. | +| `__iter__` method returns a non-iterator (`py/iter-returns-non-iterator`) | Better alert message | Alert now highlights which class is expected to be an iterator. | +| `__init__` method returns a value (`py/explicit-return-in-init`) | Fewer false positive results | Instances where the `__init__` method returns the value of a call to a procedure are no longer flagged. | ## Changes to QL libraries * Django library now recognizes positional arguments from a `django.conf.urls.url` regex (Django version 1.x) +* Instances of the `Value` class now support the `isAbsent` method, indicating + whether that `Value` lacks points-to information, but inference + suggests that it exists. For instance, if a file contains `import + django`, but `django` was not extracted properly, there will be a + `ModuleValue` corresponding to this "unknown" module, and the `isAbsent` + method will hold for this `ModuleValue`. +* The `Expr` class now has a nullary method `pointsTo` that returns the possible + instances of `Value` that this expression may have.