author | Simon Chabot <simon.chabot@logilab.fr> |
Fri, 15 Feb 2019 15:46:02 +0100 | |
changeset 861 | d5e1e2b627fc |
parent 860 | abda658fe2ae |
child 862 | 942ef0731f4c |
rql/__init__.py | file | annotate | diff | comparison | revisions | |
rql/parser.py | file | annotate | diff | comparison | revisions | |
rql/rqlgen.py | file | annotate | diff | comparison | revisions | |
rql/stcheck.py | file | annotate | diff | comparison | revisions | |
test/unittest_analyze.py | file | annotate | diff | comparison | revisions | |
test/unittest_compare.py | file | annotate | diff | comparison | revisions | |
test/unittest_editextensions.py | file | annotate | diff | comparison | revisions | |
test/unittest_nodes.py | file | annotate | diff | comparison | revisions | |
test/unittest_parser.py | file | annotate | diff | comparison | revisions | |
test/unittest_stcheck.py | file | annotate | diff | comparison | revisions | |
test/unittest_utils.py | file | annotate | diff | comparison | revisions | |
tox.ini | file | annotate | diff | comparison | revisions |
--- a/rql/__init__.py Wed Feb 13 19:10:43 2019 +0100 +++ b/rql/__init__.py Fri Feb 15 15:46:02 2019 +0100 @@ -153,7 +153,11 @@ if any(term.is_equivalent(t) for t in select.selection): rhs = copy_uid_node(select, rhs, vconsts) if vref is term: - index = next(i for i, var in enumerate(select.selection) if vref.is_equivalent(var)) + index = next( + i + for i, var in enumerate(select.selection) + if vref.is_equivalent(var) + ) select.selection[index] = rhs rhs.parent = select else: @@ -220,7 +224,10 @@ if nb_lines > 5: width = log(nb_lines, 10)+1 template = " %%%ii: %%s" % width - rqlstring = '\n'.join(template % (idx + 1, line) for idx, line in enumerate(multi_lines_rql)) + rqlstring = '\n'.join( + template % (idx + 1, line) + for idx, line in enumerate(multi_lines_rql) + ) msg = '%s\nat: %r\n%s' % (rqlstring, ex.pos, ex.msg) else:
--- a/rql/parser.py Wed Feb 13 19:10:43 2019 +0100 +++ b/rql/parser.py Fri Feb 15 15:46:02 2019 +0100 @@ -107,7 +107,14 @@ ] def __init__(self, str, *args, **kw): - runtime.Scanner.__init__(self, None, {'\\s+': None, '/\\*(?:[^*]|\\*(?!/))*\\*/': None, }, str, *args, **kw) + runtime.Scanner.__init__( + self, + None, + {'\\s+': None, '/\\*(?:[^*]|\\*(?!/))*\\*/': None}, + str, + *args, + **kw + ) class Hercule(runtime.Parser): @@ -115,7 +122,15 @@ def goal(self, _parent=None): _context = self.Context(_parent, self._scanner, 'goal', []) - _token = self._peek('DELETE', 'INSERT', 'SET', 'r"\\("', 'DISTINCT', 'E_TYPE', context=_context) + _token = self._peek( + 'DELETE', + 'INSERT', + 'SET', + 'r"\\("', + 'DISTINCT', + 'E_TYPE', + context=_context, + ) if _token == 'DELETE': self._scan('DELETE', context=_context) _delete = self._delete(Delete(), _context) @@ -224,20 +239,60 @@ _context = self.Context(_parent, self._scanner, 'selection', [S]) expr_add = self.expr_add(S, _context) S.append_selected(expr_add) - while self._peek("','", 'GROUPBY', 'ORDERBY', 'WHERE', 'LIMIT', 'OFFSET', 'HAVING', 'WITH', "';'", 'r"\\)"', context=_context) == "','": + while ( + self._peek( + "','", + 'GROUPBY', + 'ORDERBY', + 'WHERE', + 'LIMIT', + 'OFFSET', + 'HAVING', + 'WITH', + "';'", + 'r"\\)"', + context=_context, + ) + == "','" + ): self._scan("','", context=_context) expr_add = self.expr_add(S, _context) S.append_selected(expr_add) def groupby(self, S, _parent=None): _context = self.Context(_parent, self._scanner, 'groupby', [S]) - _token = self._peek('GROUPBY', 'ORDERBY', 'WHERE', 'LIMIT', 'OFFSET', 'HAVING', 'WITH', "';'", 'r"\\)"', context=_context) + _token = self._peek( + 'GROUPBY', + 'ORDERBY', + 'WHERE', + 'LIMIT', + 'OFFSET', + 'HAVING', + 'WITH', + "';'", + 'r"\\)"', + context=_context, + ) if _token == 'GROUPBY': self._scan('GROUPBY', context=_context) nodes = [] expr_add = self.expr_add(S, _context) nodes.append(expr_add) - while self._peek("','", 'ORDERBY', 'WHERE', 'LIMIT', 'OFFSET', 'HAVING', 'WITH', "';'", 'r"\\)"', context=_context) == "','": + while ( + self._peek( + "','", + 'ORDERBY', + 'WHERE', + 'LIMIT', + 'OFFSET', + 'HAVING', + 'WITH', + "';'", + 'r"\\)"', + context=_context, + ) + == "','" + ): self._scan("','", context=_context) expr_add = self.expr_add(S, _context) nodes.append(expr_add) @@ -258,13 +313,36 @@ def orderby(self, S, _parent=None): _context = self.Context(_parent, self._scanner, 'orderby', [S]) - _token = self._peek('ORDERBY', 'WHERE', 'LIMIT', 'OFFSET', 'HAVING', 'WITH', "';'", 'r"\\)"', context=_context) + _token = self._peek( + 'ORDERBY', + 'WHERE', + 'LIMIT', + 'OFFSET', + 'HAVING', + 'WITH', + "';'", + 'r"\\)"', + context=_context, + ) if _token == 'ORDERBY': self._scan('ORDERBY', context=_context) nodes = [] sort_term = self.sort_term(S, _context) nodes.append(sort_term) - while self._peek("','", 'WHERE', 'LIMIT', 'OFFSET', 'HAVING', 'WITH', "';'", 'r"\\)"', context=_context) == "','": + while ( + self._peek( + "','", + 'WHERE', + 'LIMIT', + 'OFFSET', + 'HAVING', + 'WITH', + "';'", + 'r"\\)"', + context=_context, + ) + == "','" + ): self._scan("','", context=_context) sort_term = self.sort_term(S, _context) nodes.append(sort_term) @@ -309,7 +387,19 @@ def sort_meth(self, _parent=None): _context = self.Context(_parent, self._scanner, 'sort_meth', []) - _token = self._peek('SORT_DESC', 'SORT_ASC', "','", 'WHERE', 'LIMIT', 'OFFSET', 'HAVING', 'WITH', "';'", 'r"\\)"', context=_context) + _token = self._peek( + 'SORT_DESC', + 'SORT_ASC', + "','", + 'WHERE', + 'LIMIT', + 'OFFSET', + 'HAVING', + 'WITH', + "';'", + 'r"\\)"', + context=_context, + ) if _token == 'SORT_DESC': self._scan('SORT_DESC', context=_context) return 0 @@ -327,7 +417,16 @@ def limit(self, R, _parent=None): _context = self.Context(_parent, self._scanner, 'limit', [R]) - _token = self._peek('LIMIT', 'OFFSET', 'WHERE', 'HAVING', 'WITH', "';'", 'r"\\)"', context=_context) + _token = self._peek( + 'LIMIT', + 'OFFSET', + 'WHERE', + 'HAVING', + 'WITH', + "';'", + 'r"\\)"', + context=_context, + ) if _token == 'LIMIT': self._scan('LIMIT', context=_context) INT = self._scan('INT', context=_context) @@ -371,7 +470,18 @@ _context = self.Context(_parent, self._scanner, 'rels_or', [S]) rels_and = self.rels_and(S, _context) node = rels_and - while self._peek('OR', "','", 'r"\\)"', 'HAVING', 'WITH', "';'", context=_context) == 'OR': + while ( + self._peek( + 'OR', + "','", + 'r"\\)"', + 'HAVING', + 'WITH', + "';'", + context=_context, + ) + == 'OR' + ): self._scan('OR', context=_context) rels_and = self.rels_and(S, _context) node = Or(node, rels_and) @@ -381,7 +491,19 @@ _context = self.Context(_parent, self._scanner, 'rels_and', [S]) rels_not = self.rels_not(S, _context) node = rels_not - while self._peek('AND', 'OR', "','", 'r"\\)"', 'HAVING', 'WITH', "';'", context=_context) == 'AND': + while ( + self._peek( + 'AND', + 'OR', + "','", + 'r"\\)"', + 'HAVING', + 'WITH', + "';'", + context=_context, + ) + == 'AND' + ): self._scan('AND', context=_context) rels_not = self.rels_not(S, _context) node = And(node, rels_not) @@ -438,7 +560,9 @@ def opt_left(self, S, _parent=None): _context = self.Context(_parent, self._scanner, 'opt_left', [S]) - _token = self._peek('QMARK', 'R_TYPE', 'CMP_OP', "'IN'", context=_context) + _token = self._peek( + 'QMARK', 'R_TYPE', 'CMP_OP', "'IN'", context=_context + ) if _token == 'QMARK': self._scan('QMARK', context=_context) return 'left' @@ -447,7 +571,17 @@ def opt_right(self, S, _parent=None): _context = self.Context(_parent, self._scanner, 'opt_right', [S]) - _token = self._peek('QMARK', 'AND', 'OR', "','", 'r"\\)"', 'WITH', "';'", 'HAVING', context=_context) + _token = self._peek( + 'QMARK', + 'AND', + 'OR', + "','", + 'r"\\)"', + 'WITH', + "';'", + 'HAVING', + context=_context, + ) if _token == 'QMARK': self._scan('QMARK', context=_context) return 'right' @@ -486,7 +620,24 @@ def exprs_not(self, S, _parent=None): _context = self.Context(_parent, self._scanner, 'exprs_not', [S]) - _token = self._peek('NOT', 'r"\\("', 'UNARY_OP', 'NULL', 'DATE', 'DATETIME', 'TRUE', 'FALSE', 'FLOAT', 'INT', 'STRING', 'SUBSTITUTE', 'VARIABLE', 'E_TYPE', 'FUNCTION', context=_context) + _token = self._peek( + 'NOT', + 'r"\\("', + 'UNARY_OP', + 'NULL', + 'DATE', + 'DATETIME', + 'TRUE', + 'FALSE', + 'FLOAT', + 'INT', + 'STRING', + 'SUBSTITUTE', + 'VARIABLE', + 'E_TYPE', + 'FUNCTION', + context=_context, + ) if _token == 'NOT': self._scan('NOT', context=_context) balanced_expr = self.balanced_expr(S, _context) @@ -497,7 +648,23 @@ def balanced_expr(self, S, _parent=None): _context = self.Context(_parent, self._scanner, 'balanced_expr', [S]) - _token = self._peek('r"\\("', 'UNARY_OP', 'NULL', 'DATE', 'DATETIME', 'TRUE', 'FALSE', 'FLOAT', 'INT', 'STRING', 'SUBSTITUTE', 'VARIABLE', 'E_TYPE', 'FUNCTION', context=_context) + _token = self._peek( + 'r"\\("', + 'UNARY_OP', + 'NULL', + 'DATE', + 'DATETIME', + 'TRUE', + 'FALSE', + 'FLOAT', + 'INT', + 'STRING', + 'SUBSTITUTE', + 'VARIABLE', + 'E_TYPE', + 'FUNCTION', + context=_context, + ) if _token == 'r"\\("': self._scan('r"\\("', context=_context) logical_expr = self.logical_expr(S, _context) @@ -540,7 +707,35 @@ _context = self.Context(_parent, self._scanner, 'decl_vars', [R]) E_TYPE = self._scan('E_TYPE', context=_context) var = self.var(R, _context) - while self._peek("','", 'R_TYPE', 'QMARK', 'WHERE', '":"', 'CMP_OP', 'HAVING', "'IN'", "';'", 'POW_OP', 'BEING', 'WITH', 'MUL_OP', 'r"\\)"', 'ADD_OP', 'SORT_DESC', 'SORT_ASC', 'GROUPBY', 'ORDERBY', 'LIMIT', 'OFFSET', 'AND', 'OR', context=_context) == "','": + while ( + self._peek( + "','", + 'R_TYPE', + 'QMARK', + 'WHERE', + '":"', + 'CMP_OP', + 'HAVING', + "'IN'", + "';'", + 'POW_OP', + 'BEING', + 'WITH', + 'MUL_OP', + 'r"\\)"', + 'ADD_OP', + 'SORT_DESC', + 'SORT_ASC', + 'GROUPBY', + 'ORDERBY', + 'LIMIT', + 'OFFSET', + 'AND', + 'OR', + context=_context, + ) + == "','" + ): R.add_main_variable(E_TYPE, var) self._scan("','", context=_context) E_TYPE = self._scan('E_TYPE', context=_context) @@ -550,7 +745,18 @@ def decl_rels(self, R, _parent=None): _context = self.Context(_parent, self._scanner, 'decl_rels', [R]) simple_rel = self.simple_rel(R, _context) - while self._peek("','", 'WHERE', 'HAVING', 'WITH', "';'", 'r"\\)"', context=_context) == "','": + while ( + self._peek( + "','", + 'WHERE', + 'HAVING', + 'WITH', + "';'", + 'r"\\)"', + context=_context, + ) + == "','" + ): R.add_main_relation(simple_rel) self._scan("','", context=_context) simple_rel = self.simple_rel(R, _context) @@ -568,7 +774,24 @@ def expr(self, S, _parent=None): _context = self.Context(_parent, self._scanner, 'expr', [S]) - _token = self._peek('CMP_OP', 'UNARY_OP', 'r"\\("', 'NULL', 'DATE', 'DATETIME', 'TRUE', 'FALSE', 'FLOAT', 'INT', 'STRING', 'SUBSTITUTE', 'VARIABLE', 'E_TYPE', 'FUNCTION', context=_context) + _token = self._peek( + 'CMP_OP', + 'UNARY_OP', + 'r"\\("', + 'NULL', + 'DATE', + 'DATETIME', + 'TRUE', + 'FALSE', + 'FLOAT', + 'INT', + 'STRING', + 'SUBSTITUTE', + 'VARIABLE', + 'E_TYPE', + 'FUNCTION', + context=_context, + ) if _token == 'CMP_OP': CMP_OP = self._scan('CMP_OP', context=_context) expr_add = self.expr_add(S, _context) @@ -579,11 +802,51 @@ def expr_add(self, S, _parent=None): _context = self.Context(_parent, self._scanner, 'expr_add', [S]) - _token = self._peek('UNARY_OP', 'r"\\("', 'NULL', 'DATE', 'DATETIME', 'TRUE', 'FALSE', 'FLOAT', 'INT', 'STRING', 'SUBSTITUTE', 'VARIABLE', 'E_TYPE', 'FUNCTION', context=_context) + _token = self._peek( + 'UNARY_OP', + 'r"\\("', + 'NULL', + 'DATE', + 'DATETIME', + 'TRUE', + 'FALSE', + 'FLOAT', + 'INT', + 'STRING', + 'SUBSTITUTE', + 'VARIABLE', + 'E_TYPE', + 'FUNCTION', + context=_context, + ) if _token != 'UNARY_OP': expr_mul = self.expr_mul(S, _context) node = expr_mul - while self._peek('ADD_OP', 'QMARK', 'r"\\)"', "','", 'SORT_DESC', 'SORT_ASC', 'CMP_OP', 'R_TYPE', "'IN'", 'GROUPBY', 'ORDERBY', 'WHERE', 'LIMIT', 'OFFSET', 'HAVING', 'WITH', "';'", 'AND', 'OR', context=_context) == 'ADD_OP': + while ( + self._peek( + 'ADD_OP', + 'QMARK', + 'r"\\)"', + "','", + 'SORT_DESC', + 'SORT_ASC', + 'CMP_OP', + 'R_TYPE', + "'IN'", + 'GROUPBY', + 'ORDERBY', + 'WHERE', + 'LIMIT', + 'OFFSET', + 'HAVING', + 'WITH', + "';'", + 'AND', + 'OR', + context=_context, + ) + == 'ADD_OP' + ): ADD_OP = self._scan('ADD_OP', context=_context) expr_mul = self.expr_mul(S, _context) node = MathExpression(ADD_OP, node, expr_mul) @@ -592,7 +855,31 @@ UNARY_OP = self._scan('UNARY_OP', context=_context) expr_mul = self.expr_mul(S, _context) node = UnaryExpression(UNARY_OP, expr_mul) - while self._peek('ADD_OP', 'QMARK', 'r"\\)"', "','", 'SORT_DESC', 'SORT_ASC', 'CMP_OP', 'R_TYPE', "'IN'", 'GROUPBY', 'ORDERBY', 'WHERE', 'LIMIT', 'OFFSET', 'HAVING', 'WITH', "';'", 'AND', 'OR', context=_context) == 'ADD_OP': + while ( + self._peek( + 'ADD_OP', + 'QMARK', + 'r"\\)"', + "','", + 'SORT_DESC', + 'SORT_ASC', + 'CMP_OP', + 'R_TYPE', + "'IN'", + 'GROUPBY', + 'ORDERBY', + 'WHERE', + 'LIMIT', + 'OFFSET', + 'HAVING', + 'WITH', + "';'", + 'AND', + 'OR', + context=_context, + ) + == 'ADD_OP' + ): ADD_OP = self._scan('ADD_OP', context=_context) expr_mul = self.expr_mul(S, _context) node = MathExpression(ADD_OP, node, expr_mul) @@ -602,7 +889,32 @@ _context = self.Context(_parent, self._scanner, 'expr_mul', [S]) expr_pow = self.expr_pow(S, _context) node = expr_pow - while self._peek('MUL_OP', 'ADD_OP', 'QMARK', 'r"\\)"', "','", 'SORT_DESC', 'SORT_ASC', 'CMP_OP', 'R_TYPE', "'IN'", 'GROUPBY', 'ORDERBY', 'WHERE', 'LIMIT', 'OFFSET', 'HAVING', 'WITH', "';'", 'AND', 'OR', context=_context) == 'MUL_OP': + while ( + self._peek( + 'MUL_OP', + 'ADD_OP', + 'QMARK', + 'r"\\)"', + "','", + 'SORT_DESC', + 'SORT_ASC', + 'CMP_OP', + 'R_TYPE', + "'IN'", + 'GROUPBY', + 'ORDERBY', + 'WHERE', + 'LIMIT', + 'OFFSET', + 'HAVING', + 'WITH', + "';'", + 'AND', + 'OR', + context=_context, + ) + == 'MUL_OP' + ): MUL_OP = self._scan('MUL_OP', context=_context) expr_pow = self.expr_pow(S, _context) node = MathExpression(MUL_OP, node, expr_pow) @@ -612,7 +924,33 @@ _context = self.Context(_parent, self._scanner, 'expr_pow', [S]) expr_base = self.expr_base(S, _context) node = expr_base - while self._peek('POW_OP', 'MUL_OP', 'ADD_OP', 'QMARK', 'r"\\)"', "','", 'SORT_DESC', 'SORT_ASC', 'CMP_OP', 'R_TYPE', "'IN'", 'GROUPBY', 'ORDERBY', 'WHERE', 'LIMIT', 'OFFSET', 'HAVING', 'WITH', "';'", 'AND', 'OR', context=_context) == 'POW_OP': + while ( + self._peek( + 'POW_OP', + 'MUL_OP', + 'ADD_OP', + 'QMARK', + 'r"\\)"', + "','", + 'SORT_DESC', + 'SORT_ASC', + 'CMP_OP', + 'R_TYPE', + "'IN'", + 'GROUPBY', + 'ORDERBY', + 'WHERE', + 'LIMIT', + 'OFFSET', + 'HAVING', + 'WITH', + "';'", + 'AND', + 'OR', + context=_context, + ) + == 'POW_OP' + ): self._scan('POW_OP', context=_context) expr_base = self.expr_base(S, _context) node = MathExpression(MUL_OP, node, expr_base) @@ -620,7 +958,22 @@ def expr_base(self, S, _parent=None): _context = self.Context(_parent, self._scanner, 'expr_base', [S]) - _token = self._peek('r"\\("', 'NULL', 'DATE', 'DATETIME', 'TRUE', 'FALSE', 'FLOAT', 'INT', 'STRING', 'SUBSTITUTE', 'VARIABLE', 'E_TYPE', 'FUNCTION', context=_context) + _token = self._peek( + 'r"\\("', + 'NULL', + 'DATE', + 'DATETIME', + 'TRUE', + 'FALSE', + 'FLOAT', + 'INT', + 'STRING', + 'SUBSTITUTE', + 'VARIABLE', + 'E_TYPE', + 'FUNCTION', + context=_context, + ) if _token not in ['r"\\("', 'VARIABLE', 'E_TYPE', 'FUNCTION']: const = self.const(_context) return const @@ -644,9 +997,52 @@ FUNCTION = self._scan('FUNCTION', context=_context) self._scan('r"\\("', context=_context) F = Function(FUNCTION) - if self._peek('UNARY_OP', 'r"\\)"', 'r"\\("', 'NULL', 'DATE', 'DATETIME', 'TRUE', 'FALSE', 'FLOAT', 'INT', 'STRING', 'SUBSTITUTE', 'VARIABLE', 'E_TYPE', 'FUNCTION', context=_context) != 'r"\\)"': + if ( + self._peek( + 'UNARY_OP', + 'r"\\)"', + 'r"\\("', + 'NULL', + 'DATE', + 'DATETIME', + 'TRUE', + 'FALSE', + 'FLOAT', + 'INT', + 'STRING', + 'SUBSTITUTE', + 'VARIABLE', + 'E_TYPE', + 'FUNCTION', + context=_context, + ) + != 'r"\\)"' + ): expr_add = self.expr_add(S, _context) - while self._peek("','", 'QMARK', 'r"\\)"', 'SORT_DESC', 'SORT_ASC', 'CMP_OP', 'R_TYPE', "'IN'", 'GROUPBY', 'ORDERBY', 'WHERE', 'LIMIT', 'OFFSET', 'HAVING', 'WITH', "';'", 'AND', 'OR', context=_context) == "','": + while ( + self._peek( + "','", + 'QMARK', + 'r"\\)"', + 'SORT_DESC', + 'SORT_ASC', + 'CMP_OP', + 'R_TYPE', + "'IN'", + 'GROUPBY', + 'ORDERBY', + 'WHERE', + 'LIMIT', + 'OFFSET', + 'HAVING', + 'WITH', + "';'", + 'AND', + 'OR', + context=_context, + ) + == "','" + ): F.append(expr_add) self._scan("','", context=_context) expr_add = self.expr_add(S, _context) @@ -659,9 +1055,52 @@ self._scan("'IN'", context=_context) self._scan('r"\\("', context=_context) F = Function('IN') - if self._peek('UNARY_OP', 'r"\\)"', 'r"\\("', 'NULL', 'DATE', 'DATETIME', 'TRUE', 'FALSE', 'FLOAT', 'INT', 'STRING', 'SUBSTITUTE', 'VARIABLE', 'E_TYPE', 'FUNCTION', context=_context) != 'r"\\)"': + if ( + self._peek( + 'UNARY_OP', + 'r"\\)"', + 'r"\\("', + 'NULL', + 'DATE', + 'DATETIME', + 'TRUE', + 'FALSE', + 'FLOAT', + 'INT', + 'STRING', + 'SUBSTITUTE', + 'VARIABLE', + 'E_TYPE', + 'FUNCTION', + context=_context, + ) + != 'r"\\)"' + ): expr_add = self.expr_add(S, _context) - while self._peek("','", 'QMARK', 'r"\\)"', 'SORT_DESC', 'SORT_ASC', 'CMP_OP', 'R_TYPE', "'IN'", 'GROUPBY', 'ORDERBY', 'WHERE', 'LIMIT', 'OFFSET', 'HAVING', 'WITH', "';'", 'AND', 'OR', context=_context) == "','": + while ( + self._peek( + "','", + 'QMARK', + 'r"\\)"', + 'SORT_DESC', + 'SORT_ASC', + 'CMP_OP', + 'R_TYPE', + "'IN'", + 'GROUPBY', + 'ORDERBY', + 'WHERE', + 'LIMIT', + 'OFFSET', + 'HAVING', + 'WITH', + "';'", + 'AND', + 'OR', + context=_context, + ) + == "','" + ): F.append(expr_add) self._scan("','", context=_context) expr_add = self.expr_add(S, _context) @@ -681,7 +1120,18 @@ def const(self, _parent=None): _context = self.Context(_parent, self._scanner, 'const', []) - _token = self._peek('NULL', 'DATE', 'DATETIME', 'TRUE', 'FALSE', 'FLOAT', 'INT', 'STRING', 'SUBSTITUTE', context=_context) + _token = self._peek( + 'NULL', + 'DATE', + 'DATETIME', + 'TRUE', + 'FALSE', + 'FLOAT', + 'INT', + 'STRING', + 'SUBSTITUTE', + context=_context, + ) if _token == 'NULL': self._scan('NULL', context=_context) return Constant(None, None)
--- a/rql/rqlgen.py Wed Feb 13 19:10:43 2019 +0100 +++ b/rql/rqlgen.py Fri Feb 15 15:46:02 2019 +0100 @@ -62,7 +62,7 @@ ... ('X','firstname','F'), ('X','surname','S') ), ... sorts=('F ASC', 'S DESC') ... ) - 'Person X\\nWHERE X work_for S , S name "Logilab" , X firstname F , X surname S\\nSORTBY F ASC, S DESC' + 'Person X\\nWHERE X work_for S , S name "Logilab" , X firstname F , X surname S\\nSORTBY F ASC, S DESC' # noqa """ result = [etype + ' X'] if nupplets: @@ -186,7 +186,7 @@ >>> s = RQLGenerator() >>> s.update('Person', (('firstname', "Clark"), ('lastname', "Kent")), ... (('job', "superhero"), ('nickname', "superman"))) - 'SET X job "superhero", X nickname "superman" WHERE X is "Person", X firstname "Clark", X lastname "Kent"' + 'SET X job "superhero", X nickname "superman" WHERE X is "Person", X firstname "Clark", X lastname "Kent"' # noqa """ old_restrictions = ['X is "%s"' % etype] old_restrictions += ['X %s "%s"' % (attr_name, attr_value)
--- a/rql/stcheck.py Wed Feb 13 19:10:43 2019 +0100 +++ b/rql/stcheck.py Fri Feb 15 15:46:02 2019 +0100 @@ -159,7 +159,9 @@ if node.groupby: # check that selected variables are used in groups for var in node.selection: - if isinstance(var, VariableRef) and not any(var.is_equivalent(g) for g in node.groupby): + if isinstance(var, VariableRef) and not any( + var.is_equivalent(g) for g in node.groupby + ): state.error('variable %s should be grouped' % var) for group in node.groupby: self._check_selected(group, 'group', state) @@ -539,8 +541,14 @@ # XXX node.having is a list of size 1 assert len(node.having) == 1 for term in node.having[0].get_nodes(Comparison): - lhsvariables = set(vref.variable for vref in term.children[0].get_nodes(VariableRef)) - rhsvariables = set(vref.variable for vref in term.children[1].get_nodes(VariableRef)) + lhsvariables = set( + vref.variable + for vref in term.children[0].get_nodes(VariableRef) + ) + rhsvariables = set( + vref.variable + for vref in term.children[1].get_nodes(VariableRef) + ) for var in lhsvariables | rhsvariables: var.stinfo.setdefault('having', []).append(term) if vargraph is not None: @@ -554,12 +562,16 @@ if term.optional in ('left', 'both'): for var in lhsvariables: if var.stinfo['attrvar'] is not None: - optcomps = var.stinfo['attrvar'].stinfo.setdefault('optcomparisons', set()) + optcomps = var.stinfo[ + 'attrvar' + ].stinfo.setdefault('optcomparisons', set()) optcomps.add(term) if term.optional in ('right', 'both'): for var in rhsvariables: if var.stinfo['attrvar'] is not None: - optcomps = var.stinfo['attrvar'].stinfo.setdefault('optcomparisons', set()) + optcomps = var.stinfo[ + 'attrvar' + ].stinfo.setdefault('optcomparisons', set()) optcomps.add(term) def rewrite_shared_optional(self, exists, var, identity_rel_scope=None):
--- a/test/unittest_analyze.py Wed Feb 13 19:10:43 2019 +0100 +++ b/test/unittest_analyze.py Fri Feb 15 15:46:02 2019 +0100 @@ -53,7 +53,9 @@ self.rdefs = {} for subjtype, dest_types in self.assoc_types: for objtype in dest_types: - self.rdefs[(subjtype, objtype)] = mock(subject=subjtype, object=objtype, cardinality=self.card) + self.rdefs[(subjtype, objtype)] = mock( + subject=subjtype, object=objtype, cardinality=self.card + ) def associations(self): return self.assoc_types @@ -368,8 +370,12 @@ def type_from_uid(name): self.assertEqual(name, "Societe") return 'Eetype' + uid_func_mapping = {'name': type_from_uid} - node = h.parse('Any X WHERE X name "Societe", X is ISOBJ, ISSUBJ is X, X is_instance_of ISIOOBJ, ISIOSUBJ is_instance_of X') + node = h.parse( + 'Any X WHERE X name "Societe", X is ISOBJ, ISSUBJ is X, ' + 'X is_instance_of ISIOOBJ, ISIOSUBJ is_instance_of X' + ) h.compute_solutions(node, uid_func_mapping, debug=DEBUG) select = node.children[0] sols = select.solutions @@ -380,16 +386,37 @@ for sol in sols: s.add(sol.get(var)) return s + self.assertEqual(var_sols('X'), set(('Eetype',))) - self.assertEqual(var_sols('X'), select.defined_vars['X'].stinfo['possibletypes']) - self.assertEqual(var_sols('ISSUBJ'), set(('Address', 'Company', 'Eetype', 'Person', 'Student'))) - self.assertEqual(var_sols('ISSUBJ'), select.defined_vars['ISSUBJ'].stinfo['possibletypes']) + self.assertEqual( + var_sols('X'), select.defined_vars['X'].stinfo['possibletypes'] + ) + self.assertEqual( + var_sols('ISSUBJ'), + set(('Address', 'Company', 'Eetype', 'Person', 'Student')), + ) + self.assertEqual( + var_sols('ISSUBJ'), + select.defined_vars['ISSUBJ'].stinfo['possibletypes'], + ) self.assertEqual(var_sols('ISOBJ'), set(('Eetype',))) - self.assertEqual(var_sols('ISOBJ'), select.defined_vars['ISOBJ'].stinfo['possibletypes']) - self.assertEqual(var_sols('ISIOSUBJ'), set(('Address', 'Company', 'Eetype', 'Person', 'Student'))) - self.assertEqual(var_sols('ISIOSUBJ'), select.defined_vars['ISIOSUBJ'].stinfo['possibletypes']) + self.assertEqual( + var_sols('ISOBJ'), + select.defined_vars['ISOBJ'].stinfo['possibletypes'], + ) + self.assertEqual( + var_sols('ISIOSUBJ'), + set(('Address', 'Company', 'Eetype', 'Person', 'Student')), + ) + self.assertEqual( + var_sols('ISIOSUBJ'), + select.defined_vars['ISIOSUBJ'].stinfo['possibletypes'], + ) self.assertEqual(var_sols('ISIOOBJ'), set(('Eetype',))) - self.assertEqual(var_sols('ISIOOBJ'), select.defined_vars['ISIOOBJ'].stinfo['possibletypes']) + self.assertEqual( + var_sols('ISIOOBJ'), + select.defined_vars['ISIOOBJ'].stinfo['possibletypes'], + ) def test_unusableuid_func_mapping(self): h = self.helper @@ -454,10 +481,16 @@ self.assertCountEqual(sols, [{'P': 'Person'}, {'P': 'Student'}]) def test_union(self): - node = self.helper.parse('(Any P WHERE X eid 0, X is Person, NOT X connait P) UNION (Any E1 WHERE E2 work_for E1, E2 eid 2)') + node = self.helper.parse( + '(Any P WHERE X eid 0, X is Person, NOT X connait P) ' + 'UNION (Any E1 WHERE E2 work_for E1, E2 eid 2)' + ) self.helper.compute_solutions(node, debug=DEBUG) sols = node.children[0].solutions - self.assertCountEqual(sols, [{'P': 'Person', 'X': 'Person'}, {'P': 'Student', 'X': 'Person'}]) + self.assertCountEqual( + sols, + [{'P': 'Person', 'X': 'Person'}, {'P': 'Student', 'X': 'Person'}], + ) sols = node.children[1].solutions self.assertCountEqual(sols, [{'E1': 'Company', 'E2': 'Person'}]) self.helper.simplify(node) @@ -468,8 +501,10 @@ self.assertCountEqual(sols, [{'E1': 'Company'}]) def test_exists(self): - node = self.helper.parse("Any X WHERE X firstname 'lulu'," - "EXISTS (X owned_by U, U name 'lulufanclub' OR U name 'managers');") + node = self.helper.parse( + "Any X WHERE X firstname 'lulu'," + "EXISTS (X owned_by U, U name 'lulufanclub' OR U name 'managers');" + ) self.helper.compute_solutions(node, debug=DEBUG) sols = node.children[0].solutions self.assertCountEqual(sols, [{'X': 'Person', @@ -513,13 +548,20 @@ self.assertEqual(node.children[0].with_[0].query.children[0].solutions, [{'X': 'Person', 'F': 'String'}]) # auto-simplification - self.assertEqual(len(node.children[0].with_[0].query.children), 1) - self.assertEqual(node.as_string(), 'Any L,Y,F WHERE Y located L, Y is Person WITH Y,F BEING (Any X,F WHERE X is Person, X firstname F)') - self.assertEqual(node.children[0].with_[0].query.children[0].solutions, - [{'X': 'Person', 'F': 'String'}]) + self.assertEqual( + node.as_string(), + 'Any L,Y,F WHERE Y located L, Y is Person WITH Y,F ' + 'BEING (Any X,F WHERE X is Person, X firstname F)', + ) + self.assertEqual( + node.children[0].with_[0].query.children[0].solutions, + [{'X': 'Person', 'F': 'String'}], + ) def test_insert(self): - node = self.helper.parse('INSERT Person X : X name "toto", X work_for Y WHERE Y name "logilab"') + node = self.helper.parse( + 'INSERT Person X : X name "toto", X work_for Y WHERE Y name "logilab"' + ) self.helper.compute_solutions(node, debug=DEBUG) sols = node.solutions self.assertCountEqual(sols, [{'X': 'Person', 'Y': 'Company'}])
--- a/test/unittest_compare.py Wed Feb 13 19:10:43 2019 +0100 +++ b/test/unittest_compare.py Fri Feb 15 15:46:02 2019 +0100 @@ -83,27 +83,36 @@ self._compareEquivalent(r1, r2) def test_same_request_complex(self): - r = "Any N, N2 WHERE N is Note, N2 is Note, N a_faire_par P1, P1 nom 'jphc', N2 a_faire_par P2, P2 nom 'ocy' ;" + r = ("Any N, N2 WHERE N is Note, N2 is Note, N a_faire_par P1, " + "P1 nom 'jphc', N2 a_faire_par P2, P2 nom 'ocy' ;") self._compareEquivalent(r, r) def test_same_request_comma_and(self): - r1 = "Any N, N2 WHERE N is Note, N2 is Note, N a_faire_par P1, P1 nom 'jphc', N2 a_faire_par P2, P2 nom 'ocy' ;" - r2 = "Any N, N2 WHERE N is Note AND N2 is Note AND N a_faire_par P1 AND P1 nom 'jphc' AND N2 a_faire_par P2 AND P2 nom 'ocy' ;" + r1 = ("Any N, N2 WHERE N is Note, N2 is Note, N a_faire_par P1, " + "P1 nom 'jphc', N2 a_faire_par P2, P2 nom 'ocy' ;") + r2 = ("Any N, N2 WHERE N is Note AND N2 is Note AND N a_faire_par P1 " + "AND P1 nom 'jphc' AND N2 a_faire_par P2 AND P2 nom 'ocy' ;") self._compareEquivalent(r1, r2) def test_same_request_diff_names_complex(self): - r1 = "Any N, N2 WHERE N is Note, N2 is Note, N a_faire_par P1, P1 nom 'jphc', N2 a_faire_par P2, P2 nom 'ocy' ;" - r2 = "Any Y, X WHERE X is Note, Y is Note, X a_faire_par A1, A1 nom 'ocy', Y a_faire_par A2, A2 nom 'jphc' ;" + r1 = ("Any N, N2 WHERE N is Note, N2 is Note, N a_faire_par P1, " + "P1 nom 'jphc', N2 a_faire_par P2, P2 nom 'ocy' ;") + r2 = ("Any Y, X WHERE X is Note, Y is Note, X a_faire_par A1, " + "A1 nom 'ocy', Y a_faire_par A2, A2 nom 'jphc' ;") self._compareEquivalent(r1, r2) def test_same_request_diff_order(self): - r1 = "Any N, N2 WHERE N is Note, N2 is Note, N a_faire_par P1, P1 nom 'jphc', N2 a_faire_par P2, P2 nom 'ocy' ;" - r2 = "Any N, N2 WHERE N2 is Note, N is Note, N a_faire_par P1, N2 a_faire_par P2, P2 nom 'ocy', P1 nom 'jphc' ;" + r1 = ("Any N, N2 WHERE N is Note, N2 is Note, N a_faire_par P1, " + "P1 nom 'jphc', N2 a_faire_par P2, P2 nom 'ocy' ;") + r2 = ("Any N, N2 WHERE N2 is Note, N is Note, N a_faire_par P1, " + "N2 a_faire_par P2, P2 nom 'ocy', P1 nom 'jphc' ;") self._compareEquivalent(r1, r2) def test_same_request_diff_order_diff_names(self): - r1 = "Any N, N2 WHERE N is Note, N2 is Note, N a_faire_par P1, P1 nom 'jphc', N2 a_faire_par P2, P2 nom 'ocy' ;" - r2 = "Any Y, X WHERE X is Note, X a_faire_par P1, P1 nom 'ocy', Y is Note, Y a_faire_par P2, P2 nom 'jphc' ;" + r1 = ("Any N, N2 WHERE N is Note, N2 is Note, N a_faire_par P1, " + "P1 nom 'jphc', N2 a_faire_par P2, P2 nom 'ocy' ;") + r2 = ("Any Y, X WHERE X is Note, X a_faire_par P1, P1 nom 'ocy', " + "Y is Note, Y a_faire_par P2, P2 nom 'jphc' ;") self._compareEquivalent(r1, r2) def test_same_request_with_comparison(self): @@ -112,18 +121,31 @@ self._compareEquivalent(r1, r2) def test_same_request_in_or(self): - r1 = "Note N WHERE N creation_date > today-10, N a_faire_par P, P nom 'jphc' or P nom 'ludal';" + r1 = ("Note N WHERE N creation_date > today-10, N a_faire_par P, " + "P nom 'jphc' or P nom 'ludal';") r2 = "Note K WHERE K a_faire_par Y, K creation_date > today-10, Y nom in ('jphc', 'ludal');" self._compareEquivalent(r1, r2) def test_same_request_reverse_or(self): - r1 = "Note N WHERE N creation_date > today-10, N a_faire_par P, P nom 'jphc' or P nom 'ludal';" - r2 = "Note N WHERE N creation_date > today-10, N a_faire_par P, P nom 'ludal' or P nom 'jphc';" + r1 = ( + "Note N WHERE N creation_date > today-10, N a_faire_par P, " + "P nom 'jphc' or P nom 'ludal';" + ) + r2 = ( + "Note N WHERE N creation_date > today-10, N a_faire_par P, " + "P nom 'ludal' or P nom 'jphc';" + ) self._compareEquivalent(r1, r2) def test_same_request_reverse_or2(self): - r1 = "Note N WHERE N creation_date > today-10, N a_faire_par P, P prenom 'jphc' or P nom 'ludal';" - r2 = "Note N WHERE N creation_date > today-10, N a_faire_par P, P nom 'ludal' or P prenom 'jphc';" + r1 = ( + "Note N WHERE N creation_date > today-10, N a_faire_par P, " + "P prenom 'jphc' or P nom 'ludal';" + ) + r2 = ( + "Note N WHERE N creation_date > today-10, N a_faire_par P, " + "P nom 'ludal' or P prenom 'jphc';" + ) self._compareEquivalent(r1, r2) def test_same_request_duplicate_expr(self): @@ -132,25 +154,37 @@ self._compareEquivalent(r1, r2) def test_same_request_not_in_or(self): - r1 = "Note K WHERE K a_faire_par Y, K creation_date > today-10, not Y nom in ('jphc', 'ludal');" - r2 = "Note K WHERE K a_faire_par Y, K creation_date > today-10, not Y nom 'jphc' and not Y nom 'ludal';" + r1 = ( + "Note K WHERE K a_faire_par Y, K creation_date > today-10, " + "not Y nom in ('jphc', 'ludal');" + ) + r2 = ( + "Note K WHERE K a_faire_par Y, K creation_date > today-10, " + "not Y nom 'jphc' and not Y nom 'ludal';" + ) self._compareEquivalent(r1, r2) # non equivalent queries ################################################## def test_diff_request(self): - r1 = "Any N, N2 WHERE N is Note, N2 is Note, N a_faire_par P1, P1 nom 'jphc', N2 a_faire_par P2, P2 nom 'ocy' ;" + r1 = ("Any N, N2 WHERE N is Note, N2 is Note, N a_faire_par P1, " + "P1 nom 'jphc', N2 a_faire_par P2, P2 nom 'ocy' ;") r2 = "Any X WHERE X is Note ;" self._compareNotEquivalent(r1, r2) def test_diff_request_and_or(self): - r1 = "Note N WHERE N creation_date > today-10, N a_faire_par P, P nom 'jphc' or P nom 'ludal';" - r2 = "Note N WHERE N creation_date > today-10, N a_faire_par P, P nom 'jphc', P nom 'ludal';" + r1 = ("Note N WHERE N creation_date > today-10, N a_faire_par P, " + "P nom 'jphc' or P nom 'ludal';") + r2 = ("Note N WHERE N creation_date > today-10, N a_faire_par P, " + "P nom 'jphc', P nom 'ludal';") + self._compareNotEquivalent(r1, r2) def test_diff_request_and_or2(self): - r1 = "Note N WHERE N creation_date > today-10, N a_faire_par P, P nom 'jphc' or P prenom 'ludal';" - r2 = "Note N WHERE N creation_date > today-10, N a_faire_par P, P nom 'jphc', P prenom 'ludal';" + r1 = ("Note N WHERE N creation_date > today-10, N a_faire_par P, " + "P nom 'jphc' or P prenom 'ludal';") + r2 = ("Note N WHERE N creation_date > today-10, N a_faire_par P, " + "P nom 'jphc', P prenom 'ludal';") self._compareNotEquivalent(r1, r2) def test_diff_request_non_selected_var(self): @@ -179,8 +213,10 @@ self._compareNotEquivalent(r1, r2) def test_diff_request_not_in_or(self): - r1 = "Note K WHERE K a_faire_par Y, K creation_date > today-10, not Y nom in ('jphc', 'ludal');" - r2 = "Note K WHERE K a_faire_par Y, K creation_date > today-10, not Y nom 'jphc' or not Y nom 'ludal';" + r1 = ("Note K WHERE K a_faire_par Y, K creation_date > today-10, " + "not Y nom in ('jphc', 'ludal');") + r2 = ("Note K WHERE K a_faire_par Y, K creation_date > today-10, " + "not Y nom 'jphc' or not Y nom 'ludal';") self._compareNotEquivalent(r1, r2)
--- a/test/unittest_editextensions.py Wed Feb 13 19:10:43 2019 +0100 +++ b/test/unittest_editextensions.py Fri Feb 15 15:46:02 2019 +0100 @@ -93,13 +93,19 @@ rqlst.check_references() def test_remove_exists(self): - rqlst = parse('Any U,COUNT(P) GROUPBY U WHERE U is CWUser, P? patch_reviewer U, EXISTS(P in_state S AND S name "pouet")').children[0] + rql_request = ('Any U,COUNT(P) GROUPBY U WHERE U is CWUser, ' + 'P? patch_reviewer U, EXISTS(P in_state S AND ' + 'S name "pouet")') + rqlst = parse(rql_request).children[0] orig = rqlst.as_string() rqlst.save_state() n = [r for r in rqlst.get_nodes(Exists)][0].query rqlst.remove_node(n) # check operations - self.assertEqual(rqlst.as_string(), 'Any U,COUNT(P) GROUPBY U WHERE U is CWUser, P? patch_reviewer U') + self.assertEqual( + rqlst.as_string(), + 'Any U,COUNT(P) GROUPBY U WHERE U is CWUser, P? patch_reviewer U' + ) # check references before recovering rqlst.check_references() rqlst.recover()
--- a/test/unittest_nodes.py Wed Feb 13 19:10:43 2019 +0100 +++ b/test/unittest_nodes.py Fri Feb 15 15:46:02 2019 +0100 @@ -95,7 +95,10 @@ select = tree.children[0] x = next(select.get_selected_variables()) self.assertRaises(RQLException, select.add_type_restriction, x.variable, 'Babar') - self.assertEqual(tree.as_string(), 'Any X WHERE X is IN(Person, Company), X name ILIKE "A%"') + self.assertEqual( + tree.as_string(), + 'Any X WHERE X is IN(Person, Company), X name ILIKE "A%"', + ) def test_add_is_in_type_restriction_multiple(self): tree = self.parse("Any X WHERE X is IN(Person, Company, Student, Address), " @@ -174,11 +177,18 @@ tree = self._parse("(Any X WHERE X is Person) UNION (Any X WHERE X is Company)") tree.save_state() tree.set_limit(10) - self.assertEqual(tree.as_string(), 'Any A LIMIT 10 WITH A BEING ((Any X WHERE X is Person) UNION (Any X WHERE X is Company))') + self.assertEqual( + tree.as_string(), + 'Any A LIMIT 10 WITH A BEING ' + '((Any X WHERE X is Person) UNION (Any X WHERE X is Company))', + ) select = tree.children[0] self.assertEqual(select.limit, 10) tree.recover() - self.assertEqual(tree.as_string(), '(Any X WHERE X is Person) UNION (Any X WHERE X is Company)') + self.assertEqual( + tree.as_string(), + '(Any X WHERE X is Person) UNION (Any X WHERE X is Company)', + ) def test_union_set_offset_1(self): tree = self._parse("Any X WHERE X is Person") @@ -194,25 +204,43 @@ def test_union_set_offset_2(self): # not undoable set_offset since a new root has to be introduced - tree = self._parse("(Any X WHERE X is Person) UNION (Any X WHERE X is Company)") + tree = self._parse( + "(Any X WHERE X is Person) UNION (Any X WHERE X is Company)" + ) tree.save_state() tree.set_offset(10) select = tree.children[0] - self.assertEqual(tree.as_string(), 'Any A OFFSET 10 WITH A BEING ((Any X WHERE X is Person) UNION (Any X WHERE X is Company))') + self.assertEqual( + tree.as_string(), + 'Any A OFFSET 10 WITH A BEING ' + '((Any X WHERE X is Person) UNION (Any X WHERE X is Company))', + ) self.assertEqual(select.offset, 10) tree.recover() - self.assertEqual(tree.as_string(), '(Any X WHERE X is Person) UNION (Any X WHERE X is Company)') + self.assertEqual( + tree.as_string(), + '(Any X WHERE X is Person) UNION (Any X WHERE X is Company)', + ) def test_union_undo_add_rel(self): - tree = self._parse("Any A WITH A BEING ((Any X WHERE X is Person) UNION (Any X WHERE X is Company))") + tree = self._parse( + "Any A WITH A BEING ((Any X WHERE X is Person) UNION (Any X WHERE X is Company))" + ) tree.save_state() select = tree.children[0] var = select.make_variable() mainvar = select.selection[0].variable select.add_relation(mainvar, 'name', var) - self.assertEqual(tree.as_string(), 'Any A WHERE A name B WITH A BEING ((Any X WHERE X is Person) UNION (Any X WHERE X is Company))') + self.assertEqual( + tree.as_string(), + 'Any A WHERE A name B WITH A BEING ' + '((Any X WHERE X is Person) UNION (Any X WHERE X is Company))', + ) tree.recover() - self.assertEqual(tree.as_string(), 'Any A WITH A BEING ((Any X WHERE X is Person) UNION (Any X WHERE X is Company))') + self.assertEqual( + tree.as_string(), + 'Any A WITH A BEING ((Any X WHERE X is Person) UNION (Any X WHERE X is Company))', + ) def test_select_set_limit(self): tree = self._simpleparse("Any X WHERE X is Person") @@ -326,16 +354,24 @@ self.assertEqual(tree.as_string(), 'Any X,Y GROUPBY X,Y') def test_recover_add_type_restriction_is_in(self): - tree = self._parse('Any X WHERE X is IN(Person, Company), X name ILIKE "A%"') + tree = self._parse( + 'Any X WHERE X is IN(Person, Company), X name ILIKE "A%"' + ) annotator.annotate(tree) # needed to get typerel index tree.save_state() select = tree.children[0] x = next(select.get_selected_variables()) select.add_type_restriction(x.variable, 'Company') - self.assertEqual(tree.as_string(), 'Any X WHERE X is IN(Company), X name ILIKE "A%"') + self.assertEqual( + tree.as_string(), + 'Any X WHERE X is IN(Company), X name ILIKE "A%"', + ) tree.recover() tree.check_references() - self.assertEqual(tree.as_string(), 'Any X WHERE X is IN(Person, Company), X name ILIKE "A%"') + self.assertEqual( + tree.as_string(), + 'Any X WHERE X is IN(Person, Company), X name ILIKE "A%"', + ) def test_recover_add_type_restriction_is_instance_of(self): tree = self._parse('Any X WHERE X is_instance_of IN(Person, Company), X name ILIKE "A%"') @@ -347,7 +383,10 @@ self.assertEqual(tree.as_string(), 'Any X WHERE X name ILIKE "A%", X is Company') tree.recover() tree.check_references() - self.assertEqual(tree.as_string(), 'Any X WHERE X is_instance_of IN(Person, Company), X name ILIKE "A%"') + self.assertEqual( + tree.as_string(), + 'Any X WHERE X is_instance_of IN(Person, Company), X name ILIKE "A%"', + ) def test_select_base_1(self): tree = self._parse("Any X WHERE X is Person") @@ -450,7 +489,9 @@ self._simpleparse("Any X,N WHERE X is Person, X name N, EXISTS(X work_for Y)") def test_copy(self): - tree = self._parse("Any X,LOWER(Y) GROUPBY N ORDERBY N WHERE X is Person, X name N, X date >= TODAY") + tree = self._parse( + "Any X,LOWER(Y) GROUPBY N ORDERBY N WHERE X is Person, X name N, X date >= TODAY" + ) select = stmts.Select() restriction = tree.children[0].where self.check_equal_but_not_same(restriction, restriction.copy(select)) @@ -486,7 +527,9 @@ self.assertEqual(dummy.get_variable_indices(), set([0])) def test_get_variable_indices_4(self): - dummy = self._parse("(Any X,XN WHERE X is EGroup, X name XN) UNION (Any C,CL WHERE C is EUser, C login CL)") + dummy = self._parse( + "(Any X,XN WHERE X is EGroup, X name XN) UNION (Any C,CL WHERE C is EUser, C login CL)" + ) dummy.children[0].solutions = [{'X': 'EGroup', 'XN': 'String'}] dummy.children[1].solutions = [{'C': 'EUser', 'CL': 'String'}] self.assertEqual(dummy.get_variable_indices(), set([0])) @@ -515,7 +558,9 @@ self.assertEqual(tree.main_variables[0][1].name, 'X') def test_insert_multi(self): - tree = self._parse('INSERT Person X, Person Y : X name "bidule", Y name "chouette", X friend Y') + tree = self._parse( + 'INSERT Person X, Person Y : X name "bidule", Y name "chouette", X friend Y' + ) # test specific attributes self.assertEqual(len(tree.main_relations), 3) for relation in tree.main_relations: @@ -635,9 +680,14 @@ # non regression tests #################################################### def test_get_description_and_get_type(self): - tree = sparse("Any N,COUNT(X),NOW-D GROUPBY N WHERE X name N, X creation_date D;") + tree = sparse( + "Any N,COUNT(X),NOW-D GROUPBY N WHERE X name N, X creation_date D;" + ) tree.schema = schema - self.assertEqual(tree.get_description(), [['name', 'COUNT(Company, Person, Student)', 'creation_date']]) + self.assertEqual( + tree.get_description(), + [['name', 'COUNT(Company, Person, Student)', 'creation_date']], + ) select = tree.children[0] self.assertEqual(select.selection[0].get_type(), 'Any') self.assertEqual(select.selection[1].get_type(), 'Int') @@ -647,8 +697,12 @@ def test_date_arithmetic(self): minus_expr = sparse("Any D1-D2;").children[0].selection[0] plus_expr = sparse("Any D1+D2;").children[0].selection[0] - for d1t, d2t in itertools.combinations_with_replacement(['Date', 'Datetime', 'TZDatetime'], 2): - self.assertEqual(minus_expr.get_type({'D1': d1t, 'D2': d2t}), 'Interval') + for d1t, d2t in itertools.combinations_with_replacement( + ['Date', 'Datetime', 'TZDatetime'], 2 + ): + self.assertEqual( + minus_expr.get_type({'D1': d1t, 'D2': d2t}), 'Interval' + ) with self.assertRaises(CoercionError): plus_expr.get_type({'D1': d1t, 'D2': d2t}) for d1t in ('Date', 'Datetime', 'TZDatetime'): @@ -669,11 +723,17 @@ def test_get_description_mainvar_objrel(self): tree = sparse('Any X,R,D,Y WHERE X work_for R, R creation_date D, Y owned_by X') - self.assertEqual(tree.get_description(0), [['Person', 'work_for', 'creation_date', 'owned_by_object']]) + self.assertEqual( + tree.get_description(0), + [['Person', 'work_for', 'creation_date', 'owned_by_object']], + ) def test_get_description_mainvar_symrel(self): tree = sparse('Any X,R,D,Y WHERE X work_for R, R creation_date D, Y connait X') - self.assertEqual(tree.get_description(0), [['Person, Student', 'work_for', 'creation_date', 'connait']]) + self.assertEqual( + tree.get_description(0), + [['Person, Student', 'work_for', 'creation_date', 'connait']], + ) def test_get_description_cast(self): tree = sparse('Any CAST(String, Y) WHERE X creation_date Y')
--- a/test/unittest_parser.py Wed Feb 13 19:10:43 2019 +0100 +++ b/test/unittest_parser.py Fri Feb 15 15:46:02 2019 +0100 @@ -40,8 +40,14 @@ # FIXME: incorrect because X/Y are not bound, not a syntax error "Personne P WHERE OFFSET 200;", - 'Any X GROUPBY X ORDERBY X WHERE X nom "toto" UNION Any X GROUPBY X ORDERBY X WHERE X firstname "toto";', - '(Any X GROUPBY X WHERE X nom "toto") UNION (Any X GROUPBY X WHERE X firstname "toto") ORDERBY X;', + ( + 'Any X GROUPBY X ORDERBY X WHERE X nom "toto" UNION Any X GROUPBY X ' + 'ORDERBY X WHERE X firstname "toto";' + ), + ( + '(Any X GROUPBY X WHERE X nom "toto") UNION ' + '(Any X GROUPBY X WHERE X firstname "toto") ORDERBY X;' + ), 'Any X, X/Y FROM (Any SUM(X) WHERE X is Person) WHERE X is Person;', # missing AS for subquery @@ -70,9 +76,12 @@ SPEC_QUERIES = ( 'Any X WHERE X eid 53;', 'Any X WHERE X eid -53;', - "Document X WHERE X occurence_of F, F class C, C name 'Bande dessinée', X owned_by U, U login 'syt', X available true;", - u"Document X WHERE X occurence_of F, F class C, C name 'Bande dessinée', X owned_by U, U login 'syt', X available true;", - "Personne P WHERE P travaille_pour S, S nom 'Eurocopter', P interesse_par T, T nom 'formation';", + ("Document X WHERE X occurence_of F, F class C, C name 'Bande dessinée', " + "X owned_by U, U login 'syt', X available true;"), + (u"Document X WHERE X occurence_of F, F class C, C name 'Bande dessinée', " + "X owned_by U, U login 'syt', X available true;"), + ("Personne P WHERE P travaille_pour S, S nom 'Eurocopter', P interesse_par T, " + "T nom 'formation';"), "Note N WHERE N ecrit_le D, D day > (today -10), N ecrit_par P, P nom 'jphc' or P nom 'ocy';", "Personne P WHERE (P interesse_par T, T nom 'formation') or (P ville 'Paris');", "Any X ORDERBY S DESC WHERE X is Person, X firstname 'Anne', X surname S;", @@ -96,7 +105,10 @@ # some additional cases 'INSERT Person X : X name "bidule", Y workfor X WHERE Y name "logilab";', - 'DISTINCT Any X,A,B,C,D ORDERBY A ASC WHERE P eid 41, X concerns P, P is Project, X is Story,X title A,X state B,X priority C,X cost D;', + ( + 'DISTINCT Any X,A,B,C,D ORDERBY A ASC WHERE P eid 41, X concerns P, ' + 'P is Project, X is Story,X title A,X state B,X priority C,X cost D;' + ), 'Any X WHERE X has_text "2.12.0";', 'Any X,A,B,C,D ORDERBY A ASC WHERE X concerns 41,X title A,X state B,X priority C,X cost D;', @@ -114,7 +126,10 @@ '(Any X WHERE X eid > 12) UNION (Any X WHERE X eid < 23);', '(Any X WHERE X nom "toto") UNION (Any X WHERE X firstname "toto");', - '(Any X GROUPBY X WHERE X nom "toto") UNION (Any X GROUPBY X ORDERBY X WHERE X firstname "toto");', + ( + '(Any X GROUPBY X WHERE X nom "toto") UNION ' + '(Any X GROUPBY X ORDERBY X WHERE X firstname "toto");' + ), 'Any X, X/Y WHERE X is Person WITH Y BEING (Any SUM(X) WHERE X is Person);', 'Any Y, COUNT(X) GROUPBY Y WHERE X bla Y WITH Y BEING ((Person X) UNION (Document X));', @@ -205,7 +220,10 @@ self.assertEqual(isinstance(base, nodes.Or), 1) self.assertEqual(isinstance(base.children[0], nodes.And), 1) self.assertEqual(isinstance(base.children[1], nodes.Relation), 1) - self.assertEqual(str(tree), 'Any X WHERE (X firstname "lulu", X name "toto") OR (X name "tutu")') + self.assertEqual( + str(tree), + 'Any X WHERE (X firstname "lulu", X name "toto") OR (X name "tutu")', + ) def test_precedence_2(self): tree = self.parse("Any X WHERE X firstname 'lulu', X name 'toto' OR X name 'tutu';") @@ -213,7 +231,10 @@ self.assertEqual(isinstance(base, nodes.And), 1) self.assertEqual(isinstance(base.children[0], nodes.Relation), 1) self.assertEqual(isinstance(base.children[1], nodes.Or), 1) - self.assertEqual(str(tree), 'Any X WHERE X firstname "lulu", (X name "toto") OR (X name "tutu")') + self.assertEqual( + str(tree), + 'Any X WHERE X firstname "lulu", (X name "toto") OR (X name "tutu")', + ) def test_precedence_3(self): tree = self.parse("Any X WHERE X firstname 'lulu' AND (X name 'toto' or X name 'tutu');") @@ -221,7 +242,10 @@ self.assertEqual(isinstance(base, nodes.And), 1) self.assertEqual(isinstance(base.children[0], nodes.Relation), 1) self.assertEqual(isinstance(base.children[1], nodes.Or), 1) - self.assertEqual(str(tree), 'Any X WHERE X firstname "lulu", (X name "toto") OR (X name "tutu")') + self.assertEqual( + str(tree), + 'Any X WHERE X firstname "lulu", (X name "toto") OR (X name "tutu")', + ) def test_precedence_4(self): tree = self.parse("Any X WHERE X firstname 'lulu' OR X name 'toto' AND X name 'tutu';") @@ -308,11 +332,15 @@ self.assertEqual(related.optional, 'both') def test_exists(self): - tree = self.parse("Any X WHERE X firstname 'lulu'," - "EXISTS (X owned_by U, U in_group G, G name 'lulufanclub' OR G name 'managers');") - self.assertEqual(tree.as_string(), - 'Any X WHERE X firstname "lulu", ' - 'EXISTS(X owned_by U, U in_group G, (G name "lulufanclub") OR (G name "managers"))') + tree = self.parse( + "Any X WHERE X firstname 'lulu'," + "EXISTS (X owned_by U, U in_group G, G name 'lulufanclub' OR G name 'managers');" + ) + self.assertEqual( + tree.as_string(), + 'Any X WHERE X firstname "lulu", ' + 'EXISTS(X owned_by U, U in_group G, (G name "lulufanclub") OR (G name "managers"))', + ) exists = tree.children[0].where.get_nodes(nodes.Exists)[0] self.assertTrue(exists.children[0].parent is exists) self.assertTrue(exists.parent)
--- a/test/unittest_stcheck.py Wed Feb 13 19:10:43 2019 +0100 +++ b/test/unittest_stcheck.py Fri Feb 15 15:46:02 2019 +0100 @@ -214,8 +214,10 @@ self.annotate = helper.annotate def test_copy_exists(self): - tree = self.parse("Any X WHERE X firstname 'lulu'," - "EXISTS (X owned_by U, U work_for G, G name 'lulufanclub' OR G name 'managers');") + tree = self.parse( + "Any X WHERE X firstname 'lulu'," + "EXISTS (X owned_by U, U work_for G, G name 'lulufanclub' OR G name 'managers');" + ) self.simplify(tree) copy = tree.copy() exists = copy.get_nodes(nodes.Exists)[0] @@ -235,7 +237,10 @@ newroot.append(copy) self.annotate(newroot) self.simplify(newroot) - self.assertEqual(newroot.as_string(), 'Any 1,U WHERE 2 owned_by U, NOT EXISTS(1 owned_by U)') + self.assertEqual( + newroot.as_string(), + 'Any 1,U WHERE 2 owned_by U, NOT EXISTS(1 owned_by U)', + ) self.assertEqual(copy.defined_vars['U'].valuable_references(), 3) @@ -273,32 +278,54 @@ self.assertTrue(C.scope is rqlst, C.scope) def test_not_rel_normalization_3(self): - rqlst = self.parse('Any X WHERE C is Company, X work_for C, NOT C name "World Company"').children[0] - self.assertEqual(rqlst.as_string(), 'Any X WHERE C is Company, X work_for C, NOT C name "World Company"') + rqlst = self.parse( + 'Any X WHERE C is Company, X work_for C, NOT C name "World Company"' + ).children[0] + self.assertEqual( + rqlst.as_string(), + 'Any X WHERE C is Company, X work_for C, NOT C name "World Company"', + ) C = rqlst.defined_vars['C'] self.assertTrue(C.scope is rqlst, C.scope) def test_not_rel_normalization_4(self): - rqlst = self.parse('Any X WHERE C is Company, NOT (X work_for C, C name "World Company")').children[0] - self.assertEqual(rqlst.as_string(), 'Any X WHERE C is Company, NOT EXISTS(X work_for C, C name "World Company")') + rqlst = self.parse( + 'Any X WHERE C is Company, NOT (X work_for C, C name "World Company")' + ).children[0] + self.assertEqual( + rqlst.as_string(), + 'Any X WHERE C is Company, NOT EXISTS(X work_for C, C name "World Company")', + ) C = rqlst.defined_vars['C'] self.assertFalse(C.scope is rqlst, C.scope) def test_not_rel_normalization_5(self): - rqlst = self.parse('Any X WHERE X work_for C, EXISTS(C identity D, NOT Y work_for D, D name "World Company")').children[0] - self.assertEqual(rqlst.as_string(), 'Any X WHERE X work_for C, EXISTS(C identity D, NOT EXISTS(Y work_for D), D name "World Company")') + rqlst = self.parse( + 'Any X WHERE X work_for C, ' + 'EXISTS(C identity D, NOT Y work_for D, D name "World Company")' + ).children[0] + self.assertEqual( + rqlst.as_string(), + 'Any X WHERE X work_for C, ' + 'EXISTS(C identity D, NOT EXISTS(Y work_for D), D name "World Company")', + ) + D = rqlst.defined_vars['D'] D = rqlst.defined_vars['D'] self.assertFalse(D.scope is rqlst, D.scope) self.assertTrue(D.scope.parent.scope is rqlst, D.scope.parent.scope) def test_subquery_annotation_1(self): - rqlst = self.parse('Any X WITH X BEING (Any X WHERE C is Company, EXISTS(X work_for C))').children[0] + rqlst = self.parse( + 'Any X WITH X BEING (Any X WHERE C is Company, EXISTS(X work_for C))' + ).children[0] C = rqlst.with_[0].query.children[0].defined_vars['C'] self.assertFalse(C.scope is rqlst, C.scope) self.assertEqual(len(C.stinfo['relations']), 1) def test_subquery_annotation_2(self): - rqlst = self.parse('Any X,ET WITH X,ET BEING (Any X, ET WHERE C is ET, EXISTS(X work_for C))').children[0] + rqlst = self.parse( + 'Any X,ET WITH X,ET BEING (Any X, ET WHERE C is ET, EXISTS(X work_for C))' + ).children[0] C = rqlst.with_[0].query.children[0].defined_vars['C'] self.assertTrue(C.scope is rqlst.with_[0].query.children[0], C.scope) self.assertEqual(len(C.stinfo['relations']), 2) @@ -308,7 +335,10 @@ def test_no_attr_var_if_uid_rel(self): with self.assertRaises(BadRQLQuery) as cm: self.parse('Any X, Y WHERE X work_for Z, Y work_for Z, X eid > Y') - self.assertEqual(str(cm.exception), 'variable Y should not be used as rhs of attribute relation X eid > Y') + self.assertEqual( + str(cm.exception), + 'variable Y should not be used as rhs of attribute relation X eid > Y', + ) def test_no_uid_rel_if_not_constant(self): rqlst = self.parse('Any X,EID WHERE X eid EID').children[0]
--- a/test/unittest_utils.py Wed Feb 13 19:10:43 2019 +0100 +++ b/test/unittest_utils.py Fri Feb 15 15:46:02 2019 +0100 @@ -46,7 +46,10 @@ self.visitor.visit(tree) def test_methods_3(self): - tree = parse('Set X nom "yo" WHERE X is Person', {'Person': nodes.Constant('Person', 'etype')}) + tree = parse( + 'Set X nom "yo" WHERE X is Person', + {'Person': nodes.Constant('Person', 'etype')}, + ) self.visitor.visit(tree) def test_methods_4(self):
--- a/tox.ini Wed Feb 13 19:10:43 2019 +0100 +++ b/tox.ini Fri Feb 15 15:46:02 2019 +0100 @@ -11,7 +11,7 @@ basepython = python3 deps = flake8 -commands = flake8 {posargs:--ignore=E501,E741,F403,F405,F811,E123,E226,W503,E241,W504,E126,E121} +commands = flake8 {posargs:--ignore=E741,F403,F405,F811,E123,E226,W503,E241,W504,E126,E121} [pytest] python_files = *test_*.py