diff --git a/python/ql/src/semmle/python/AstGenerated.qll b/python/ql/src/semmle/python/AstGenerated.qll index c74efec24ca1..6c1802f58c2c 100644 --- a/python/ql/src/semmle/python/AstGenerated.qll +++ b/python/ql/src/semmle/python/AstGenerated.qll @@ -1310,13 +1310,13 @@ library class AliasList_ extends @py_alias_list { /** INTERNAL: See the class `Arguments` for further information. */ library class Arguments_ extends @py_arguments { - /** Gets the keyword default values of this parameters definition. */ + /** Gets the keyword-only default values of this parameters definition. */ ExprList getKwDefaults() { py_expr_lists(result, this, 0) } - /** Gets the nth keyword default value of this parameters definition. */ + /** Gets the nth keyword-only default value of this parameters definition. */ Expr getKwDefault(int index) { result = this.getKwDefaults().getItem(index) } - /** Gets a keyword default value of this parameters definition. */ + /** Gets a keyword-only default value of this parameters definition. */ Expr getAKwDefault() { result = this.getKwDefaults().getAnItem() } /** Gets the default values of this parameters definition. */ @@ -1343,13 +1343,13 @@ library class Arguments_ extends @py_arguments { /** Gets the **kwarg annotation of this parameters definition. */ Expr getKwargannotation() { py_exprs(result, _, this, 4) } - /** Gets the kw_annotations of this parameters definition. */ + /** Gets the keyword-only annotations of this parameters definition. */ ExprList getKwAnnotations() { py_expr_lists(result, this, 5) } - /** Gets the nth kw_annotation of this parameters definition. */ + /** Gets the nth keyword-only annotation of this parameters definition. */ Expr getKwAnnotation(int index) { result = this.getKwAnnotations().getItem(index) } - /** Gets a kw_annotation of this parameters definition. */ + /** Gets a keyword-only annotation of this parameters definition. */ Expr getAKwAnnotation() { result = this.getKwAnnotations().getAnItem() } ArgumentsParent getParent() { py_arguments(this, result) } diff --git a/python/ql/src/semmle/python/Function.qll b/python/ql/src/semmle/python/Function.qll index 3bf991b313e2..b5cd9b4db4f6 100644 --- a/python/ql/src/semmle/python/Function.qll +++ b/python/ql/src/semmle/python/Function.qll @@ -49,7 +49,11 @@ class Function extends Function_, Scope, AstNode { string getArgName(int index) { result = this.getArg(index).(Name).getId() } Parameter getArgByName(string name) { - result = this.getAnArg() and + ( + result = this.getAnArg() + or + result = this.getAKeywordOnlyArg() + ) and result.(Name).getId() = name } @@ -90,7 +94,7 @@ class Function extends Function_, Scope, AstNode { int getPositionalParameterCount() { result = count(this.getAnArg()) } /** Gets the number of keyword-only parameters */ - int getKeywordOnlyParameterCount() { result = count(this.getAKwonlyarg()) } + int getKeywordOnlyParameterCount() { result = count(this.getAKeywordOnlyArg()) } /** Whether this function accepts a variable number of arguments. That is, whether it has a starred (*arg) parameter. */ predicate hasVarArg() { exists(this.getVararg()) } @@ -102,6 +106,7 @@ class Function extends Function_, Scope, AstNode { result = this.getAStmt() or result = this.getAnArg() or result = this.getVararg() or + result = this.getAKeywordOnlyArg() or result = this.getKwarg() } @@ -185,6 +190,8 @@ class Parameter extends Parameter_ { f.getVararg() = this or f.getKwarg() = this + or + f.getAKeywordOnlyArg() = this ) } @@ -202,19 +209,31 @@ class Parameter extends Parameter_ { /** Gets the expression for the default value of this parameter */ Expr getDefault() { - exists(Function f, int n, int c, int d, Arguments args | args = f.getDefinition().getArgs() | - f.getArg(n) = this and - c = count(f.getAnArg()) and - d = count(args.getADefault()) and - result = args.getDefault(d - c + n) + exists(Function f, int i, Arguments args | args = f.getDefinition().getArgs() | + // positional (normal) + f.getArg(i) = this and + result = args.getDefault(i) + ) + or + exists(Function f, int i, Arguments args | args = f.getDefinition().getArgs() | + // keyword-only + f.getKeywordOnlyArg(i) = this and + result = args.getKwDefault(i) ) } /** Gets the annotation expression of this parameter */ Expr getAnnotation() { - exists(Function f, int n, Arguments args | args = f.getDefinition().getArgs() | - f.getArg(n) = this and - result = args.getAnnotation(n) + exists(Function f, int i, Arguments args | args = f.getDefinition().getArgs() | + // positional (normal) + f.getArg(i) = this and + result = args.getAnnotation(i) + ) + or + exists(Function f, int i, Arguments args | args = f.getDefinition().getArgs() | + // keyword-only + f.getKeywordOnlyArg(i) = this and + result = args.getKwAnnotation(i) ) or exists(Function f, Arguments args | args = f.getDefinition().getArgs() | @@ -228,7 +247,10 @@ class Parameter extends Parameter_ { Variable getVariable() { result.getAnAccess() = this.asName() } - /** Gets the position of this parameter */ + /** + * Gets the position of this parameter (if any). + * No result if this is a "varargs", "kwargs", or keyword-only parameter. + */ int getPosition() { exists(Function f | f.getArg(result) = this) } /** Gets the name of this parameter */ @@ -243,13 +265,13 @@ class Parameter extends Parameter_ { } /** - * Holds if this parameter is a 'varargs' parameter. + * Holds if this parameter is a "varargs" parameter. * The `varargs` in `f(a, b, *varargs)`. */ predicate isVarargs() { exists(Function func | func.getVararg() = this) } /** - * Holds if this parameter is a 'kwargs' parameter. + * Holds if this parameter is a "kwargs" parameter. * The `kwargs` in `f(a, b, **kwargs)`. */ predicate isKwargs() { exists(Function func | func.getKwarg() = this) } @@ -258,7 +280,8 @@ class Parameter extends Parameter_ { /** An expression that generates a callable object, either a function expression or a lambda */ abstract class CallableExpr extends Expr { /** - * Gets the parameters of this callable. + * Gets The default values and annotations (type-hints) for the arguments of this callable. + * * This predicate is called getArgs(), rather than getParameters() for compatibility with Python's AST module. */ abstract Arguments getArgs(); @@ -295,7 +318,7 @@ class FunctionExpr extends FunctionExpr_, CallableExpr { override Arguments getArgs() { result = FunctionExpr_.super.getArgs() } } -/** A lambda expression, such as lambda x:x*x */ +/** A lambda expression, such as `lambda x: x+1` */ class Lambda extends Lambda_, CallableExpr { /** Gets the expression to the right of the colon in this lambda expression */ Expr getExpression() { @@ -314,13 +337,36 @@ class Lambda extends Lambda_, CallableExpr { override Arguments getArgs() { result = Lambda_.super.getArgs() } } -/** The arguments in a function definition */ +/** + * The default values and annotations (type hints) for the arguments in a function definition. + * + * Annotations (PEP 3107) is a general mechanism for providing annotations for a function, + * that is generally only used for type hints today (PEP 484). + */ class Arguments extends Arguments_ { + Expr getASubExpression() { + result = this.getADefault() or result = this.getAKwDefault() or + // result = this.getAnAnnotation() or - result = this.getKwargannotation() or result = this.getVarargannotation() or - result = this.getADefault() + result = this.getAKwAnnotation() or + result = this.getKwargannotation() } + + // The following 4 methods are overwritten to provide better QLdoc. Since the + // Arguments_ is auto-generated, we can't change the poor auto-generated docs there :( + + /** Gets the default value for the `index`'th positional parameter. */ + override Expr getDefault(int index) { result = super.getDefault(index) } + + /** Gets the default value for the `index`'th keyword-only parameter. */ + override Expr getKwDefault(int index) { result = super.getKwDefault(index) } + + /** Gets the annotation for the `index`'th positional parameter. */ + override Expr getAnnotation(int index) { result = super.getAnnotation(index) } + + /** Gets the annotation for the `index`'th keyword-only parameter. */ + override Expr getKwAnnotation(int index) { result = super.getKwAnnotation(index) } } diff --git a/python/ql/src/semmle/python/objects/ObjectAPI.qll b/python/ql/src/semmle/python/objects/ObjectAPI.qll index 6428473d1c05..833a755c0594 100644 --- a/python/ql/src/semmle/python/objects/ObjectAPI.qll +++ b/python/ql/src/semmle/python/objects/ObjectAPI.qll @@ -438,6 +438,7 @@ class CallableValue extends Value { exists(int n | call.getArg(n) = result and this.getParameter(n + offset).getId() = name + // TODO: and not positional only argument (Python 3.8+) ) or called instanceof BoundMethodObjectInternal and diff --git a/python/ql/src/semmlecode.python.dbscheme b/python/ql/src/semmlecode.python.dbscheme index f635b392038a..4f1806347d7f 100644 --- a/python/ql/src/semmlecode.python.dbscheme +++ b/python/ql/src/semmlecode.python.dbscheme @@ -5,6 +5,17 @@ * by adding rules to dbscheme.template */ +/* This is a dummy line to alter the dbscheme, so we can make a database upgrade + * without actually changing any of the dbscheme predicates. It contains a date + * to allow for such updates in the future as well. + * + * 2020-07-02 + * + * DO NOT remove this comment carelessly, since it can revert the dbscheme back to a + * previously seen state (matching a previously seen SHA), which would make the upgrade + * mechanism not work properly. + */ + /* * External artifacts */ @@ -126,7 +137,7 @@ containerparent(int parent: @container ref, unique int child: @container ref); @sourceline = @file | @py_Module | @xmllocatable; - + numlines(int element_id: @sourceline ref, int num_lines: int ref, int num_code: int ref, @@ -922,7 +933,7 @@ ext_rettype(int funcid : @py_object ref, ext_proptype(int propid : @py_object ref, int typeid : @py_object ref); -ext_argreturn(int funcid : @py_object ref, +ext_argreturn(int funcid : @py_object ref, int arg : int ref); py_special_objects(unique int obj : @py_cobject ref, @@ -935,7 +946,7 @@ py_decorated_object(int object : @py_object ref, @py_source_element = @py_ast_node | @container; -/* XML Files */ +/* XML Files */ xmlEncoding (unique int id: @file ref, varchar(900) encoding: string ref); @@ -943,7 +954,7 @@ xmlDTDs (unique int id: @xmldtd, varchar(900) root: string ref, varchar(900) publicId: string ref, varchar(900) systemId: string ref, - int fileid: @file ref); + int fileid: @file ref); xmlElements (unique int id: @xmlelement, varchar(900) name: string ref, @@ -958,7 +969,7 @@ xmlAttrs (unique int id: @xmlattribute, int idx: int ref, int fileid: @file ref); -xmlNs (int id: @xmlnamespace, +xmlNs (int id: @xmlnamespace, varchar(900) prefixName: string ref, varchar(900) URI: string ref, int fileid: @file ref); @@ -970,7 +981,7 @@ xmlHasNs (int elementId: @xmlnamespaceable ref, xmlComments (unique int id: @xmlcomment, varchar(3600) text: string ref, int parentid: @xmlparent ref, - int fileid: @file ref); + int fileid: @file ref); xmlChars (unique int id: @xmlcharacters, varchar(3600) text: string ref, diff --git a/python/ql/test/3/library-tests/functions/Function.getAChildNode.expected b/python/ql/test/3/library-tests/functions/Function.getAChildNode.expected new file mode 100644 index 000000000000..2f6fe749f4a0 --- /dev/null +++ b/python/ql/test/3/library-tests/functions/Function.getAChildNode.expected @@ -0,0 +1,16 @@ +| test.py:4:1:11:2 | Function func | test.py:5:5:5:12 | pos_only | +| test.py:4:1:11:2 | Function func | test.py:7:5:7:10 | normal | +| test.py:4:1:11:2 | Function func | test.py:8:6:8:9 | args | +| test.py:4:1:11:2 | Function func | test.py:9:5:9:16 | keyword_only | +| test.py:4:1:11:2 | Function func | test.py:10:7:10:12 | kwargs | +| test.py:4:1:11:2 | Function func | test.py:12:5:12:41 | ExprStmt | +| test.py:4:1:11:2 | Function func | test.py:13:5:13:15 | ExprStmt | +| test.py:4:1:11:2 | Function func | test.py:14:5:14:17 | ExprStmt | +| test.py:23:1:31:2 | Function func2 | test.py:24:5:24:11 | pos_req | +| test.py:23:1:31:2 | Function func2 | test.py:25:5:25:17 | pos_w_default | +| test.py:23:1:31:2 | Function func2 | test.py:26:5:26:18 | pos_w_default2 | +| test.py:23:1:31:2 | Function func2 | test.py:28:5:28:15 | keyword_req | +| test.py:23:1:31:2 | Function func2 | test.py:29:5:29:21 | keyword_w_default | +| test.py:23:1:31:2 | Function func2 | test.py:30:5:30:20 | keyword_also_req | +| test.py:23:1:31:2 | Function func2 | test.py:32:5:32:18 | ExprStmt | +| test.py:23:1:31:2 | Function func2 | test.py:33:5:40:5 | ExprStmt | diff --git a/python/ql/test/3/library-tests/functions/Function.getAChildNode.ql b/python/ql/test/3/library-tests/functions/Function.getAChildNode.ql new file mode 100644 index 000000000000..222d30481196 --- /dev/null +++ b/python/ql/test/3/library-tests/functions/Function.getAChildNode.ql @@ -0,0 +1,4 @@ +import python + +from Function f +select f, f.getAChildNode() diff --git a/python/ql/test/3/library-tests/functions/Function.getArg.expected b/python/ql/test/3/library-tests/functions/Function.getArg.expected new file mode 100644 index 000000000000..0469a6db200b --- /dev/null +++ b/python/ql/test/3/library-tests/functions/Function.getArg.expected @@ -0,0 +1,5 @@ +| test.py:4:1:11:2 | Function func | 0 | test.py:5:5:5:12 | Parameter | +| test.py:4:1:11:2 | Function func | 1 | test.py:7:5:7:10 | Parameter | +| test.py:23:1:31:2 | Function func2 | 0 | test.py:24:5:24:11 | Parameter | +| test.py:23:1:31:2 | Function func2 | 1 | test.py:25:5:25:17 | Parameter | +| test.py:23:1:31:2 | Function func2 | 2 | test.py:26:5:26:18 | Parameter | diff --git a/python/ql/test/3/library-tests/functions/Function.getArg.ql b/python/ql/test/3/library-tests/functions/Function.getArg.ql new file mode 100644 index 000000000000..660a27143379 --- /dev/null +++ b/python/ql/test/3/library-tests/functions/Function.getArg.ql @@ -0,0 +1,4 @@ +import python + +from Function f, int i +select f, i, f.getArg(i) diff --git a/python/ql/test/3/library-tests/functions/Function.getArgByName.expected b/python/ql/test/3/library-tests/functions/Function.getArgByName.expected new file mode 100644 index 000000000000..48682cdd5e0f --- /dev/null +++ b/python/ql/test/3/library-tests/functions/Function.getArgByName.expected @@ -0,0 +1,9 @@ +| test.py:4:1:11:2 | Function func | keyword_only | test.py:9:5:9:16 | Parameter | +| test.py:4:1:11:2 | Function func | normal | test.py:7:5:7:10 | Parameter | +| test.py:4:1:11:2 | Function func | pos_only | test.py:5:5:5:12 | Parameter | +| test.py:23:1:31:2 | Function func2 | keyword_also_req | test.py:30:5:30:20 | Parameter | +| test.py:23:1:31:2 | Function func2 | keyword_req | test.py:28:5:28:15 | Parameter | +| test.py:23:1:31:2 | Function func2 | keyword_w_default | test.py:29:5:29:21 | Parameter | +| test.py:23:1:31:2 | Function func2 | pos_req | test.py:24:5:24:11 | Parameter | +| test.py:23:1:31:2 | Function func2 | pos_w_default | test.py:25:5:25:17 | Parameter | +| test.py:23:1:31:2 | Function func2 | pos_w_default2 | test.py:26:5:26:18 | Parameter | diff --git a/python/ql/test/3/library-tests/functions/Function.getArgByName.ql b/python/ql/test/3/library-tests/functions/Function.getArgByName.ql new file mode 100644 index 000000000000..75f16f985a98 --- /dev/null +++ b/python/ql/test/3/library-tests/functions/Function.getArgByName.ql @@ -0,0 +1,4 @@ +import python + +from Function f, string name +select f, name, f.getArgByName(name) diff --git a/python/ql/test/3/library-tests/functions/FunctionExpr.getASubExpression.expected b/python/ql/test/3/library-tests/functions/FunctionExpr.getASubExpression.expected new file mode 100644 index 000000000000..a4ef726012a9 --- /dev/null +++ b/python/ql/test/3/library-tests/functions/FunctionExpr.getASubExpression.expected @@ -0,0 +1,13 @@ +| test.py:4:1:11:2 | FunctionExpr | test.py:5:15:5:17 | int | +| test.py:4:1:11:2 | FunctionExpr | test.py:5:21:5:22 | UnaryExpr | +| test.py:4:1:11:2 | FunctionExpr | test.py:7:13:7:15 | int | +| test.py:4:1:11:2 | FunctionExpr | test.py:7:19:7:20 | UnaryExpr | +| test.py:4:1:11:2 | FunctionExpr | test.py:8:12:8:23 | Str | +| test.py:4:1:11:2 | FunctionExpr | test.py:9:19:9:21 | int | +| test.py:4:1:11:2 | FunctionExpr | test.py:9:25:9:26 | UnaryExpr | +| test.py:4:1:11:2 | FunctionExpr | test.py:10:15:10:30 | Str | +| test.py:23:1:31:2 | FunctionExpr | test.py:25:20:25:24 | Str | +| test.py:23:1:31:2 | FunctionExpr | test.py:25:28:25:31 | None | +| test.py:23:1:31:2 | FunctionExpr | test.py:26:20:26:23 | None | +| test.py:23:1:31:2 | FunctionExpr | test.py:29:24:29:28 | Str | +| test.py:23:1:31:2 | FunctionExpr | test.py:29:32:29:35 | None | diff --git a/python/ql/test/3/library-tests/functions/FunctionExpr.getASubExpression.ql b/python/ql/test/3/library-tests/functions/FunctionExpr.getASubExpression.ql new file mode 100644 index 000000000000..16acf1fda311 --- /dev/null +++ b/python/ql/test/3/library-tests/functions/FunctionExpr.getASubExpression.ql @@ -0,0 +1,4 @@ +import python + +from FunctionExpr fe +select fe, fe.getASubExpression() diff --git a/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getAnnotation.expected b/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getAnnotation.expected new file mode 100644 index 000000000000..71573e3ad262 --- /dev/null +++ b/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getAnnotation.expected @@ -0,0 +1,3 @@ +| test.py:4:1:11:2 | FunctionExpr | 0 | test.py:5:15:5:17 | int | +| test.py:4:1:11:2 | FunctionExpr | 1 | test.py:7:13:7:15 | int | +| test.py:23:1:31:2 | FunctionExpr | 1 | test.py:25:20:25:24 | Str | diff --git a/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getAnnotation.ql b/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getAnnotation.ql new file mode 100644 index 000000000000..a1fdd4d443bb --- /dev/null +++ b/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getAnnotation.ql @@ -0,0 +1,4 @@ +import python + +from FunctionExpr fe, int i +select fe, i, fe.getArgs().getAnnotation(i) diff --git a/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getDefault.expected b/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getDefault.expected new file mode 100644 index 000000000000..5e50bddb200a --- /dev/null +++ b/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getDefault.expected @@ -0,0 +1,4 @@ +| test.py:4:1:11:2 | FunctionExpr | 0 | test.py:5:21:5:22 | UnaryExpr | +| test.py:4:1:11:2 | FunctionExpr | 1 | test.py:7:19:7:20 | UnaryExpr | +| test.py:23:1:31:2 | FunctionExpr | 1 | test.py:25:28:25:31 | None | +| test.py:23:1:31:2 | FunctionExpr | 2 | test.py:26:20:26:23 | None | diff --git a/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getDefault.ql b/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getDefault.ql new file mode 100644 index 000000000000..21ceeef54913 --- /dev/null +++ b/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getDefault.ql @@ -0,0 +1,4 @@ +import python + +from FunctionExpr fe, int i +select fe, i, fe.getArgs().getDefault(i) diff --git a/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getKwAnnotation.expected b/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getKwAnnotation.expected new file mode 100644 index 000000000000..c3e879fb7223 --- /dev/null +++ b/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getKwAnnotation.expected @@ -0,0 +1,2 @@ +| test.py:4:1:11:2 | FunctionExpr | 0 | test.py:9:19:9:21 | int | +| test.py:23:1:31:2 | FunctionExpr | 1 | test.py:29:24:29:28 | Str | diff --git a/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getKwAnnotation.ql b/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getKwAnnotation.ql new file mode 100644 index 000000000000..935dd68243ce --- /dev/null +++ b/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getKwAnnotation.ql @@ -0,0 +1,4 @@ +import python + +from FunctionExpr fe, int i +select fe, i, fe.getArgs().getKwAnnotation(i) diff --git a/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getKwDefault.expected b/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getKwDefault.expected new file mode 100644 index 000000000000..c5ba91814e5a --- /dev/null +++ b/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getKwDefault.expected @@ -0,0 +1,2 @@ +| test.py:4:1:11:2 | FunctionExpr | 0 | test.py:9:25:9:26 | UnaryExpr | +| test.py:23:1:31:2 | FunctionExpr | 1 | test.py:29:32:29:35 | None | diff --git a/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getKwDefault.ql b/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getKwDefault.ql new file mode 100644 index 000000000000..0bf959b21795 --- /dev/null +++ b/python/ql/test/3/library-tests/functions/FunctionExpr.getArgs.getKwDefault.ql @@ -0,0 +1,4 @@ +import python + +from FunctionExpr fe, int i +select fe, i, fe.getArgs().getKwDefault(i) diff --git a/python/ql/test/3/library-tests/functions/test.py b/python/ql/test/3/library-tests/functions/test.py new file mode 100644 index 000000000000..a81714491c0d --- /dev/null +++ b/python/ql/test/3/library-tests/functions/test.py @@ -0,0 +1,43 @@ +# not importing typing so we don't need to filter by location in Ql tests + + +def func( + pos_only: int = -1, + /, + normal: int = -2, + *args: "Tuple[str]", + keyword_only: int = -3, + **kwargs: "Dict[str, str]", +): + print(pos_only, normal, keyword_only) + print(args) + print(kwargs) + + +func(1, 2, keyword_only=3) +func(4, normal=5, keyword_only=6) + +func(1, 2, "varargs0", "varargs1", keyword_only=3, kwargs0="0", kwargs1="1") + + +def func2( + pos_req, + pos_w_default: "foo" = None, + pos_w_default2=None, + *, + keyword_req, + keyword_w_default: "foo" = None, + keyword_also_req, +): + print("func2") + print( + pos_req, + pos_w_default, + pos_w_default2, + keyword_req, + keyword_w_default, + keyword_also_req, + ) + + +func2(1, keyword_req=2, keyword_also_req=3) diff --git a/python/ql/test/3/library-tests/parameters/Annotations.expected b/python/ql/test/3/library-tests/parameters/Annotations.expected new file mode 100644 index 000000000000..91835eac4194 --- /dev/null +++ b/python/ql/test/3/library-tests/parameters/Annotations.expected @@ -0,0 +1,7 @@ +| args | test.py:8:12:8:23 | Str | +| keyword_only | test.py:9:19:9:21 | int | +| keyword_w_default | test.py:29:24:29:28 | Str | +| kwargs | test.py:10:15:10:30 | Str | +| normal | test.py:7:13:7:15 | int | +| pos_only | test.py:5:15:5:17 | int | +| pos_w_default | test.py:25:20:25:24 | Str | diff --git a/python/ql/test/3/library-tests/parameters/Annotations.ql b/python/ql/test/3/library-tests/parameters/Annotations.ql new file mode 100644 index 000000000000..17b02844a44f --- /dev/null +++ b/python/ql/test/3/library-tests/parameters/Annotations.ql @@ -0,0 +1,4 @@ +import python + +from Parameter p +select p.getName(), p.getAnnotation() diff --git a/python/ql/test/3/library-tests/parameters/Defaults.expected b/python/ql/test/3/library-tests/parameters/Defaults.expected new file mode 100644 index 000000000000..84cd7967c806 --- /dev/null +++ b/python/ql/test/3/library-tests/parameters/Defaults.expected @@ -0,0 +1,6 @@ +| keyword_only | test.py:9:25:9:26 | UnaryExpr | +| keyword_w_default | test.py:29:32:29:35 | None | +| normal | test.py:7:19:7:20 | UnaryExpr | +| pos_only | test.py:5:21:5:22 | UnaryExpr | +| pos_w_default | test.py:25:28:25:31 | None | +| pos_w_default2 | test.py:26:20:26:23 | None | diff --git a/python/ql/test/3/library-tests/parameters/Defaults.ql b/python/ql/test/3/library-tests/parameters/Defaults.ql new file mode 100644 index 000000000000..ebc8215074bc --- /dev/null +++ b/python/ql/test/3/library-tests/parameters/Defaults.ql @@ -0,0 +1,4 @@ +import python + +from Parameter p +select p.getName(), p.getDefault() diff --git a/python/ql/test/3/library-tests/parameters/Special.expected b/python/ql/test/3/library-tests/parameters/Special.expected new file mode 100644 index 000000000000..2b81e393e5e7 --- /dev/null +++ b/python/ql/test/3/library-tests/parameters/Special.expected @@ -0,0 +1,11 @@ +| args | varargs | +| keyword_also_req | normal | +| keyword_only | normal | +| keyword_req | normal | +| keyword_w_default | normal | +| kwargs | kwargs | +| normal | normal | +| pos_only | normal | +| pos_req | normal | +| pos_w_default | normal | +| pos_w_default2 | normal | diff --git a/python/ql/test/3/library-tests/parameters/Special.ql b/python/ql/test/3/library-tests/parameters/Special.ql new file mode 100644 index 000000000000..4987599bc720 --- /dev/null +++ b/python/ql/test/3/library-tests/parameters/Special.ql @@ -0,0 +1,10 @@ +import python + +from Parameter p, string type +where + p.isKwargs() and type = "kwargs" + or + p.isVarargs() and type = "varargs" + or + not p.isKwargs() and not p.isVarargs() and type = "normal" +select p.getName(), type diff --git a/python/ql/test/3/library-tests/parameters/test.py b/python/ql/test/3/library-tests/parameters/test.py new file mode 100644 index 000000000000..a81714491c0d --- /dev/null +++ b/python/ql/test/3/library-tests/parameters/test.py @@ -0,0 +1,43 @@ +# not importing typing so we don't need to filter by location in Ql tests + + +def func( + pos_only: int = -1, + /, + normal: int = -2, + *args: "Tuple[str]", + keyword_only: int = -3, + **kwargs: "Dict[str, str]", +): + print(pos_only, normal, keyword_only) + print(args) + print(kwargs) + + +func(1, 2, keyword_only=3) +func(4, normal=5, keyword_only=6) + +func(1, 2, "varargs0", "varargs1", keyword_only=3, kwargs0="0", kwargs1="1") + + +def func2( + pos_req, + pos_w_default: "foo" = None, + pos_w_default2=None, + *, + keyword_req, + keyword_w_default: "foo" = None, + keyword_also_req, +): + print("func2") + print( + pos_req, + pos_w_default, + pos_w_default2, + keyword_req, + keyword_w_default, + keyword_also_req, + ) + + +func2(1, keyword_req=2, keyword_also_req=3) diff --git a/python/upgrades/f635b392038a494915307f913657cd3058f9b476/old.dbscheme b/python/upgrades/f635b392038a494915307f913657cd3058f9b476/old.dbscheme new file mode 100644 index 000000000000..f635b392038a --- /dev/null +++ b/python/upgrades/f635b392038a494915307f913657cd3058f9b476/old.dbscheme @@ -0,0 +1,988 @@ +/* + * This dbscheme is auto-generated by 'semmle/dbscheme_gen.py'. + * WARNING: Any modifications to this file will be lost. + * Relations can be changed by modifying master.py or + * by adding rules to dbscheme.template + */ + + /* + * External artifacts + */ + +externalDefects( + unique int id : @externalDefect, + varchar(900) queryPath : string ref, + int location : @location ref, + varchar(900) message : string ref, + float severity : float ref +); + +externalMetrics( + unique int id : @externalMetric, + varchar(900) queryPath : string ref, + int location : @location ref, + float value : float ref +); + +externalData( + int id : @externalDataElement, + varchar(900) queryPath : string ref, + int column: int ref, + varchar(900) data : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/* + * Line metrics + */ +py_codelines(int id : @py_scope ref, + int count : int ref); + +py_commentlines(int id : @py_scope ref, + int count : int ref); + +py_docstringlines(int id : @py_scope ref, + int count : int ref); + +py_alllines(int id : @py_scope ref, + int count : int ref); + +/* + * Version history + */ + +svnentries( + int id : @svnentry, + varchar(500) revision : string ref, + varchar(500) author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + varchar(500) action : string ref +) + +svnentrymsg( + int id : @svnentry ref, + varchar(500) message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/**************************** + Python dbscheme +****************************/ + +/* fromSource is ignored */ +files(unique int id: @file, + varchar(900) name: string ref, + varchar(900) simple: string ref, + varchar(900) ext: string ref, + int fromSource: int ref); + +folders(unique int id: @folder, + varchar(900) name: string ref, + varchar(900) simple: string ref); + +@container = @folder | @file; + +containerparent(int parent: @container ref, + unique int child: @container ref); + +@sourceline = @file | @py_Module | @xmllocatable; + +numlines(int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref + ); + +@location = @location_ast | @location_default ; + +locations_default(unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +locations_ast(unique int id: @location_ast, + int module: @py_Module ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +file_contents(unique int file: @file ref, string contents: string ref); + +py_module_path(int module: @py_Module ref, int file: @container ref); + +variable(unique int id : @py_variable, + int scope : @py_scope ref, + varchar(1) name : string ref); + +py_line_lengths(unique int id : @py_line, + int file: @py_Module ref, + int line : int ref, + int length : int ref); + +py_extracted_version(int module : @py_Module ref, + varchar(1) version : string ref); + +/* AUTO GENERATED PART STARTS HERE */ + + +/* AnnAssign.location = 0, location */ +/* AnnAssign.value = 1, expr */ +/* AnnAssign.annotation = 2, expr */ +/* AnnAssign.target = 3, expr */ + +/* Assert.location = 0, location */ +/* Assert.test = 1, expr */ +/* Assert.msg = 2, expr */ + +/* Assign.location = 0, location */ +/* Assign.value = 1, expr */ +/* Assign.targets = 2, expr_list */ + +/* AssignExpr.location = 0, location */ +/* AssignExpr.parenthesised = 1, bool */ +/* AssignExpr.value = 2, expr */ +/* AssignExpr.target = 3, expr */ + +/* Attribute.location = 0, location */ +/* Attribute.parenthesised = 1, bool */ +/* Attribute.value = 2, expr */ +/* Attribute.attr = 3, str */ +/* Attribute.ctx = 4, expr_context */ + +/* AugAssign.location = 0, location */ +/* AugAssign.operation = 1, BinOp */ + +/* Await.location = 0, location */ +/* Await.parenthesised = 1, bool */ +/* Await.value = 2, expr */ + +/* BinaryExpr.location = 0, location */ +/* BinaryExpr.parenthesised = 1, bool */ +/* BinaryExpr.left = 2, expr */ +/* BinaryExpr.op = 3, operator */ +/* BinaryExpr.right = 4, expr */ +/* BinaryExpr = AugAssign */ + +/* BoolExpr.location = 0, location */ +/* BoolExpr.parenthesised = 1, bool */ +/* BoolExpr.op = 2, boolop */ +/* BoolExpr.values = 3, expr_list */ + +/* Break.location = 0, location */ + +/* Bytes.location = 0, location */ +/* Bytes.parenthesised = 1, bool */ +/* Bytes.s = 2, bytes */ +/* Bytes.prefix = 3, bytes */ +/* Bytes.implicitly_concatenated_parts = 4, StringPart_list */ + +/* Call.location = 0, location */ +/* Call.parenthesised = 1, bool */ +/* Call.func = 2, expr */ +/* Call.positional_args = 3, expr_list */ +/* Call.named_args = 4, dict_item_list */ + +/* Class.name = 0, str */ +/* Class.body = 1, stmt_list */ +/* Class = ClassExpr */ + +/* ClassExpr.location = 0, location */ +/* ClassExpr.parenthesised = 1, bool */ +/* ClassExpr.name = 2, str */ +/* ClassExpr.bases = 3, expr_list */ +/* ClassExpr.keywords = 4, dict_item_list */ +/* ClassExpr.inner_scope = 5, Class */ + +/* Compare.location = 0, location */ +/* Compare.parenthesised = 1, bool */ +/* Compare.left = 2, expr */ +/* Compare.ops = 3, cmpop_list */ +/* Compare.comparators = 4, expr_list */ + +/* Continue.location = 0, location */ + +/* Delete.location = 0, location */ +/* Delete.targets = 1, expr_list */ + +/* Dict.location = 0, location */ +/* Dict.parenthesised = 1, bool */ +/* Dict.items = 2, dict_item_list */ + +/* DictComp.location = 0, location */ +/* DictComp.parenthesised = 1, bool */ +/* DictComp.function = 2, Function */ +/* DictComp.iterable = 3, expr */ + +/* DictUnpacking.location = 0, location */ +/* DictUnpacking.value = 1, expr */ + +/* Ellipsis.location = 0, location */ +/* Ellipsis.parenthesised = 1, bool */ + +/* ExceptStmt.location = 0, location */ +/* ExceptStmt.type = 1, expr */ +/* ExceptStmt.name = 2, expr */ +/* ExceptStmt.body = 3, stmt_list */ + +/* Exec.location = 0, location */ +/* Exec.body = 1, expr */ +/* Exec.globals = 2, expr */ +/* Exec.locals = 3, expr */ + +/* ExprStmt.location = 0, location */ +/* ExprStmt.value = 1, expr */ + +/* Filter.location = 0, location */ +/* Filter.parenthesised = 1, bool */ +/* Filter.value = 2, expr */ +/* Filter.filter = 3, expr */ + +/* For.location = 0, location */ +/* For.target = 1, expr */ +/* For.iter = 2, expr */ +/* For.body = 3, stmt_list */ +/* For.orelse = 4, stmt_list */ +/* For.is_async = 5, bool */ + +/* FormattedValue.location = 0, location */ +/* FormattedValue.parenthesised = 1, bool */ +/* FormattedValue.value = 2, expr */ +/* FormattedValue.conversion = 3, str */ +/* FormattedValue.format_spec = 4, JoinedStr */ + +/* Function.name = 0, str */ +/* Function.args = 1, parameter_list */ +/* Function.vararg = 2, expr */ +/* Function.kwonlyargs = 3, expr_list */ +/* Function.kwarg = 4, expr */ +/* Function.body = 5, stmt_list */ +/* Function.is_async = 6, bool */ +/* Function = FunctionParent */ + +/* FunctionExpr.location = 0, location */ +/* FunctionExpr.parenthesised = 1, bool */ +/* FunctionExpr.name = 2, str */ +/* FunctionExpr.args = 3, arguments */ +/* FunctionExpr.returns = 4, expr */ +/* FunctionExpr.inner_scope = 5, Function */ + +/* GeneratorExp.location = 0, location */ +/* GeneratorExp.parenthesised = 1, bool */ +/* GeneratorExp.function = 2, Function */ +/* GeneratorExp.iterable = 3, expr */ + +/* Global.location = 0, location */ +/* Global.names = 1, str_list */ + +/* If.location = 0, location */ +/* If.test = 1, expr */ +/* If.body = 2, stmt_list */ +/* If.orelse = 3, stmt_list */ + +/* IfExp.location = 0, location */ +/* IfExp.parenthesised = 1, bool */ +/* IfExp.test = 2, expr */ +/* IfExp.body = 3, expr */ +/* IfExp.orelse = 4, expr */ + +/* Import.location = 0, location */ +/* Import.names = 1, alias_list */ + +/* ImportExpr.location = 0, location */ +/* ImportExpr.parenthesised = 1, bool */ +/* ImportExpr.level = 2, int */ +/* ImportExpr.name = 3, str */ +/* ImportExpr.top = 4, bool */ + +/* ImportStar.location = 0, location */ +/* ImportStar.module = 1, expr */ + +/* ImportMember.location = 0, location */ +/* ImportMember.parenthesised = 1, bool */ +/* ImportMember.module = 2, expr */ +/* ImportMember.name = 3, str */ + +/* Fstring.location = 0, location */ +/* Fstring.parenthesised = 1, bool */ +/* Fstring.values = 2, expr_list */ +/* Fstring = FormattedValue */ + +/* KeyValuePair.location = 0, location */ +/* KeyValuePair.value = 1, expr */ +/* KeyValuePair.key = 2, expr */ + +/* Lambda.location = 0, location */ +/* Lambda.parenthesised = 1, bool */ +/* Lambda.args = 2, arguments */ +/* Lambda.inner_scope = 3, Function */ + +/* List.location = 0, location */ +/* List.parenthesised = 1, bool */ +/* List.elts = 2, expr_list */ +/* List.ctx = 3, expr_context */ + +/* ListComp.location = 0, location */ +/* ListComp.parenthesised = 1, bool */ +/* ListComp.function = 2, Function */ +/* ListComp.iterable = 3, expr */ +/* ListComp.generators = 4, comprehension_list */ +/* ListComp.elt = 5, expr */ + +/* Module.name = 0, str */ +/* Module.hash = 1, str */ +/* Module.body = 2, stmt_list */ +/* Module.kind = 3, str */ + +/* Name.location = 0, location */ +/* Name.parenthesised = 1, bool */ +/* Name.variable = 2, variable */ +/* Name.ctx = 3, expr_context */ +/* Name = ParameterList */ + +/* Nonlocal.location = 0, location */ +/* Nonlocal.names = 1, str_list */ + +/* Num.location = 0, location */ +/* Num.parenthesised = 1, bool */ +/* Num.n = 2, number */ +/* Num.text = 3, number */ + +/* Pass.location = 0, location */ + +/* PlaceHolder.location = 0, location */ +/* PlaceHolder.parenthesised = 1, bool */ +/* PlaceHolder.variable = 2, variable */ +/* PlaceHolder.ctx = 3, expr_context */ + +/* Print.location = 0, location */ +/* Print.dest = 1, expr */ +/* Print.values = 2, expr_list */ +/* Print.nl = 3, bool */ + +/* Raise.location = 0, location */ +/* Raise.exc = 1, expr */ +/* Raise.cause = 2, expr */ +/* Raise.type = 3, expr */ +/* Raise.inst = 4, expr */ +/* Raise.tback = 5, expr */ + +/* Repr.location = 0, location */ +/* Repr.parenthesised = 1, bool */ +/* Repr.value = 2, expr */ + +/* Return.location = 0, location */ +/* Return.value = 1, expr */ + +/* Set.location = 0, location */ +/* Set.parenthesised = 1, bool */ +/* Set.elts = 2, expr_list */ + +/* SetComp.location = 0, location */ +/* SetComp.parenthesised = 1, bool */ +/* SetComp.function = 2, Function */ +/* SetComp.iterable = 3, expr */ + +/* Slice.location = 0, location */ +/* Slice.parenthesised = 1, bool */ +/* Slice.start = 2, expr */ +/* Slice.stop = 3, expr */ +/* Slice.step = 4, expr */ + +/* SpecialOperation.location = 0, location */ +/* SpecialOperation.parenthesised = 1, bool */ +/* SpecialOperation.name = 2, str */ +/* SpecialOperation.arguments = 3, expr_list */ + +/* Starred.location = 0, location */ +/* Starred.parenthesised = 1, bool */ +/* Starred.value = 2, expr */ +/* Starred.ctx = 3, expr_context */ + +/* Str.location = 0, location */ +/* Str.parenthesised = 1, bool */ +/* Str.s = 2, str */ +/* Str.prefix = 3, str */ +/* Str.implicitly_concatenated_parts = 4, StringPart_list */ + +/* StringPart.text = 0, str */ +/* StringPart.location = 1, location */ +/* StringPart = StringPartList */ +/* StringPartList = BytesOrStr */ + +/* Subscript.location = 0, location */ +/* Subscript.parenthesised = 1, bool */ +/* Subscript.value = 2, expr */ +/* Subscript.index = 3, expr */ +/* Subscript.ctx = 4, expr_context */ + +/* TemplateDottedNotation.location = 0, location */ +/* TemplateDottedNotation.parenthesised = 1, bool */ +/* TemplateDottedNotation.value = 2, expr */ +/* TemplateDottedNotation.attr = 3, str */ +/* TemplateDottedNotation.ctx = 4, expr_context */ + +/* TemplateWrite.location = 0, location */ +/* TemplateWrite.value = 1, expr */ + +/* Try.location = 0, location */ +/* Try.body = 1, stmt_list */ +/* Try.orelse = 2, stmt_list */ +/* Try.handlers = 3, stmt_list */ +/* Try.finalbody = 4, stmt_list */ + +/* Tuple.location = 0, location */ +/* Tuple.parenthesised = 1, bool */ +/* Tuple.elts = 2, expr_list */ +/* Tuple.ctx = 3, expr_context */ +/* Tuple = ParameterList */ + +/* UnaryExpr.location = 0, location */ +/* UnaryExpr.parenthesised = 1, bool */ +/* UnaryExpr.op = 2, unaryop */ +/* UnaryExpr.operand = 3, expr */ + +/* While.location = 0, location */ +/* While.test = 1, expr */ +/* While.body = 2, stmt_list */ +/* While.orelse = 3, stmt_list */ + +/* With.location = 0, location */ +/* With.context_expr = 1, expr */ +/* With.optional_vars = 2, expr */ +/* With.body = 3, stmt_list */ +/* With.is_async = 4, bool */ + +/* Yield.location = 0, location */ +/* Yield.parenthesised = 1, bool */ +/* Yield.value = 2, expr */ + +/* YieldFrom.location = 0, location */ +/* YieldFrom.parenthesised = 1, bool */ +/* YieldFrom.value = 2, expr */ + +/* Alias.value = 0, expr */ +/* Alias.asname = 1, expr */ +/* Alias = AliasList */ +/* AliasList = Import */ + +/* Arguments.kw_defaults = 0, expr_list */ +/* Arguments.defaults = 1, expr_list */ +/* Arguments.annotations = 2, expr_list */ +/* Arguments.varargannotation = 3, expr */ +/* Arguments.kwargannotation = 4, expr */ +/* Arguments.kw_annotations = 5, expr_list */ +/* Arguments = ArgumentsParent */ +/* boolean = BoolParent */ +/* Boolop = BoolExpr */ +/* string = Bytes */ +/* Cmpop = CmpopList */ +/* CmpopList = Compare */ + +/* Comprehension.location = 0, location */ +/* Comprehension.iter = 1, expr */ +/* Comprehension.target = 2, expr */ +/* Comprehension.ifs = 3, expr_list */ +/* Comprehension = ComprehensionList */ +/* ComprehensionList = ListComp */ +/* DictItem = DictItemList */ +/* DictItemList = DictItemListParent */ + +/* Expr.location = 0, location */ +/* Expr.parenthesised = 1, bool */ +/* Expr = ExprParent */ +/* ExprContext = ExprContextParent */ +/* ExprList = ExprListParent */ +/* int = ImportExpr */ + +/* Keyword.location = 0, location */ +/* Keyword.value = 1, expr */ +/* Keyword.arg = 2, str */ +/* Location = LocationParent */ +/* string = Num */ +/* Operator = BinaryExpr */ +/* ParameterList = Function */ + +/* Stmt.location = 0, location */ +/* Stmt = StmtList */ +/* StmtList = StmtListParent */ +/* string = StrParent */ +/* StringList = StrListParent */ +/* Unaryop = UnaryExpr */ +/* Variable = VariableParent */ +py_Classes(unique int id : @py_Class, + unique int parent : @py_ClassExpr ref); + +py_Functions(unique int id : @py_Function, + unique int parent : @py_Function_parent ref); + +py_Modules(unique int id : @py_Module); + +py_StringParts(unique int id : @py_StringPart, + int parent : @py_StringPart_list ref, + int idx : int ref); + +py_StringPart_lists(unique int id : @py_StringPart_list, + unique int parent : @py_Bytes_or_Str ref); + +py_aliases(unique int id : @py_alias, + int parent : @py_alias_list ref, + int idx : int ref); + +py_alias_lists(unique int id : @py_alias_list, + unique int parent : @py_Import ref); + +py_arguments(unique int id : @py_arguments, + unique int parent : @py_arguments_parent ref); + +py_bools(int parent : @py_bool_parent ref, + int idx : int ref); + +py_boolops(unique int id : @py_boolop, + int kind: int ref, + unique int parent : @py_BoolExpr ref); + +py_bytes(varchar(1) id : string ref, + int parent : @py_Bytes ref, + int idx : int ref); + +py_cmpops(unique int id : @py_cmpop, + int kind: int ref, + int parent : @py_cmpop_list ref, + int idx : int ref); + +py_cmpop_lists(unique int id : @py_cmpop_list, + unique int parent : @py_Compare ref); + +py_comprehensions(unique int id : @py_comprehension, + int parent : @py_comprehension_list ref, + int idx : int ref); + +py_comprehension_lists(unique int id : @py_comprehension_list, + unique int parent : @py_ListComp ref); + +py_dict_items(unique int id : @py_dict_item, + int kind: int ref, + int parent : @py_dict_item_list ref, + int idx : int ref); + +py_dict_item_lists(unique int id : @py_dict_item_list, + unique int parent : @py_dict_item_list_parent ref); + +py_exprs(unique int id : @py_expr, + int kind: int ref, + int parent : @py_expr_parent ref, + int idx : int ref); + +py_expr_contexts(unique int id : @py_expr_context, + int kind: int ref, + unique int parent : @py_expr_context_parent ref); + +py_expr_lists(unique int id : @py_expr_list, + int parent : @py_expr_list_parent ref, + int idx : int ref); + +py_ints(int id : int ref, + unique int parent : @py_ImportExpr ref); + +py_locations(unique int id : @location ref, + unique int parent : @py_location_parent ref); + +py_numbers(varchar(1) id : string ref, + int parent : @py_Num ref, + int idx : int ref); + +py_operators(unique int id : @py_operator, + int kind: int ref, + unique int parent : @py_BinaryExpr ref); + +py_parameter_lists(unique int id : @py_parameter_list, + unique int parent : @py_Function ref); + +py_stmts(unique int id : @py_stmt, + int kind: int ref, + int parent : @py_stmt_list ref, + int idx : int ref); + +py_stmt_lists(unique int id : @py_stmt_list, + int parent : @py_stmt_list_parent ref, + int idx : int ref); + +py_strs(varchar(1) id : string ref, + int parent : @py_str_parent ref, + int idx : int ref); + +py_str_lists(unique int id : @py_str_list, + unique int parent : @py_str_list_parent ref); + +py_unaryops(unique int id : @py_unaryop, + int kind: int ref, + unique int parent : @py_UnaryExpr ref); + +py_variables(int id : @py_variable ref, + unique int parent : @py_variable_parent ref); + +case @py_boolop.kind of + 0 = @py_And +| 1 = @py_Or; + +case @py_cmpop.kind of + 0 = @py_Eq +| 1 = @py_Gt +| 2 = @py_GtE +| 3 = @py_In +| 4 = @py_Is +| 5 = @py_IsNot +| 6 = @py_Lt +| 7 = @py_LtE +| 8 = @py_NotEq +| 9 = @py_NotIn; + +case @py_dict_item.kind of + 0 = @py_DictUnpacking +| 1 = @py_KeyValuePair +| 2 = @py_keyword; + +case @py_expr.kind of + 0 = @py_Attribute +| 1 = @py_BinaryExpr +| 2 = @py_BoolExpr +| 3 = @py_Bytes +| 4 = @py_Call +| 5 = @py_ClassExpr +| 6 = @py_Compare +| 7 = @py_Dict +| 8 = @py_DictComp +| 9 = @py_Ellipsis +| 10 = @py_FunctionExpr +| 11 = @py_GeneratorExp +| 12 = @py_IfExp +| 13 = @py_ImportExpr +| 14 = @py_ImportMember +| 15 = @py_Lambda +| 16 = @py_List +| 17 = @py_ListComp +| 18 = @py_Name +| 19 = @py_Num +| 20 = @py_Repr +| 21 = @py_Set +| 22 = @py_SetComp +| 23 = @py_Slice +| 24 = @py_Starred +| 25 = @py_Str +| 26 = @py_Subscript +| 27 = @py_Tuple +| 28 = @py_UnaryExpr +| 29 = @py_Yield +| 30 = @py_YieldFrom +| 31 = @py_TemplateDottedNotation +| 32 = @py_Filter +| 33 = @py_PlaceHolder +| 34 = @py_Await +| 35 = @py_Fstring +| 36 = @py_FormattedValue +| 37 = @py_AssignExpr +| 38 = @py_SpecialOperation; + +case @py_expr_context.kind of + 0 = @py_AugLoad +| 1 = @py_AugStore +| 2 = @py_Del +| 3 = @py_Load +| 4 = @py_Param +| 5 = @py_Store; + +case @py_operator.kind of + 0 = @py_Add +| 1 = @py_BitAnd +| 2 = @py_BitOr +| 3 = @py_BitXor +| 4 = @py_Div +| 5 = @py_FloorDiv +| 6 = @py_LShift +| 7 = @py_Mod +| 8 = @py_Mult +| 9 = @py_Pow +| 10 = @py_RShift +| 11 = @py_Sub +| 12 = @py_MatMult; + +case @py_stmt.kind of + 0 = @py_Assert +| 1 = @py_Assign +| 2 = @py_AugAssign +| 3 = @py_Break +| 4 = @py_Continue +| 5 = @py_Delete +| 6 = @py_ExceptStmt +| 7 = @py_Exec +| 8 = @py_Expr_stmt +| 9 = @py_For +| 10 = @py_Global +| 11 = @py_If +| 12 = @py_Import +| 13 = @py_ImportStar +| 14 = @py_Nonlocal +| 15 = @py_Pass +| 16 = @py_Print +| 17 = @py_Raise +| 18 = @py_Return +| 19 = @py_Try +| 20 = @py_While +| 21 = @py_With +| 22 = @py_TemplateWrite +| 23 = @py_AnnAssign; + +case @py_unaryop.kind of + 0 = @py_Invert +| 1 = @py_Not +| 2 = @py_UAdd +| 3 = @py_USub; + +@py_Bytes_or_Str = @py_Bytes | @py_Str; + +@py_Function_parent = @py_DictComp | @py_FunctionExpr | @py_GeneratorExp | @py_Lambda | @py_ListComp | @py_SetComp; + +@py_arguments_parent = @py_FunctionExpr | @py_Lambda; + +@py_ast_node = @py_Class | @py_Function | @py_Module | @py_StringPart | @py_comprehension | @py_dict_item | @py_expr | @py_stmt; + +@py_bool_parent = @py_For | @py_Function | @py_Print | @py_With | @py_expr; + +@py_dict_item_list_parent = @py_Call | @py_ClassExpr | @py_Dict; + +@py_expr_context_parent = @py_Attribute | @py_List | @py_Name | @py_PlaceHolder | @py_Starred | @py_Subscript | @py_TemplateDottedNotation | @py_Tuple; + +@py_expr_list_parent = @py_Assign | @py_BoolExpr | @py_Call | @py_ClassExpr | @py_Compare | @py_Delete | @py_Fstring | @py_Function | @py_List | @py_Print | @py_Set | @py_SpecialOperation | @py_Tuple | @py_arguments | @py_comprehension; + +@py_expr_or_stmt = @py_expr | @py_stmt; + +@py_expr_parent = @py_AnnAssign | @py_Assert | @py_Assign | @py_AssignExpr | @py_Attribute | @py_AugAssign | @py_Await | @py_BinaryExpr | @py_Call | @py_Compare | @py_DictComp | @py_DictUnpacking | @py_ExceptStmt | @py_Exec | @py_Expr_stmt | @py_Filter | @py_For | @py_FormattedValue | @py_Function | @py_FunctionExpr | @py_GeneratorExp | @py_If | @py_IfExp | @py_ImportMember | @py_ImportStar | @py_KeyValuePair | @py_ListComp | @py_Print | @py_Raise | @py_Repr | @py_Return | @py_SetComp | @py_Slice | @py_Starred | @py_Subscript | @py_TemplateDottedNotation | @py_TemplateWrite | @py_UnaryExpr | @py_While | @py_With | @py_Yield | @py_YieldFrom | @py_alias | @py_arguments | @py_comprehension | @py_expr_list | @py_keyword | @py_parameter_list; + +@py_location_parent = @py_DictUnpacking | @py_KeyValuePair | @py_StringPart | @py_comprehension | @py_expr | @py_keyword | @py_stmt; + +@py_parameter = @py_Name | @py_Tuple; + +@py_scope = @py_Class | @py_Function | @py_Module; + +@py_stmt_list_parent = @py_Class | @py_ExceptStmt | @py_For | @py_Function | @py_If | @py_Module | @py_Try | @py_While | @py_With; + +@py_str_list_parent = @py_Global | @py_Nonlocal; + +@py_str_parent = @py_Attribute | @py_Class | @py_ClassExpr | @py_FormattedValue | @py_Function | @py_FunctionExpr | @py_ImportExpr | @py_ImportMember | @py_Module | @py_SpecialOperation | @py_Str | @py_StringPart | @py_TemplateDottedNotation | @py_keyword | @py_str_list; + +@py_variable_parent = @py_Name | @py_PlaceHolder; + + +/* + * End of auto-generated part + */ + + + +/* Map relative names to absolute names for imports */ +py_absolute_names(int module : @py_Module ref, + varchar(1) relname : string ref, + varchar(1) absname : string ref); + +py_exports(int id : @py_Module ref, + varchar(1) name : string ref); + +/* Successor information */ +py_successors(int predecessor : @py_flow_node ref, + int successor : @py_flow_node ref); + +py_true_successors(int predecessor : @py_flow_node ref, + int successor : @py_flow_node ref); + +py_exception_successors(int predecessor : @py_flow_node ref, + int successor : @py_flow_node ref); + +py_false_successors(int predecessor : @py_flow_node ref, + int successor : @py_flow_node ref); + +py_flow_bb_node(unique int flownode : @py_flow_node, + int realnode : @py_ast_node ref, + int basicblock : @py_flow_node ref, + int index : int ref); + +py_scope_flow(int flow : @py_flow_node ref, + int scope : @py_scope ref, + int kind : int ref); + +py_idoms(unique int node : @py_flow_node ref, + int immediate_dominator : @py_flow_node ref); + +py_ssa_phi(int phi : @py_ssa_var ref, + int arg: @py_ssa_var ref); + +py_ssa_var(unique int id : @py_ssa_var, + int var : @py_variable ref); + +py_ssa_use(int node: @py_flow_node ref, + int var : @py_ssa_var ref); + +py_ssa_defn(unique int id : @py_ssa_var ref, + int node: @py_flow_node ref); + +@py_base_var = @py_variable | @py_ssa_var; + +py_scopes(unique int node : @py_expr_or_stmt ref, + int scope : @py_scope ref); + +py_scope_location(unique int id : @location ref, + unique int scope : @py_scope ref); + +py_flags_versioned(varchar(1) name : string ref, + varchar(1) value : string ref, + varchar(1) version : string ref); + +py_syntax_error_versioned(unique int id : @location ref, + varchar(1) message : string ref, + varchar(1) version : string ref); + +py_comments(unique int id : @py_comment, + varchar(1) text : string ref, + unique int location : @location ref); + +/* Type information support */ + +py_cobjects(unique int obj : @py_cobject); + +py_cobjecttypes(unique int obj : @py_cobject ref, + int typeof : @py_cobject ref); + +py_cobjectnames(unique int obj : @py_cobject ref, + varchar(1) name : string ref); + +/* Kind should be 0 for introspection, > 0 from source, as follows: + 1 from C extension source + */ +py_cobject_sources(int obj : @py_cobject ref, + int kind : int ref); + +py_cmembers_versioned(int object : @py_cobject ref, + varchar(1) name : string ref, + int member : @py_cobject ref, + varchar(1) version : string ref); + +py_citems(int object : @py_cobject ref, + int index : int ref, + int member : @py_cobject ref); + +ext_argtype(int funcid : @py_object ref, + int arg : int ref, + int typeid : @py_object ref); + +ext_rettype(int funcid : @py_object ref, + int typeid : @py_object ref); + +ext_proptype(int propid : @py_object ref, + int typeid : @py_object ref); + +ext_argreturn(int funcid : @py_object ref, + int arg : int ref); + +py_special_objects(unique int obj : @py_cobject ref, + unique varchar(1) name : string ref); + +py_decorated_object(int object : @py_object ref, + int level: int ref); + +@py_object = @py_cobject | @py_flow_node; + +@py_source_element = @py_ast_node | @container; + +/* XML Files */ + +xmlEncoding (unique int id: @file ref, varchar(900) encoding: string ref); + +xmlDTDs (unique int id: @xmldtd, + varchar(900) root: string ref, + varchar(900) publicId: string ref, + varchar(900) systemId: string ref, + int fileid: @file ref); + +xmlElements (unique int id: @xmlelement, + varchar(900) name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs (unique int id: @xmlattribute, + int elementid: @xmlelement ref, + varchar(900) name: string ref, + varchar(3600) value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs (int id: @xmlnamespace, + varchar(900) prefixName: string ref, + varchar(900) URI: string ref, + int fileid: @file ref); + +xmlHasNs (int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments (unique int id: @xmlcomment, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars (unique int id: @xmlcharacters, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations(int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; diff --git a/python/upgrades/f635b392038a494915307f913657cd3058f9b476/py_exprs.ql b/python/upgrades/f635b392038a494915307f913657cd3058f9b476/py_exprs.ql new file mode 100644 index 000000000000..1c5aa49030e9 --- /dev/null +++ b/python/upgrades/f635b392038a494915307f913657cd3058f9b476/py_exprs.ql @@ -0,0 +1,161 @@ +class Location extends @location { + /** Gets the start line of this location */ + int getStartLine() { + locations_default(this, _, result, _, _, _) or + locations_ast(this, _, result, _, _, _) + } + + /** Gets the start column of this location */ + int getStartColumn() { + locations_default(this, _, _, result, _, _) or + locations_ast(this, _, _, result, _, _) + } + + string toString() { result = "" + ":" + this.getStartLine().toString() } +} + +class Expr_ extends @py_expr { + string toString() { result = "Expr" } + + Location getLocation() { py_locations(result, this) } +} + +class ExprParent_ extends @py_expr_parent { + string toString() { result = "ExprParent" } +} + +class ExprList_ extends @py_expr_list { + /** Gets the nth item of this expression list */ + Expr_ getItem(int index) { py_exprs(result, _, this, index) } + + string toString() { result = "ExprList" } +} + +class Parameter_ extends @py_parameter { + string toString() { result = "Parameter" } + + Location getLocation() { result = this.(Expr_).getLocation() } +} + +class ParameterList extends @py_parameter_list { + /** Gets the nth parameter */ + Parameter_ getItem(int index) { + /* Item can be a Name or a Tuple, both of which are expressions */ + py_exprs(result, _, this, index) + } + + string toString() { result = "ParameterList" } +} + +class Arguments_ extends @py_arguments { + /** Gets the keyword-only default values of this parameters definition. */ + ExprList_ getKwDefaults() { py_expr_lists(result, this, 0) } + + /** Gets the nth keyword-only default value of this parameters definition. */ + Expr_ getKwDefault(int index) { result = this.getKwDefaults().getItem(index) } + + /** Gets the default values of this parameters definition. */ + ExprList_ getDefaults() { py_expr_lists(result, this, 1) } + + /** Gets the nth default value of this parameters definition. */ + Expr_ getDefault(int index) { result = this.getDefaults().getItem(index) } + + string toString() { result = "Arguments" } +} + +class Function_ extends @py_Function { + /** Gets the positional parameter list of this function. */ + ParameterList getArgs() { py_parameter_lists(result, this) } + + /** Gets the nth positional parameter of this function. */ + Parameter_ getArg(int index) { result = this.getArgs().getItem(index) } + + /** Gets the keyword-only parameter list of this function. */ + ExprList_ getKwonlyargs() { py_expr_lists(result, this, 3) } + + /** Gets the nth keyword-only parameter of this function. */ + Expr_ getKwonlyarg(int index) { result = this.getKwonlyargs().getItem(index) } + + string toString() { result = "Function" } +} + +/** + * This class serves the same purpose as CallableExpr. CallableExpr is defined in Function.qll + * To ease the burden of number of classes that needs to be implemented here, I make the class + * hierarchy slightly different (that's why it's called Adjusted) + */ +abstract class CallableExprAdjusted extends Expr_ { + /** + * Gets The default values and annotations (type-hints) for the arguments of this callable. + * + * This predicate is called getArgs(), rather than getParameters() for compatibility with Python's AST module. + */ + abstract Arguments_ getArgs(); + + /** Gets the function scope of this code expression. */ + abstract Function_ getInnerScope(); +} + +class Lambda_ extends @py_Lambda, CallableExprAdjusted, Expr_ { + /** Gets the arguments of this lambda expression. */ + override Arguments_ getArgs() { py_arguments(result, this) } + + /** Gets the function scope of this lambda expression. */ + override Function_ getInnerScope() { py_Functions(result, this) } + + override string toString() { result = "Lambda" } +} + +class FunctionExpr_ extends @py_FunctionExpr, CallableExprAdjusted, Expr_ { + /** Gets the parameters of this function definition. */ + override Arguments_ getArgs() { py_arguments(result, this) } + + /** Gets the function scope of this function definition. */ + override Function_ getInnerScope() { py_Functions(result, this) } + + override string toString() { result = "FunctionExpr" } +} + + +/* + * This upgrade changes the *layout* of the default values for parameters, by + * making `Argument.getKwDefault(i)` return the default value for keyword-only parameter `i` + * (instead of the i'th default for a keyword-only parameter). `Argument.getDefault` is + * changed in the same manner to keep consistency. + */ +from Expr_ expr, int kind, ExprParent_ parent, int oldidx, int newidx +where + py_exprs(expr, kind, parent, oldidx) and + ( + // expr is not a parameter default + not exists(Arguments_ args | args.getDefault(oldidx) = expr) and + not exists(Arguments_ args | args.getKwDefault(oldidx) = expr) and + newidx = oldidx + or + // expr is a default for a normal parameter + exists(Arguments_ args, CallableExprAdjusted callable | + callable.getArgs() = args and + args.getDefault(oldidx) = expr and + newidx = oldidx + count(callable.getInnerScope().getArg(_)) - count(args.getDefault(_)) + ) + or + // expr is a default for a keyword-only parameter. + // before this upgrade, we would not always attach the default value to the correct keyword-only parameter, + // to fix this, we calculate the new index based on the source location of the default value (a default value + // must belong to the parameter that was defined immediately before the default value). + exists(Arguments_ args, CallableExprAdjusted callable | + callable.getArgs() = args and + args.getKwDefault(oldidx) = expr and + newidx = + // the last parameter to be defined before this default value + max(int i | + exists(Parameter_ param | param = callable.getInnerScope().getKwonlyarg(i) | + param.getLocation().getStartLine() < expr.getLocation().getStartLine() + or + param.getLocation().getStartLine() = expr.getLocation().getStartLine() and + param.getLocation().getStartColumn() < expr.getLocation().getStartColumn() + ) + ) + ) + ) +select expr, kind, parent, newidx diff --git a/python/upgrades/f635b392038a494915307f913657cd3058f9b476/semmlecode.python.dbscheme b/python/upgrades/f635b392038a494915307f913657cd3058f9b476/semmlecode.python.dbscheme new file mode 100644 index 000000000000..4f1806347d7f --- /dev/null +++ b/python/upgrades/f635b392038a494915307f913657cd3058f9b476/semmlecode.python.dbscheme @@ -0,0 +1,999 @@ +/* + * This dbscheme is auto-generated by 'semmle/dbscheme_gen.py'. + * WARNING: Any modifications to this file will be lost. + * Relations can be changed by modifying master.py or + * by adding rules to dbscheme.template + */ + +/* This is a dummy line to alter the dbscheme, so we can make a database upgrade + * without actually changing any of the dbscheme predicates. It contains a date + * to allow for such updates in the future as well. + * + * 2020-07-02 + * + * DO NOT remove this comment carelessly, since it can revert the dbscheme back to a + * previously seen state (matching a previously seen SHA), which would make the upgrade + * mechanism not work properly. + */ + + /* + * External artifacts + */ + +externalDefects( + unique int id : @externalDefect, + varchar(900) queryPath : string ref, + int location : @location ref, + varchar(900) message : string ref, + float severity : float ref +); + +externalMetrics( + unique int id : @externalMetric, + varchar(900) queryPath : string ref, + int location : @location ref, + float value : float ref +); + +externalData( + int id : @externalDataElement, + varchar(900) queryPath : string ref, + int column: int ref, + varchar(900) data : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/* + * Line metrics + */ +py_codelines(int id : @py_scope ref, + int count : int ref); + +py_commentlines(int id : @py_scope ref, + int count : int ref); + +py_docstringlines(int id : @py_scope ref, + int count : int ref); + +py_alllines(int id : @py_scope ref, + int count : int ref); + +/* + * Version history + */ + +svnentries( + int id : @svnentry, + varchar(500) revision : string ref, + varchar(500) author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + varchar(500) action : string ref +) + +svnentrymsg( + int id : @svnentry ref, + varchar(500) message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/**************************** + Python dbscheme +****************************/ + +/* fromSource is ignored */ +files(unique int id: @file, + varchar(900) name: string ref, + varchar(900) simple: string ref, + varchar(900) ext: string ref, + int fromSource: int ref); + +folders(unique int id: @folder, + varchar(900) name: string ref, + varchar(900) simple: string ref); + +@container = @folder | @file; + +containerparent(int parent: @container ref, + unique int child: @container ref); + +@sourceline = @file | @py_Module | @xmllocatable; + +numlines(int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref + ); + +@location = @location_ast | @location_default ; + +locations_default(unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +locations_ast(unique int id: @location_ast, + int module: @py_Module ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +file_contents(unique int file: @file ref, string contents: string ref); + +py_module_path(int module: @py_Module ref, int file: @container ref); + +variable(unique int id : @py_variable, + int scope : @py_scope ref, + varchar(1) name : string ref); + +py_line_lengths(unique int id : @py_line, + int file: @py_Module ref, + int line : int ref, + int length : int ref); + +py_extracted_version(int module : @py_Module ref, + varchar(1) version : string ref); + +/* AUTO GENERATED PART STARTS HERE */ + + +/* AnnAssign.location = 0, location */ +/* AnnAssign.value = 1, expr */ +/* AnnAssign.annotation = 2, expr */ +/* AnnAssign.target = 3, expr */ + +/* Assert.location = 0, location */ +/* Assert.test = 1, expr */ +/* Assert.msg = 2, expr */ + +/* Assign.location = 0, location */ +/* Assign.value = 1, expr */ +/* Assign.targets = 2, expr_list */ + +/* AssignExpr.location = 0, location */ +/* AssignExpr.parenthesised = 1, bool */ +/* AssignExpr.value = 2, expr */ +/* AssignExpr.target = 3, expr */ + +/* Attribute.location = 0, location */ +/* Attribute.parenthesised = 1, bool */ +/* Attribute.value = 2, expr */ +/* Attribute.attr = 3, str */ +/* Attribute.ctx = 4, expr_context */ + +/* AugAssign.location = 0, location */ +/* AugAssign.operation = 1, BinOp */ + +/* Await.location = 0, location */ +/* Await.parenthesised = 1, bool */ +/* Await.value = 2, expr */ + +/* BinaryExpr.location = 0, location */ +/* BinaryExpr.parenthesised = 1, bool */ +/* BinaryExpr.left = 2, expr */ +/* BinaryExpr.op = 3, operator */ +/* BinaryExpr.right = 4, expr */ +/* BinaryExpr = AugAssign */ + +/* BoolExpr.location = 0, location */ +/* BoolExpr.parenthesised = 1, bool */ +/* BoolExpr.op = 2, boolop */ +/* BoolExpr.values = 3, expr_list */ + +/* Break.location = 0, location */ + +/* Bytes.location = 0, location */ +/* Bytes.parenthesised = 1, bool */ +/* Bytes.s = 2, bytes */ +/* Bytes.prefix = 3, bytes */ +/* Bytes.implicitly_concatenated_parts = 4, StringPart_list */ + +/* Call.location = 0, location */ +/* Call.parenthesised = 1, bool */ +/* Call.func = 2, expr */ +/* Call.positional_args = 3, expr_list */ +/* Call.named_args = 4, dict_item_list */ + +/* Class.name = 0, str */ +/* Class.body = 1, stmt_list */ +/* Class = ClassExpr */ + +/* ClassExpr.location = 0, location */ +/* ClassExpr.parenthesised = 1, bool */ +/* ClassExpr.name = 2, str */ +/* ClassExpr.bases = 3, expr_list */ +/* ClassExpr.keywords = 4, dict_item_list */ +/* ClassExpr.inner_scope = 5, Class */ + +/* Compare.location = 0, location */ +/* Compare.parenthesised = 1, bool */ +/* Compare.left = 2, expr */ +/* Compare.ops = 3, cmpop_list */ +/* Compare.comparators = 4, expr_list */ + +/* Continue.location = 0, location */ + +/* Delete.location = 0, location */ +/* Delete.targets = 1, expr_list */ + +/* Dict.location = 0, location */ +/* Dict.parenthesised = 1, bool */ +/* Dict.items = 2, dict_item_list */ + +/* DictComp.location = 0, location */ +/* DictComp.parenthesised = 1, bool */ +/* DictComp.function = 2, Function */ +/* DictComp.iterable = 3, expr */ + +/* DictUnpacking.location = 0, location */ +/* DictUnpacking.value = 1, expr */ + +/* Ellipsis.location = 0, location */ +/* Ellipsis.parenthesised = 1, bool */ + +/* ExceptStmt.location = 0, location */ +/* ExceptStmt.type = 1, expr */ +/* ExceptStmt.name = 2, expr */ +/* ExceptStmt.body = 3, stmt_list */ + +/* Exec.location = 0, location */ +/* Exec.body = 1, expr */ +/* Exec.globals = 2, expr */ +/* Exec.locals = 3, expr */ + +/* ExprStmt.location = 0, location */ +/* ExprStmt.value = 1, expr */ + +/* Filter.location = 0, location */ +/* Filter.parenthesised = 1, bool */ +/* Filter.value = 2, expr */ +/* Filter.filter = 3, expr */ + +/* For.location = 0, location */ +/* For.target = 1, expr */ +/* For.iter = 2, expr */ +/* For.body = 3, stmt_list */ +/* For.orelse = 4, stmt_list */ +/* For.is_async = 5, bool */ + +/* FormattedValue.location = 0, location */ +/* FormattedValue.parenthesised = 1, bool */ +/* FormattedValue.value = 2, expr */ +/* FormattedValue.conversion = 3, str */ +/* FormattedValue.format_spec = 4, JoinedStr */ + +/* Function.name = 0, str */ +/* Function.args = 1, parameter_list */ +/* Function.vararg = 2, expr */ +/* Function.kwonlyargs = 3, expr_list */ +/* Function.kwarg = 4, expr */ +/* Function.body = 5, stmt_list */ +/* Function.is_async = 6, bool */ +/* Function = FunctionParent */ + +/* FunctionExpr.location = 0, location */ +/* FunctionExpr.parenthesised = 1, bool */ +/* FunctionExpr.name = 2, str */ +/* FunctionExpr.args = 3, arguments */ +/* FunctionExpr.returns = 4, expr */ +/* FunctionExpr.inner_scope = 5, Function */ + +/* GeneratorExp.location = 0, location */ +/* GeneratorExp.parenthesised = 1, bool */ +/* GeneratorExp.function = 2, Function */ +/* GeneratorExp.iterable = 3, expr */ + +/* Global.location = 0, location */ +/* Global.names = 1, str_list */ + +/* If.location = 0, location */ +/* If.test = 1, expr */ +/* If.body = 2, stmt_list */ +/* If.orelse = 3, stmt_list */ + +/* IfExp.location = 0, location */ +/* IfExp.parenthesised = 1, bool */ +/* IfExp.test = 2, expr */ +/* IfExp.body = 3, expr */ +/* IfExp.orelse = 4, expr */ + +/* Import.location = 0, location */ +/* Import.names = 1, alias_list */ + +/* ImportExpr.location = 0, location */ +/* ImportExpr.parenthesised = 1, bool */ +/* ImportExpr.level = 2, int */ +/* ImportExpr.name = 3, str */ +/* ImportExpr.top = 4, bool */ + +/* ImportStar.location = 0, location */ +/* ImportStar.module = 1, expr */ + +/* ImportMember.location = 0, location */ +/* ImportMember.parenthesised = 1, bool */ +/* ImportMember.module = 2, expr */ +/* ImportMember.name = 3, str */ + +/* Fstring.location = 0, location */ +/* Fstring.parenthesised = 1, bool */ +/* Fstring.values = 2, expr_list */ +/* Fstring = FormattedValue */ + +/* KeyValuePair.location = 0, location */ +/* KeyValuePair.value = 1, expr */ +/* KeyValuePair.key = 2, expr */ + +/* Lambda.location = 0, location */ +/* Lambda.parenthesised = 1, bool */ +/* Lambda.args = 2, arguments */ +/* Lambda.inner_scope = 3, Function */ + +/* List.location = 0, location */ +/* List.parenthesised = 1, bool */ +/* List.elts = 2, expr_list */ +/* List.ctx = 3, expr_context */ + +/* ListComp.location = 0, location */ +/* ListComp.parenthesised = 1, bool */ +/* ListComp.function = 2, Function */ +/* ListComp.iterable = 3, expr */ +/* ListComp.generators = 4, comprehension_list */ +/* ListComp.elt = 5, expr */ + +/* Module.name = 0, str */ +/* Module.hash = 1, str */ +/* Module.body = 2, stmt_list */ +/* Module.kind = 3, str */ + +/* Name.location = 0, location */ +/* Name.parenthesised = 1, bool */ +/* Name.variable = 2, variable */ +/* Name.ctx = 3, expr_context */ +/* Name = ParameterList */ + +/* Nonlocal.location = 0, location */ +/* Nonlocal.names = 1, str_list */ + +/* Num.location = 0, location */ +/* Num.parenthesised = 1, bool */ +/* Num.n = 2, number */ +/* Num.text = 3, number */ + +/* Pass.location = 0, location */ + +/* PlaceHolder.location = 0, location */ +/* PlaceHolder.parenthesised = 1, bool */ +/* PlaceHolder.variable = 2, variable */ +/* PlaceHolder.ctx = 3, expr_context */ + +/* Print.location = 0, location */ +/* Print.dest = 1, expr */ +/* Print.values = 2, expr_list */ +/* Print.nl = 3, bool */ + +/* Raise.location = 0, location */ +/* Raise.exc = 1, expr */ +/* Raise.cause = 2, expr */ +/* Raise.type = 3, expr */ +/* Raise.inst = 4, expr */ +/* Raise.tback = 5, expr */ + +/* Repr.location = 0, location */ +/* Repr.parenthesised = 1, bool */ +/* Repr.value = 2, expr */ + +/* Return.location = 0, location */ +/* Return.value = 1, expr */ + +/* Set.location = 0, location */ +/* Set.parenthesised = 1, bool */ +/* Set.elts = 2, expr_list */ + +/* SetComp.location = 0, location */ +/* SetComp.parenthesised = 1, bool */ +/* SetComp.function = 2, Function */ +/* SetComp.iterable = 3, expr */ + +/* Slice.location = 0, location */ +/* Slice.parenthesised = 1, bool */ +/* Slice.start = 2, expr */ +/* Slice.stop = 3, expr */ +/* Slice.step = 4, expr */ + +/* SpecialOperation.location = 0, location */ +/* SpecialOperation.parenthesised = 1, bool */ +/* SpecialOperation.name = 2, str */ +/* SpecialOperation.arguments = 3, expr_list */ + +/* Starred.location = 0, location */ +/* Starred.parenthesised = 1, bool */ +/* Starred.value = 2, expr */ +/* Starred.ctx = 3, expr_context */ + +/* Str.location = 0, location */ +/* Str.parenthesised = 1, bool */ +/* Str.s = 2, str */ +/* Str.prefix = 3, str */ +/* Str.implicitly_concatenated_parts = 4, StringPart_list */ + +/* StringPart.text = 0, str */ +/* StringPart.location = 1, location */ +/* StringPart = StringPartList */ +/* StringPartList = BytesOrStr */ + +/* Subscript.location = 0, location */ +/* Subscript.parenthesised = 1, bool */ +/* Subscript.value = 2, expr */ +/* Subscript.index = 3, expr */ +/* Subscript.ctx = 4, expr_context */ + +/* TemplateDottedNotation.location = 0, location */ +/* TemplateDottedNotation.parenthesised = 1, bool */ +/* TemplateDottedNotation.value = 2, expr */ +/* TemplateDottedNotation.attr = 3, str */ +/* TemplateDottedNotation.ctx = 4, expr_context */ + +/* TemplateWrite.location = 0, location */ +/* TemplateWrite.value = 1, expr */ + +/* Try.location = 0, location */ +/* Try.body = 1, stmt_list */ +/* Try.orelse = 2, stmt_list */ +/* Try.handlers = 3, stmt_list */ +/* Try.finalbody = 4, stmt_list */ + +/* Tuple.location = 0, location */ +/* Tuple.parenthesised = 1, bool */ +/* Tuple.elts = 2, expr_list */ +/* Tuple.ctx = 3, expr_context */ +/* Tuple = ParameterList */ + +/* UnaryExpr.location = 0, location */ +/* UnaryExpr.parenthesised = 1, bool */ +/* UnaryExpr.op = 2, unaryop */ +/* UnaryExpr.operand = 3, expr */ + +/* While.location = 0, location */ +/* While.test = 1, expr */ +/* While.body = 2, stmt_list */ +/* While.orelse = 3, stmt_list */ + +/* With.location = 0, location */ +/* With.context_expr = 1, expr */ +/* With.optional_vars = 2, expr */ +/* With.body = 3, stmt_list */ +/* With.is_async = 4, bool */ + +/* Yield.location = 0, location */ +/* Yield.parenthesised = 1, bool */ +/* Yield.value = 2, expr */ + +/* YieldFrom.location = 0, location */ +/* YieldFrom.parenthesised = 1, bool */ +/* YieldFrom.value = 2, expr */ + +/* Alias.value = 0, expr */ +/* Alias.asname = 1, expr */ +/* Alias = AliasList */ +/* AliasList = Import */ + +/* Arguments.kw_defaults = 0, expr_list */ +/* Arguments.defaults = 1, expr_list */ +/* Arguments.annotations = 2, expr_list */ +/* Arguments.varargannotation = 3, expr */ +/* Arguments.kwargannotation = 4, expr */ +/* Arguments.kw_annotations = 5, expr_list */ +/* Arguments = ArgumentsParent */ +/* boolean = BoolParent */ +/* Boolop = BoolExpr */ +/* string = Bytes */ +/* Cmpop = CmpopList */ +/* CmpopList = Compare */ + +/* Comprehension.location = 0, location */ +/* Comprehension.iter = 1, expr */ +/* Comprehension.target = 2, expr */ +/* Comprehension.ifs = 3, expr_list */ +/* Comprehension = ComprehensionList */ +/* ComprehensionList = ListComp */ +/* DictItem = DictItemList */ +/* DictItemList = DictItemListParent */ + +/* Expr.location = 0, location */ +/* Expr.parenthesised = 1, bool */ +/* Expr = ExprParent */ +/* ExprContext = ExprContextParent */ +/* ExprList = ExprListParent */ +/* int = ImportExpr */ + +/* Keyword.location = 0, location */ +/* Keyword.value = 1, expr */ +/* Keyword.arg = 2, str */ +/* Location = LocationParent */ +/* string = Num */ +/* Operator = BinaryExpr */ +/* ParameterList = Function */ + +/* Stmt.location = 0, location */ +/* Stmt = StmtList */ +/* StmtList = StmtListParent */ +/* string = StrParent */ +/* StringList = StrListParent */ +/* Unaryop = UnaryExpr */ +/* Variable = VariableParent */ +py_Classes(unique int id : @py_Class, + unique int parent : @py_ClassExpr ref); + +py_Functions(unique int id : @py_Function, + unique int parent : @py_Function_parent ref); + +py_Modules(unique int id : @py_Module); + +py_StringParts(unique int id : @py_StringPart, + int parent : @py_StringPart_list ref, + int idx : int ref); + +py_StringPart_lists(unique int id : @py_StringPart_list, + unique int parent : @py_Bytes_or_Str ref); + +py_aliases(unique int id : @py_alias, + int parent : @py_alias_list ref, + int idx : int ref); + +py_alias_lists(unique int id : @py_alias_list, + unique int parent : @py_Import ref); + +py_arguments(unique int id : @py_arguments, + unique int parent : @py_arguments_parent ref); + +py_bools(int parent : @py_bool_parent ref, + int idx : int ref); + +py_boolops(unique int id : @py_boolop, + int kind: int ref, + unique int parent : @py_BoolExpr ref); + +py_bytes(varchar(1) id : string ref, + int parent : @py_Bytes ref, + int idx : int ref); + +py_cmpops(unique int id : @py_cmpop, + int kind: int ref, + int parent : @py_cmpop_list ref, + int idx : int ref); + +py_cmpop_lists(unique int id : @py_cmpop_list, + unique int parent : @py_Compare ref); + +py_comprehensions(unique int id : @py_comprehension, + int parent : @py_comprehension_list ref, + int idx : int ref); + +py_comprehension_lists(unique int id : @py_comprehension_list, + unique int parent : @py_ListComp ref); + +py_dict_items(unique int id : @py_dict_item, + int kind: int ref, + int parent : @py_dict_item_list ref, + int idx : int ref); + +py_dict_item_lists(unique int id : @py_dict_item_list, + unique int parent : @py_dict_item_list_parent ref); + +py_exprs(unique int id : @py_expr, + int kind: int ref, + int parent : @py_expr_parent ref, + int idx : int ref); + +py_expr_contexts(unique int id : @py_expr_context, + int kind: int ref, + unique int parent : @py_expr_context_parent ref); + +py_expr_lists(unique int id : @py_expr_list, + int parent : @py_expr_list_parent ref, + int idx : int ref); + +py_ints(int id : int ref, + unique int parent : @py_ImportExpr ref); + +py_locations(unique int id : @location ref, + unique int parent : @py_location_parent ref); + +py_numbers(varchar(1) id : string ref, + int parent : @py_Num ref, + int idx : int ref); + +py_operators(unique int id : @py_operator, + int kind: int ref, + unique int parent : @py_BinaryExpr ref); + +py_parameter_lists(unique int id : @py_parameter_list, + unique int parent : @py_Function ref); + +py_stmts(unique int id : @py_stmt, + int kind: int ref, + int parent : @py_stmt_list ref, + int idx : int ref); + +py_stmt_lists(unique int id : @py_stmt_list, + int parent : @py_stmt_list_parent ref, + int idx : int ref); + +py_strs(varchar(1) id : string ref, + int parent : @py_str_parent ref, + int idx : int ref); + +py_str_lists(unique int id : @py_str_list, + unique int parent : @py_str_list_parent ref); + +py_unaryops(unique int id : @py_unaryop, + int kind: int ref, + unique int parent : @py_UnaryExpr ref); + +py_variables(int id : @py_variable ref, + unique int parent : @py_variable_parent ref); + +case @py_boolop.kind of + 0 = @py_And +| 1 = @py_Or; + +case @py_cmpop.kind of + 0 = @py_Eq +| 1 = @py_Gt +| 2 = @py_GtE +| 3 = @py_In +| 4 = @py_Is +| 5 = @py_IsNot +| 6 = @py_Lt +| 7 = @py_LtE +| 8 = @py_NotEq +| 9 = @py_NotIn; + +case @py_dict_item.kind of + 0 = @py_DictUnpacking +| 1 = @py_KeyValuePair +| 2 = @py_keyword; + +case @py_expr.kind of + 0 = @py_Attribute +| 1 = @py_BinaryExpr +| 2 = @py_BoolExpr +| 3 = @py_Bytes +| 4 = @py_Call +| 5 = @py_ClassExpr +| 6 = @py_Compare +| 7 = @py_Dict +| 8 = @py_DictComp +| 9 = @py_Ellipsis +| 10 = @py_FunctionExpr +| 11 = @py_GeneratorExp +| 12 = @py_IfExp +| 13 = @py_ImportExpr +| 14 = @py_ImportMember +| 15 = @py_Lambda +| 16 = @py_List +| 17 = @py_ListComp +| 18 = @py_Name +| 19 = @py_Num +| 20 = @py_Repr +| 21 = @py_Set +| 22 = @py_SetComp +| 23 = @py_Slice +| 24 = @py_Starred +| 25 = @py_Str +| 26 = @py_Subscript +| 27 = @py_Tuple +| 28 = @py_UnaryExpr +| 29 = @py_Yield +| 30 = @py_YieldFrom +| 31 = @py_TemplateDottedNotation +| 32 = @py_Filter +| 33 = @py_PlaceHolder +| 34 = @py_Await +| 35 = @py_Fstring +| 36 = @py_FormattedValue +| 37 = @py_AssignExpr +| 38 = @py_SpecialOperation; + +case @py_expr_context.kind of + 0 = @py_AugLoad +| 1 = @py_AugStore +| 2 = @py_Del +| 3 = @py_Load +| 4 = @py_Param +| 5 = @py_Store; + +case @py_operator.kind of + 0 = @py_Add +| 1 = @py_BitAnd +| 2 = @py_BitOr +| 3 = @py_BitXor +| 4 = @py_Div +| 5 = @py_FloorDiv +| 6 = @py_LShift +| 7 = @py_Mod +| 8 = @py_Mult +| 9 = @py_Pow +| 10 = @py_RShift +| 11 = @py_Sub +| 12 = @py_MatMult; + +case @py_stmt.kind of + 0 = @py_Assert +| 1 = @py_Assign +| 2 = @py_AugAssign +| 3 = @py_Break +| 4 = @py_Continue +| 5 = @py_Delete +| 6 = @py_ExceptStmt +| 7 = @py_Exec +| 8 = @py_Expr_stmt +| 9 = @py_For +| 10 = @py_Global +| 11 = @py_If +| 12 = @py_Import +| 13 = @py_ImportStar +| 14 = @py_Nonlocal +| 15 = @py_Pass +| 16 = @py_Print +| 17 = @py_Raise +| 18 = @py_Return +| 19 = @py_Try +| 20 = @py_While +| 21 = @py_With +| 22 = @py_TemplateWrite +| 23 = @py_AnnAssign; + +case @py_unaryop.kind of + 0 = @py_Invert +| 1 = @py_Not +| 2 = @py_UAdd +| 3 = @py_USub; + +@py_Bytes_or_Str = @py_Bytes | @py_Str; + +@py_Function_parent = @py_DictComp | @py_FunctionExpr | @py_GeneratorExp | @py_Lambda | @py_ListComp | @py_SetComp; + +@py_arguments_parent = @py_FunctionExpr | @py_Lambda; + +@py_ast_node = @py_Class | @py_Function | @py_Module | @py_StringPart | @py_comprehension | @py_dict_item | @py_expr | @py_stmt; + +@py_bool_parent = @py_For | @py_Function | @py_Print | @py_With | @py_expr; + +@py_dict_item_list_parent = @py_Call | @py_ClassExpr | @py_Dict; + +@py_expr_context_parent = @py_Attribute | @py_List | @py_Name | @py_PlaceHolder | @py_Starred | @py_Subscript | @py_TemplateDottedNotation | @py_Tuple; + +@py_expr_list_parent = @py_Assign | @py_BoolExpr | @py_Call | @py_ClassExpr | @py_Compare | @py_Delete | @py_Fstring | @py_Function | @py_List | @py_Print | @py_Set | @py_SpecialOperation | @py_Tuple | @py_arguments | @py_comprehension; + +@py_expr_or_stmt = @py_expr | @py_stmt; + +@py_expr_parent = @py_AnnAssign | @py_Assert | @py_Assign | @py_AssignExpr | @py_Attribute | @py_AugAssign | @py_Await | @py_BinaryExpr | @py_Call | @py_Compare | @py_DictComp | @py_DictUnpacking | @py_ExceptStmt | @py_Exec | @py_Expr_stmt | @py_Filter | @py_For | @py_FormattedValue | @py_Function | @py_FunctionExpr | @py_GeneratorExp | @py_If | @py_IfExp | @py_ImportMember | @py_ImportStar | @py_KeyValuePair | @py_ListComp | @py_Print | @py_Raise | @py_Repr | @py_Return | @py_SetComp | @py_Slice | @py_Starred | @py_Subscript | @py_TemplateDottedNotation | @py_TemplateWrite | @py_UnaryExpr | @py_While | @py_With | @py_Yield | @py_YieldFrom | @py_alias | @py_arguments | @py_comprehension | @py_expr_list | @py_keyword | @py_parameter_list; + +@py_location_parent = @py_DictUnpacking | @py_KeyValuePair | @py_StringPart | @py_comprehension | @py_expr | @py_keyword | @py_stmt; + +@py_parameter = @py_Name | @py_Tuple; + +@py_scope = @py_Class | @py_Function | @py_Module; + +@py_stmt_list_parent = @py_Class | @py_ExceptStmt | @py_For | @py_Function | @py_If | @py_Module | @py_Try | @py_While | @py_With; + +@py_str_list_parent = @py_Global | @py_Nonlocal; + +@py_str_parent = @py_Attribute | @py_Class | @py_ClassExpr | @py_FormattedValue | @py_Function | @py_FunctionExpr | @py_ImportExpr | @py_ImportMember | @py_Module | @py_SpecialOperation | @py_Str | @py_StringPart | @py_TemplateDottedNotation | @py_keyword | @py_str_list; + +@py_variable_parent = @py_Name | @py_PlaceHolder; + + +/* + * End of auto-generated part + */ + + + +/* Map relative names to absolute names for imports */ +py_absolute_names(int module : @py_Module ref, + varchar(1) relname : string ref, + varchar(1) absname : string ref); + +py_exports(int id : @py_Module ref, + varchar(1) name : string ref); + +/* Successor information */ +py_successors(int predecessor : @py_flow_node ref, + int successor : @py_flow_node ref); + +py_true_successors(int predecessor : @py_flow_node ref, + int successor : @py_flow_node ref); + +py_exception_successors(int predecessor : @py_flow_node ref, + int successor : @py_flow_node ref); + +py_false_successors(int predecessor : @py_flow_node ref, + int successor : @py_flow_node ref); + +py_flow_bb_node(unique int flownode : @py_flow_node, + int realnode : @py_ast_node ref, + int basicblock : @py_flow_node ref, + int index : int ref); + +py_scope_flow(int flow : @py_flow_node ref, + int scope : @py_scope ref, + int kind : int ref); + +py_idoms(unique int node : @py_flow_node ref, + int immediate_dominator : @py_flow_node ref); + +py_ssa_phi(int phi : @py_ssa_var ref, + int arg: @py_ssa_var ref); + +py_ssa_var(unique int id : @py_ssa_var, + int var : @py_variable ref); + +py_ssa_use(int node: @py_flow_node ref, + int var : @py_ssa_var ref); + +py_ssa_defn(unique int id : @py_ssa_var ref, + int node: @py_flow_node ref); + +@py_base_var = @py_variable | @py_ssa_var; + +py_scopes(unique int node : @py_expr_or_stmt ref, + int scope : @py_scope ref); + +py_scope_location(unique int id : @location ref, + unique int scope : @py_scope ref); + +py_flags_versioned(varchar(1) name : string ref, + varchar(1) value : string ref, + varchar(1) version : string ref); + +py_syntax_error_versioned(unique int id : @location ref, + varchar(1) message : string ref, + varchar(1) version : string ref); + +py_comments(unique int id : @py_comment, + varchar(1) text : string ref, + unique int location : @location ref); + +/* Type information support */ + +py_cobjects(unique int obj : @py_cobject); + +py_cobjecttypes(unique int obj : @py_cobject ref, + int typeof : @py_cobject ref); + +py_cobjectnames(unique int obj : @py_cobject ref, + varchar(1) name : string ref); + +/* Kind should be 0 for introspection, > 0 from source, as follows: + 1 from C extension source + */ +py_cobject_sources(int obj : @py_cobject ref, + int kind : int ref); + +py_cmembers_versioned(int object : @py_cobject ref, + varchar(1) name : string ref, + int member : @py_cobject ref, + varchar(1) version : string ref); + +py_citems(int object : @py_cobject ref, + int index : int ref, + int member : @py_cobject ref); + +ext_argtype(int funcid : @py_object ref, + int arg : int ref, + int typeid : @py_object ref); + +ext_rettype(int funcid : @py_object ref, + int typeid : @py_object ref); + +ext_proptype(int propid : @py_object ref, + int typeid : @py_object ref); + +ext_argreturn(int funcid : @py_object ref, + int arg : int ref); + +py_special_objects(unique int obj : @py_cobject ref, + unique varchar(1) name : string ref); + +py_decorated_object(int object : @py_object ref, + int level: int ref); + +@py_object = @py_cobject | @py_flow_node; + +@py_source_element = @py_ast_node | @container; + +/* XML Files */ + +xmlEncoding (unique int id: @file ref, varchar(900) encoding: string ref); + +xmlDTDs (unique int id: @xmldtd, + varchar(900) root: string ref, + varchar(900) publicId: string ref, + varchar(900) systemId: string ref, + int fileid: @file ref); + +xmlElements (unique int id: @xmlelement, + varchar(900) name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs (unique int id: @xmlattribute, + int elementid: @xmlelement ref, + varchar(900) name: string ref, + varchar(3600) value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs (int id: @xmlnamespace, + varchar(900) prefixName: string ref, + varchar(900) URI: string ref, + int fileid: @file ref); + +xmlHasNs (int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments (unique int id: @xmlcomment, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars (unique int id: @xmlcharacters, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations(int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; diff --git a/python/upgrades/f635b392038a494915307f913657cd3058f9b476/upgrade.properties b/python/upgrades/f635b392038a494915307f913657cd3058f9b476/upgrade.properties new file mode 100644 index 000000000000..1f17cd87dacd --- /dev/null +++ b/python/upgrades/f635b392038a494915307f913657cd3058f9b476/upgrade.properties @@ -0,0 +1,3 @@ +description: Changed indexing for parameter defaults +compatibility: full +py_exprs.rel: run py_exprs.qlo