From 6c6e35f541f34b25cfc74ce60b49f16d82d296bf Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 9 Aug 2019 16:23:07 +0100 Subject: [PATCH 1/3] Python: Enhance points-to to support type-hint analysis. --- .../ql/src/semmle/python/objects/Classes.qll | 78 +++++++++++++++++++ .../src/semmle/python/objects/Instances.qll | 9 ++- .../src/semmle/python/objects/ObjectAPI.qll | 6 +- .../semmle/python/objects/ObjectInternal.qll | 2 + .../src/semmle/python/objects/Sequences.qll | 9 ++- .../ql/src/semmle/python/objects/TObject.qll | 14 +++- .../src/semmle/python/pointsto/PointsTo.qll | 7 ++ .../PointsTo/typehints/Values.expected | 12 +++ .../PointsTo/typehints/Values.ql | 8 ++ .../library-tests/PointsTo/typehints/options | 2 + .../library-tests/PointsTo/typehints/test.py | 7 ++ python/ql/test/3/library-tests/lib/typing.py | 29 +++++++ .../PointsTo/general/GlobalPointsTo.expected | 2 + .../PointsTo/general/LocalPointsTo.expected | 2 + .../PointsTo/new/NameSpace.expected | 1 + .../PointsTo/new/PointsToWithContext.expected | 2 + .../PointsTo/new/PointsToWithType.expected | 2 + .../PointsTo/new/Values.expected | 5 ++ 18 files changed, 193 insertions(+), 4 deletions(-) create mode 100644 python/ql/test/3/library-tests/PointsTo/typehints/Values.expected create mode 100644 python/ql/test/3/library-tests/PointsTo/typehints/Values.ql create mode 100644 python/ql/test/3/library-tests/PointsTo/typehints/options create mode 100644 python/ql/test/3/library-tests/PointsTo/typehints/test.py create mode 100644 python/ql/test/3/library-tests/lib/typing.py diff --git a/python/ql/src/semmle/python/objects/Classes.qll b/python/ql/src/semmle/python/objects/Classes.qll index a8aec963860..0f8ce81bbdc 100644 --- a/python/ql/src/semmle/python/objects/Classes.qll +++ b/python/ql/src/semmle/python/objects/Classes.qll @@ -365,3 +365,81 @@ class DynamicallyCreatedClass extends ClassObjectInternal, TDynamicClass { } +class SubscriptedTypeInternal extends ObjectInternal, TSubscriptedType { + + ObjectInternal getGeneric() { + this = TSubscriptedType(result, _) + } + + ObjectInternal getSpecializer() { + this = TSubscriptedType(_, result) + } + + override string getName() { result = this.getGeneric().getName() } + + override string toString() { result = this.getGeneric().toString() + "[" + this.getSpecializer().toString() + "]" } + + override predicate introducedAt(ControlFlowNode node, PointsToContext context) { + exists(ObjectInternal generic, ObjectInternal index | + this = TSubscriptedType(generic, index) and + Expressions::subscriptPartsPointsTo(node, context, generic, index) + ) + } + + /** Gets the class declaration for this object, if it is a class with a declaration. */ + override ClassDecl getClassDeclaration() { + result = this.getGeneric().getClassDeclaration() + } + + /** True if this "object" is a class. That is, its class inherits from `type` */ + override boolean isClass() { result = true } + + override ObjectInternal getClass() { + result = this.getGeneric().getClass() + } + + override predicate notTestableForEquality() { none() } + + override Builtin getBuiltin() { none() } + + override ControlFlowNode getOrigin() { none() } + + override predicate callResult(ObjectInternal obj, CfgOrigin origin) { none() } + + override predicate callResult(PointsToContext callee, ObjectInternal obj, CfgOrigin origin) { none() } + + override predicate calleeAndOffset(Function scope, int paramOffset){ none() } + + override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) { none() } + + override predicate attributesUnknown() { none() } + + override boolean isDescriptor() { result = false } + + override predicate descriptorGetClass(ObjectInternal cls, ObjectInternal value, CfgOrigin origin) { none() } + + override predicate descriptorGetInstance(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) { none() } + + override predicate binds(ObjectInternal instance, string name, ObjectInternal descriptor) { none() } + + override int length() { none() } + + override boolean booleanValue() { result = true } + + override int intValue() { none()} + + override string strValue() { none() } + + override predicate subscriptUnknown() { none() } + + override predicate contextSensitiveCallee() { none() } + + override predicate useOriginAsLegacyObject() { none() } + + /* Classes aren't usually iterable, but can e.g. Enums */ + override ObjectInternal getIterNext() { result = ObjectInternal::unknown() } + +} + + + diff --git a/python/ql/src/semmle/python/objects/Instances.qll b/python/ql/src/semmle/python/objects/Instances.qll index f72f1094f08..47b4a9bc55a 100644 --- a/python/ql/src/semmle/python/objects/Instances.qll +++ b/python/ql/src/semmle/python/objects/Instances.qll @@ -91,7 +91,14 @@ class SpecificInstanceInternal extends TSpecificInstance, InstanceObject { override predicate notTestableForEquality() { none() } override ObjectInternal getClass() { - this = TSpecificInstance(_, result, _) + exists(ClassObjectInternal cls, ClassDecl decl | + this = TSpecificInstance(_, cls, _) and + decl = cls.getClassDeclaration() | + if decl.callReturnsInstance() then + result = cls + else + result = TUnknownClass() + ) } /** Gets the `Builtin` for this object, if any. diff --git a/python/ql/src/semmle/python/objects/ObjectAPI.qll b/python/ql/src/semmle/python/objects/ObjectAPI.qll index f1fa459d71f..a120c3f97b8 100644 --- a/python/ql/src/semmle/python/objects/ObjectAPI.qll +++ b/python/ql/src/semmle/python/objects/ObjectAPI.qll @@ -322,7 +322,11 @@ class ClassValue extends Value { /** Gets an improper super type of this class. */ ClassValue getASuperType() { - result = Types::getMro(this).getAnItem() + result = this.getBaseType(_) + or + result = this.getASuperType().getBaseType(_) + or + result = this } /** Looks up the attribute `name` on this class. diff --git a/python/ql/src/semmle/python/objects/ObjectInternal.qll b/python/ql/src/semmle/python/objects/ObjectInternal.qll index 094d84f01b6..4837eba7026 100644 --- a/python/ql/src/semmle/python/objects/ObjectInternal.qll +++ b/python/ql/src/semmle/python/objects/ObjectInternal.qll @@ -557,6 +557,8 @@ class DecoratedFunction extends ObjectInternal, TDecoratedFunction { override string toString() { result = "Decorated " + this.decoratedObject().toString() + or + not exists(this.decoratedObject()) and result = "Decorated function" } override boolean booleanValue() { result = true } diff --git a/python/ql/src/semmle/python/objects/Sequences.qll b/python/ql/src/semmle/python/objects/Sequences.qll index dda2f920dbf..83679c78fe8 100644 --- a/python/ql/src/semmle/python/objects/Sequences.qll +++ b/python/ql/src/semmle/python/objects/Sequences.qll @@ -49,7 +49,14 @@ abstract class TupleObjectInternal extends SequenceObjectInternal { or n = 3 and this.length() > 3 and result = (this.length()-3).toString() + " more..." or - result = this.getItem(n).toString() + ", " + this.contents(n+1) + result = this.item(n) + ", " + this.contents(n+1) + } + + private string item(int n) { + result = this.getItem(n).toString() + or + n in [0..this.length()-1] and + not exists(this.getItem(n)) and result = "?" } /** Gets the class declaration for this object, if it is a declared class. */ diff --git a/python/ql/src/semmle/python/objects/TObject.qll b/python/ql/src/semmle/python/objects/TObject.qll index b79eb5fc73d..58a089ef8f1 100644 --- a/python/ql/src/semmle/python/objects/TObject.qll +++ b/python/ql/src/semmle/python/objects/TObject.qll @@ -132,7 +132,7 @@ cached newtype TObject = /* An instance of `cls`, instantiated at `instantiation` given the `context`. */ TSpecificInstance(ControlFlowNode instantiation, ClassObjectInternal cls, PointsToContext context) { PointsToInternal::pointsTo(instantiation.(CallNode).getFunction(), context, cls, _) and - cls.isSpecial() = false and cls.getClassDeclaration().callReturnsInstance() + cls.isSpecial() = false or literal_instantiation(instantiation, cls, context) } @@ -236,6 +236,18 @@ cached newtype TObject = TDecoratedFunction(CallNode call) { call.isFunctionDecoratorCall() } + or + /* Represents a subscript operation applied to a type. For type-hint analysis */ + TSubscriptedType(ObjectInternal generic, ObjectInternal index) { + isType(generic) and + Expressions::subscriptPartsPointsTo(_, _, generic, index) + } + +predicate isType(ObjectInternal t) { + t.isClass() = true + or + t.getOrigin().getEnclosingModule().getName().matches("%typing") +} private predicate is_power_2(int n) { n = 1 or diff --git a/python/ql/src/semmle/python/pointsto/PointsTo.qll b/python/ql/src/semmle/python/pointsto/PointsTo.qll index b3716994429..41935fb8e00 100644 --- a/python/ql/src/semmle/python/pointsto/PointsTo.qll +++ b/python/ql/src/semmle/python/pointsto/PointsTo.qll @@ -1229,6 +1229,13 @@ module Expressions { origin = subscr } + predicate subscriptPartsPointsTo(SubscriptNode subscr, PointsToContext context, ObjectInternal objvalue, ObjectInternal indexvalue) { + exists(ControlFlowNode index | + subscriptObjectAndIndex(subscr, context, _, objvalue, index) and + PointsToInternal::pointsTo(index, context, indexvalue, _) + ) + } + pragma [noinline] private predicate subscriptObjectAndIndex(SubscriptNode subscr, PointsToContext context, ControlFlowNode obj, ObjectInternal objvalue, ControlFlowNode index) { subscr.isLoad() and diff --git a/python/ql/test/3/library-tests/PointsTo/typehints/Values.expected b/python/ql/test/3/library-tests/PointsTo/typehints/Values.expected new file mode 100644 index 00000000000..692ebaba7af --- /dev/null +++ b/python/ql/test/3/library-tests/PointsTo/typehints/Values.expected @@ -0,0 +1,12 @@ +| test.py:1:6:1:11 | test.py:1 | ControlFlowNode for ImportExpr | import | ../../lib/typing.py:0:0:0:0 | Module typing | +| test.py:1:6:1:11 | test.py:1 | ControlFlowNode for ImportExpr | import | ../../lib/typing.py:0:0:0:0 | Module typing | +| test.py:1:20:1:27 | test.py:1 | ControlFlowNode for ImportMember | import | ../../lib/typing.py:18:12:18:32 | _Optional() | +| test.py:1:30:1:32 | test.py:1 | ControlFlowNode for ImportMember | import | ../../lib/typing.py:23:1:23:23 | class Set | +| test.py:3:1:3:32 | test.py:3 | ControlFlowNode for FunctionExpr | import | test.py:3:1:3:32 | Function foo | +| test.py:3:11:3:18 | test.py:3 | ControlFlowNode for Optional | import | ../../lib/typing.py:18:12:18:32 | _Optional() | +| test.py:3:11:3:23 | test.py:3 | ControlFlowNode for Subscript | import | file://:0:0:0:0 | _Optional()[builtin-class int] | +| test.py:3:20:3:22 | test.py:3 | ControlFlowNode for int | import | file://:0:0:0:0 | builtin-class int | +| test.py:3:29:3:31 | test.py:3 | ControlFlowNode for int | import | file://:0:0:0:0 | builtin-class int | +| test.py:6:1:6:20 | test.py:6 | ControlFlowNode for FunctionExpr | import | test.py:6:1:6:20 | Function bar | +| test.py:6:11:6:13 | test.py:6 | ControlFlowNode for set | import | file://:0:0:0:0 | builtin-class set | +| test.py:6:17:6:19 | test.py:6 | ControlFlowNode for Set | import | ../../lib/typing.py:23:1:23:23 | class Set | diff --git a/python/ql/test/3/library-tests/PointsTo/typehints/Values.ql b/python/ql/test/3/library-tests/PointsTo/typehints/Values.ql new file mode 100644 index 00000000000..d8e877aa437 --- /dev/null +++ b/python/ql/test/3/library-tests/PointsTo/typehints/Values.ql @@ -0,0 +1,8 @@ + +import python + +from ControlFlowNode f, Context ctx, Value v, ControlFlowNode origin +where + f.pointsTo(ctx, v, origin) and + f.getLocation().getFile().getBaseName() = "test.py" +select f.getLocation(), f.toString(), ctx, v diff --git a/python/ql/test/3/library-tests/PointsTo/typehints/options b/python/ql/test/3/library-tests/PointsTo/typehints/options new file mode 100644 index 00000000000..a4313cfa0c5 --- /dev/null +++ b/python/ql/test/3/library-tests/PointsTo/typehints/options @@ -0,0 +1,2 @@ +semmle-extractor-options: -p ../../lib/ --max-import-depth=3 +optimize: true diff --git a/python/ql/test/3/library-tests/PointsTo/typehints/test.py b/python/ql/test/3/library-tests/PointsTo/typehints/test.py new file mode 100644 index 00000000000..b3214d3c16b --- /dev/null +++ b/python/ql/test/3/library-tests/PointsTo/typehints/test.py @@ -0,0 +1,7 @@ +from typing import Optional, Set + +def foo(x:Optional[int]) -> int: + pass + +def bar(s:set)->Set: + pass diff --git a/python/ql/test/3/library-tests/lib/typing.py b/python/ql/test/3/library-tests/lib/typing.py new file mode 100644 index 00000000000..f9e0a386337 --- /dev/null +++ b/python/ql/test/3/library-tests/lib/typing.py @@ -0,0 +1,29 @@ +#Fake typing module for testing. + +class ComplexMetaclass(type): + + def __new__(self): + pass + +class ComplexBaseClass(metaclass=ComplexMetaclass): + + def __new__(self): + pass + +class _Optional(ComplexBaseClass, extras=...): + + def __new__(self): + pass + +Optional = _Optional("Optional") + +class Collections(ComplexBaseClass, extras=...): + pass + +class Set(Collections): + pass + +class List(Collections): + pass + +Optional diff --git a/python/ql/test/library-tests/PointsTo/general/GlobalPointsTo.expected b/python/ql/test/library-tests/PointsTo/general/GlobalPointsTo.expected index c5e91b6077b..9040788529a 100644 --- a/python/ql/test/library-tests/PointsTo/general/GlobalPointsTo.expected +++ b/python/ql/test/library-tests/PointsTo/general/GlobalPointsTo.expected @@ -143,6 +143,8 @@ | Module pointsto_test | 161 | ControlFlowNode for ClassExpr | class Derived3 | | Module pointsto_test | 161 | ControlFlowNode for Derived3 | class Derived3 | | Module pointsto_test | 164 | ControlFlowNode for Base | class Base | +| Module pointsto_test | 164 | ControlFlowNode for Base() | Base() | +| Module pointsto_test | 164 | ControlFlowNode for thing | Base() | | Module pointsto_test | 167 | ControlFlowNode for FunctionExpr | Function multiple_assignment | | Module pointsto_test | 167 | ControlFlowNode for multiple_assignment | Function multiple_assignment | | Module pointsto_test | 173 | ControlFlowNode for Base2 | class Base2 | diff --git a/python/ql/test/library-tests/PointsTo/general/LocalPointsTo.expected b/python/ql/test/library-tests/PointsTo/general/LocalPointsTo.expected index d26f953352a..b9494250615 100644 --- a/python/ql/test/library-tests/PointsTo/general/LocalPointsTo.expected +++ b/python/ql/test/library-tests/PointsTo/general/LocalPointsTo.expected @@ -233,6 +233,8 @@ | 161 | ControlFlowNode for ClassExpr | class Derived3 | | 161 | ControlFlowNode for Derived3 | class Derived3 | | 164 | ControlFlowNode for Base | class Base | +| 164 | ControlFlowNode for Base() | Base() | +| 164 | ControlFlowNode for thing | Base() | | 167 | ControlFlowNode for FunctionExpr | Function multiple_assignment | | 167 | ControlFlowNode for multiple_assignment | Function multiple_assignment | | 168 | ControlFlowNode for Tuple | Tuple | diff --git a/python/ql/test/library-tests/PointsTo/new/NameSpace.expected b/python/ql/test/library-tests/PointsTo/new/NameSpace.expected index 8849333ff9a..418b399bd83 100644 --- a/python/ql/test/library-tests/PointsTo/new/NameSpace.expected +++ b/python/ql/test/library-tests/PointsTo/new/NameSpace.expected @@ -79,6 +79,7 @@ | h_classes.py:0 | Module code.h_classes | f | Function f | | h_classes.py:0 | Module code.h_classes | k | Function k | | h_classes.py:0 | Module code.h_classes | sys | Module sys | +| h_classes.py:0 | Module code.h_classes | thing | Base() | | h_classes.py:3 | Class C | __init__ | Function __init__ | | h_classes.py:3 | Class C | x | 'C_x' | | h_classes.py:23 | Class Base | __init__ | Function __init__ | diff --git a/python/ql/test/library-tests/PointsTo/new/PointsToWithContext.expected b/python/ql/test/library-tests/PointsTo/new/PointsToWithContext.expected index cfd397f968b..e91ae8bcbf2 100644 --- a/python/ql/test/library-tests/PointsTo/new/PointsToWithContext.expected +++ b/python/ql/test/library-tests/PointsTo/new/PointsToWithContext.expected @@ -403,6 +403,8 @@ WARNING: Predicate points_to has been deprecated and may be removed in future (P | h_classes.py:39 | ControlFlowNode for ClassExpr | class Derived3 | builtin-class type | 39 | import | | h_classes.py:39 | ControlFlowNode for Derived3 | class Derived3 | builtin-class type | 39 | import | | h_classes.py:42 | ControlFlowNode for Base | class Base | builtin-class type | 23 | import | +| h_classes.py:42 | ControlFlowNode for Base() | Base() | *UNKNOWN TYPE* | 42 | import | +| h_classes.py:42 | ControlFlowNode for thing | Base() | *UNKNOWN TYPE* | 42 | import | | h_classes.py:45 | ControlFlowNode for FunctionExpr | Function f | builtin-class function | 45 | import | | h_classes.py:45 | ControlFlowNode for f | Function f | builtin-class function | 45 | import | | h_classes.py:48 | ControlFlowNode for ClassExpr | class D | builtin-class type | 48 | import | diff --git a/python/ql/test/library-tests/PointsTo/new/PointsToWithType.expected b/python/ql/test/library-tests/PointsTo/new/PointsToWithType.expected index 6fc1935b52c..e4434f3d605 100644 --- a/python/ql/test/library-tests/PointsTo/new/PointsToWithType.expected +++ b/python/ql/test/library-tests/PointsTo/new/PointsToWithType.expected @@ -500,6 +500,8 @@ WARNING: Predicate points_to has been deprecated and may be removed in future (P | h_classes.py:39 | ControlFlowNode for ClassExpr | class Derived3 | builtin-class type | 39 | | h_classes.py:39 | ControlFlowNode for Derived3 | class Derived3 | builtin-class type | 39 | | h_classes.py:42 | ControlFlowNode for Base | class Base | builtin-class type | 23 | +| h_classes.py:42 | ControlFlowNode for Base() | Base() | *UNKNOWN TYPE* | 42 | +| h_classes.py:42 | ControlFlowNode for thing | Base() | *UNKNOWN TYPE* | 42 | | h_classes.py:45 | ControlFlowNode for FunctionExpr | Function f | builtin-class function | 45 | | h_classes.py:45 | ControlFlowNode for f | Function f | builtin-class function | 45 | | h_classes.py:48 | ControlFlowNode for ClassExpr | class D | builtin-class type | 48 | diff --git a/python/ql/test/library-tests/PointsTo/new/Values.expected b/python/ql/test/library-tests/PointsTo/new/Values.expected index 29fe8622bde..7763594ff76 100644 --- a/python/ql/test/library-tests/PointsTo/new/Values.expected +++ b/python/ql/test/library-tests/PointsTo/new/Values.expected @@ -11,8 +11,10 @@ | a_simple.py:16 | ControlFlowNode for d | runtime | instance of dict | builtin-class dict | | a_simple.py:18 | ControlFlowNode for FunctionExpr | import | Function multi_loop | builtin-class function | | a_simple.py:19 | ControlFlowNode for None | runtime | None | builtin-class NoneType | +| a_simple.py:20 | ControlFlowNode for Tuple | runtime | (?, ?, ) | builtin-class tuple | | a_simple.py:23 | ControlFlowNode for FunctionExpr | import | Function with_definition | builtin-class function | | a_simple.py:27 | ControlFlowNode for FunctionExpr | import | Function multi_loop_in_try | builtin-class function | +| a_simple.py:29 | ControlFlowNode for Tuple | runtime | (?, ?, ) | builtin-class tuple | | a_simple.py:31 | ControlFlowNode for KeyError | runtime | builtin-class KeyError | builtin-class type | | a_simple.py:34 | ControlFlowNode for FunctionExpr | import | Function f | builtin-class function | | a_simple.py:35 | ControlFlowNode for IntegerLiteral | runtime | int 0 | builtin-class int | @@ -36,11 +38,14 @@ | a_simple.py:40 | ControlFlowNode for Tuple | runtime | (Unknown value, Unknown value, Unknown value, ) | builtin-class tuple | | a_simple.py:40 | ControlFlowNode for b | runtime | 'b' | builtin-class str | | a_simple.py:40 | ControlFlowNode for c | runtime | 'c' | builtin-class str | +| a_simple.py:41 | ControlFlowNode for Tuple | runtime | (?, ?, ?, ) | builtin-class tuple | | a_simple.py:41 | ControlFlowNode for t | runtime | (int 1, int 2, int 3, ) | builtin-class tuple | +| a_simple.py:42 | ControlFlowNode for Tuple | runtime | (?, ?, ?, ) | builtin-class tuple | | a_simple.py:42 | ControlFlowNode for w | runtime | (Unknown value, 'b', 'c', ) | builtin-class tuple | | a_simple.py:42 | ControlFlowNode for w | runtime | (Unknown value, 'b', Unknown value, ) | builtin-class tuple | | a_simple.py:42 | ControlFlowNode for w | runtime | (Unknown value, Unknown value, 'c', ) | builtin-class tuple | | a_simple.py:42 | ControlFlowNode for w | runtime | (Unknown value, Unknown value, Unknown value, ) | builtin-class tuple | +| a_simple.py:49 | ControlFlowNode for Tuple | runtime | (?, ?, ?, ) | builtin-class tuple | | a_simple.py:49 | ControlFlowNode for Tuple | runtime | (Unknown value, 'b', 'c', ) | builtin-class tuple | | a_simple.py:49 | ControlFlowNode for Tuple | runtime | (Unknown value, 'b', Unknown value, ) | builtin-class tuple | | a_simple.py:49 | ControlFlowNode for Tuple | runtime | (Unknown value, Unknown value, 'c', ) | builtin-class tuple | From 45f5825b4796950ac55b983c9a08b53ac711f4d6 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 15 Aug 2019 10:26:03 +0100 Subject: [PATCH 2/3] Python API: Add ClassValue.getABaseType() --- python/ql/src/semmle/python/objects/ObjectAPI.qll | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/python/ql/src/semmle/python/objects/ObjectAPI.qll b/python/ql/src/semmle/python/objects/ObjectAPI.qll index a120c3f97b8..e46c8b701be 100644 --- a/python/ql/src/semmle/python/objects/ObjectAPI.qll +++ b/python/ql/src/semmle/python/objects/ObjectAPI.qll @@ -322,11 +322,7 @@ class ClassValue extends Value { /** Gets an improper super type of this class. */ ClassValue getASuperType() { - result = this.getBaseType(_) - or - result = this.getASuperType().getBaseType(_) - or - result = this + result = this.getABaseType*() } /** Looks up the attribute `name` on this class. @@ -371,6 +367,11 @@ class ClassValue extends Value { result = Types::getBase(this, n) } + /** Gets a base class of this class */ + ClassValue getABaseType() { + result = Types::getBase(this, _) + } + /** Holds if this class is a new style class. A new style class is one that implicitly or explicitly inherits from `object`. */ predicate isNewStyle() { From 902871bd48264a8a0d97c0f747f7c112c7b6f54e Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 15 Aug 2019 11:37:07 +0100 Subject: [PATCH 3/3] Python: update tests results after rebase. --- python/ql/test/library-tests/PointsTo/new/Values.expected | 5 ----- 1 file changed, 5 deletions(-) diff --git a/python/ql/test/library-tests/PointsTo/new/Values.expected b/python/ql/test/library-tests/PointsTo/new/Values.expected index 7763594ff76..29fe8622bde 100644 --- a/python/ql/test/library-tests/PointsTo/new/Values.expected +++ b/python/ql/test/library-tests/PointsTo/new/Values.expected @@ -11,10 +11,8 @@ | a_simple.py:16 | ControlFlowNode for d | runtime | instance of dict | builtin-class dict | | a_simple.py:18 | ControlFlowNode for FunctionExpr | import | Function multi_loop | builtin-class function | | a_simple.py:19 | ControlFlowNode for None | runtime | None | builtin-class NoneType | -| a_simple.py:20 | ControlFlowNode for Tuple | runtime | (?, ?, ) | builtin-class tuple | | a_simple.py:23 | ControlFlowNode for FunctionExpr | import | Function with_definition | builtin-class function | | a_simple.py:27 | ControlFlowNode for FunctionExpr | import | Function multi_loop_in_try | builtin-class function | -| a_simple.py:29 | ControlFlowNode for Tuple | runtime | (?, ?, ) | builtin-class tuple | | a_simple.py:31 | ControlFlowNode for KeyError | runtime | builtin-class KeyError | builtin-class type | | a_simple.py:34 | ControlFlowNode for FunctionExpr | import | Function f | builtin-class function | | a_simple.py:35 | ControlFlowNode for IntegerLiteral | runtime | int 0 | builtin-class int | @@ -38,14 +36,11 @@ | a_simple.py:40 | ControlFlowNode for Tuple | runtime | (Unknown value, Unknown value, Unknown value, ) | builtin-class tuple | | a_simple.py:40 | ControlFlowNode for b | runtime | 'b' | builtin-class str | | a_simple.py:40 | ControlFlowNode for c | runtime | 'c' | builtin-class str | -| a_simple.py:41 | ControlFlowNode for Tuple | runtime | (?, ?, ?, ) | builtin-class tuple | | a_simple.py:41 | ControlFlowNode for t | runtime | (int 1, int 2, int 3, ) | builtin-class tuple | -| a_simple.py:42 | ControlFlowNode for Tuple | runtime | (?, ?, ?, ) | builtin-class tuple | | a_simple.py:42 | ControlFlowNode for w | runtime | (Unknown value, 'b', 'c', ) | builtin-class tuple | | a_simple.py:42 | ControlFlowNode for w | runtime | (Unknown value, 'b', Unknown value, ) | builtin-class tuple | | a_simple.py:42 | ControlFlowNode for w | runtime | (Unknown value, Unknown value, 'c', ) | builtin-class tuple | | a_simple.py:42 | ControlFlowNode for w | runtime | (Unknown value, Unknown value, Unknown value, ) | builtin-class tuple | -| a_simple.py:49 | ControlFlowNode for Tuple | runtime | (?, ?, ?, ) | builtin-class tuple | | a_simple.py:49 | ControlFlowNode for Tuple | runtime | (Unknown value, 'b', 'c', ) | builtin-class tuple | | a_simple.py:49 | ControlFlowNode for Tuple | runtime | (Unknown value, 'b', Unknown value, ) | builtin-class tuple | | a_simple.py:49 | ControlFlowNode for Tuple | runtime | (Unknown value, Unknown value, 'c', ) | builtin-class tuple |