diff --git a/_exceptions.py b/_exceptions.py index 9608f5a83b22dac97d2f6f0a8e7d5fc23e5975c1_X2V4Y2VwdGlvbnMucHk=..cba0eb99537b1dd0afe56fb1be2d60123f394f4b_X2V4Y2VwdGlvbnMucHk= 100644 --- a/_exceptions.py +++ b/_exceptions.py @@ -23,6 +23,6 @@ class BadRQLQuery(RQLException): """Raised when there is a no sense in the rql query.""" - + class CoercionError(RQLException): """Failed to infer type of a math expression.""" diff --git a/compare.py b/compare.py index 9608f5a83b22dac97d2f6f0a8e7d5fc23e5975c1_Y29tcGFyZS5weQ==..cba0eb99537b1dd0afe56fb1be2d60123f394f4b_Y29tcGFyZS5weQ== 100644 --- a/compare.py +++ b/compare.py @@ -25,5 +25,5 @@ 'selected' : [], 'restriction' : {}, } - + canon = RQLCanonizer().visit(rql_tree, canon) @@ -29,5 +29,5 @@ canon = RQLCanonizer().visit(rql_tree, canon) - + # forge variable name for var, name_parts in allvars.values(): name_parts.sort() @@ -35,7 +35,7 @@ sort(canon) if verbose: print 'CANON FOR', rql_tree - from pprint import pprint + from pprint import pprint pprint(canon) return canon @@ -45,9 +45,9 @@ canon_dict['selection'].sort() for values in canon_dict['restriction'].values(): values.sort() - + class SkipChildren(Exception): """Signal indicating to ignore the current child.""" class RQLCanonizer(object): """Build a dictionnary which represents a RQL syntax tree.""" @@ -49,9 +49,9 @@ class SkipChildren(Exception): """Signal indicating to ignore the current child.""" class RQLCanonizer(object): """Build a dictionnary which represents a RQL syntax tree.""" - + def visit(self, node, canon): try: node.accept(self, canon) @@ -77,6 +77,6 @@ l.append(node) for var in node.iget_nodes(VariableRef): var.parent.replace(var, allvars[var.variable][0]) - + def visit_group(self, group, canon): canon['group'] = group @@ -81,5 +81,5 @@ def visit_group(self, group, canon): canon['group'] = group - + def visit_sort(self, sort, canon): canon['sort'] = sort @@ -84,5 +84,5 @@ def visit_sort(self, sort, canon): canon['sort'] = sort - + def visit_sortterm(self, sortterm, canon): pass @@ -87,5 +87,5 @@ def visit_sortterm(self, sortterm, canon): pass - + def visit_and(self, et, canon): pass @@ -90,6 +90,6 @@ def visit_and(self, et, canon): pass - + def visit_or(self, ou, canon): canon_dict = {} keys = [] @@ -108,7 +108,7 @@ for expr in canon_dict[key]: self.manage_relation(expr, canon, r_list) raise SkipChildren() - + def manage_relation(self, relation, canon, r_list): lhs, rhs = relation.get_parts() # handle special case of the IN function @@ -146,8 +146,8 @@ rhs_vars = rhs.get_nodes(VariableRef) if not rhs_vars: expr_reminder = "%s_%s" % (expr_reminder, rhs) - + for var in lhs_vars + rhs_vars: var = var.variable canon['all_variables'][var][1].append(expr_reminder) @@ -150,9 +150,9 @@ for var in lhs_vars + rhs_vars: var = var.variable canon['all_variables'][var][1].append(expr_reminder) - + def visit_relation(self, relation, canon): key = '%s%s' % (relation.r_type, relation._not) r_list = canon['restriction'].setdefault(key, []) self.manage_relation(relation, canon, r_list) @@ -155,8 +155,8 @@ def visit_relation(self, relation, canon): key = '%s%s' % (relation.r_type, relation._not) r_list = canon['restriction'].setdefault(key, []) self.manage_relation(relation, canon, r_list) - - + + def visit_comparison(self, comparison, canon): """do nothing for this node type""" @@ -161,5 +161,5 @@ def visit_comparison(self, comparison, canon): """do nothing for this node type""" - + def visit_mathexpression(self, mathexpression, canon): """do nothing for this node type""" @@ -164,5 +164,5 @@ def visit_mathexpression(self, mathexpression, canon): """do nothing for this node type""" - + def visit_function(self, function, canon): """do nothing for this node type""" @@ -167,6 +167,6 @@ def visit_function(self, function, canon): """do nothing for this node type""" - + def visit_variableref(self, varref, canon): varref.parent.replace(varref, canon['all_variables'][varref.variable][0]) @@ -170,7 +170,7 @@ def visit_variableref(self, varref, canon): varref.parent.replace(varref, canon['all_variables'][varref.variable][0]) - + def visit_constant(self, constante, canon): """do nothing for this node type""" diff --git a/editextensions.py b/editextensions.py index 9608f5a83b22dac97d2f6f0a8e7d5fc23e5975c1_ZWRpdGV4dGVuc2lvbnMucHk=..cba0eb99537b1dd0afe56fb1be2d60123f394f4b_ZWRpdGV4dGVuc2lvbnMucHk= 100644 --- a/editextensions.py +++ b/editextensions.py @@ -18,7 +18,7 @@ def add_main_restriction(rqlst, new_type, r_type, direction): """The result_tree must represent the same restriction as 'rqlst' and : - 'new_varname' IS <new_type> - - 'old_main_var' <r_type> 'new_varname' + - 'old_main_var' <r_type> 'new_varname' """ new_var = rqlst.make_variable(new_type) # new_var IS new_type @@ -41,7 +41,7 @@ if rel.r_type == 'has_text': node.remove_node(rel) return - + def get_vars_relations(node): """Return a dict with 'var_names' as keys, and the list of relations which concern them. diff --git a/interfaces.py b/interfaces.py index 9608f5a83b22dac97d2f6f0a8e7d5fc23e5975c1_aW50ZXJmYWNlcy5weQ==..cba0eb99537b1dd0afe56fb1be2d60123f394f4b_aW50ZXJmYWNlcy5weQ== 100644 --- a/interfaces.py +++ b/interfaces.py @@ -12,7 +12,7 @@ """RQL expects some base types to exists: String, Float, Int, Boolean, Date and a base relation : is """ - + def has_entity(self, etype): """Return true if the given type is defined in the schema. """ @@ -16,7 +16,7 @@ def has_entity(self, etype): """Return true if the given type is defined in the schema. """ - + def has_relation(self, rtype): """Return true if the given relation's type is defined in the schema. """ @@ -20,6 +20,6 @@ def has_relation(self, rtype): """Return true if the given relation's type is defined in the schema. """ - + def entities(self, schema=None): """Return the list of possible types. @@ -24,8 +24,8 @@ def entities(self, schema=None): """Return the list of possible types. - + If schema is not None, return a list of schemas instead of types. """ def relations(self, schema=None): """Return the list of possible relations. @@ -27,9 +27,9 @@ If schema is not None, return a list of schemas instead of types. """ def relations(self, schema=None): """Return the list of possible relations. - + If schema is not None, return a list of schemas instead of relation's types. """ @@ -37,9 +37,9 @@ def relation_schema(self, rtype): """Return the relation schema for the given relation type. """ - + class IRelationSchema(Interface): """Interface for Relation schema (a relation is a named oriented link between two entities). """ @@ -41,10 +41,10 @@ class IRelationSchema(Interface): """Interface for Relation schema (a relation is a named oriented link between two entities). """ - + def associations(self): """Return a list of (fromtype, [totypes]) defining between which types this relation may exists. """ @@ -47,8 +47,8 @@ def associations(self): """Return a list of (fromtype, [totypes]) defining between which types this relation may exists. """ - + def subjects(self): """Return a list of types which can be subject of this relation. """ @@ -52,10 +52,10 @@ def subjects(self): """Return a list of types which can be subject of this relation. """ - + def objects(self): """Return a list of types which can be object of this relation. """ class IEntitySchema(Interface): """Interface for Entity schema.""" @@ -56,11 +56,11 @@ def objects(self): """Return a list of types which can be object of this relation. """ class IEntitySchema(Interface): """Interface for Entity schema.""" - + def is_final(self): """Return true if the entity is a final entity (ie cannot be used as subject of a relation). """ @@ -63,5 +63,5 @@ def is_final(self): """Return true if the entity is a final entity (ie cannot be used as subject of a relation). """ - + diff --git a/parser.g b/parser.g index 9608f5a83b22dac97d2f6f0a8e7d5fc23e5975c1_cGFyc2VyLmc=..cba0eb99537b1dd0afe56fb1be2d60123f394f4b_cGFyc2VyLmc= 100644 --- a/parser.g +++ b/parser.g @@ -104,7 +104,7 @@ token SUBSTITUTE: r'%\([A-Za-z_0-9]+\)s' -# Grammar entry ############################################################### +#// Grammar entry ############################################################### rule goal: DELETE _delete<<Delete()>> ';' {{ return _delete }} @@ -115,10 +115,10 @@ | union<<Union()>> ';' {{ return union }} -# Deletion ################################################################### +#// Deletion ################################################################### rule _delete<<R>>: decl_rels<<R>> where<<R>> {{ return R }} | decl_vars<<R>> where<<R>> {{ return R }} @@ -119,10 +119,10 @@ rule _delete<<R>>: decl_rels<<R>> where<<R>> {{ return R }} | decl_vars<<R>> where<<R>> {{ return R }} -# Insertion ################################################################## +#// Insertion ################################################################## rule _insert<<R>>: decl_vars<<R>> insert_rels<<R>> {{ return R }} @@ -132,8 +132,8 @@ | -# Update ##################################################################### +#// Update ##################################################################### rule update<<R>>: decl_rels<<R>> where<<R>> {{ return R }} @@ -136,8 +136,8 @@ rule update<<R>>: decl_rels<<R>> where<<R>> {{ return R }} -# Selection ################################################################## +#// Selection ################################################################## rule union<<R>>: select<<Select()>> {{ R.append(select); return R }} @@ -166,5 +166,5 @@ -# other clauses (groupby, orderby, with, having) ############################## +#// other clauses (groupby, orderby, with, having) ############################## @@ -170,5 +170,5 @@ -# to remove in rql 1.0 +#// to remove in rql 1.0 rule dorderby<<S>>: orderby<<S>> {{ if orderby: warn('ORDERBY is now before WHERE clause') }} rule dgroupby<<S>>: groupby<<S>> {{ if groupby: warn('GROUPBY is now before WHERE clause') }} rule dlimit_offset<<S>>: limit_offset<<S>> {{ if limit_offset: warn('LIMIT/OFFSET are now before WHERE clause') }} @@ -213,7 +213,7 @@ | {{ return 1 # default to SORT_ASC }} -# Limit and offset ############################################################ +#// Limit and offset ############################################################ rule limit_offset<<R>> : limit<<R>> offset<<R>> {{ return limit or offset }} @@ -224,7 +224,7 @@ | -# Restriction statements ###################################################### +#// Restriction statements ###################################################### rule where<<S>>: WHERE restriction<<S>> {{ S.set_where(restriction) }} | @@ -259,7 +259,7 @@ rule opt_right<<S>>: QMARK {{ return 'right' }} | -# common statements ########################################################### +#// common statements ########################################################### rule variables<<S>>: {{ vars = [] }} var<<S>> {{ vars.append(var) }} diff --git a/parser.py b/parser.py index 9608f5a83b22dac97d2f6f0a8e7d5fc23e5975c1_cGFyc2VyLnB5..cba0eb99537b1dd0afe56fb1be2d60123f394f4b_cGFyc2VyLnB5 100644 --- a/parser.py +++ b/parser.py @@ -647,7 +647,7 @@ if __name__ == '__main__': from sys import argv - + parser = Hercule(HerculeScanner(argv[1])) e_types = {} # parse the RQL string diff --git a/parser_main.py b/parser_main.py index 9608f5a83b22dac97d2f6f0a8e7d5fc23e5975c1_cGFyc2VyX21haW4ucHk=..cba0eb99537b1dd0afe56fb1be2d60123f394f4b_cGFyc2VyX21haW4ucHk= 100644 --- a/parser_main.py +++ b/parser_main.py @@ -8,7 +8,7 @@ if __name__ == '__main__': from sys import argv - + parser = Hercule(HerculeScanner(argv[1])) e_types = {} # parse the RQL string diff --git a/rqlgen.py b/rqlgen.py index 9608f5a83b22dac97d2f6f0a8e7d5fc23e5975c1_cnFsZ2VuLnB5..cba0eb99537b1dd0afe56fb1be2d60123f394f4b_cnFsZ2VuLnB5 100644 --- a/rqlgen.py +++ b/rqlgen.py @@ -19,7 +19,7 @@ :Parameters: * `etype`: the desired entity type (can be 'Any') - + * `nupplets`: a list of 4-uples (subject, relation, object, not). <subject> and <object> may be a string representing a variable or a constant. The special variable X represents the searched set @@ -28,5 +28,5 @@ <not> is a boolean indicating it should be a negative statement (0 -> positive statement, 1 -> negative statement). You may omit this parameter, it default to 0. - + * `groups`: a list of variables to use in groups @@ -32,7 +32,7 @@ * `groups`: a list of variables to use in groups - + * `sorts`: a list of sort term. A sort term is a string designing a variable and optionnaly the sort order ('ASC' or 'DESC'). If the sort order is omitted default to 'ASC' Example: @@ -34,9 +34,9 @@ * `sorts`: a list of sort term. A sort term is a string designing a variable and optionnaly the sort order ('ASC' or 'DESC'). If the sort order is omitted default to 'ASC' Example: - + >>> s = RQLGenerator() >>> s.select('Any', (('X', 'eid', 14),) ) 'Any X\\nWHERE X eid 14' @@ -56,7 +56,7 @@ result.append(self.sortby(sorts)) return '\n'.join(result) - + def where(self, nupplets): """Return a WHERE statement. @@ -71,7 +71,7 @@ this parameter, it default to 0. Example: - + >>> s = RQLGenerator() >>> s.where( (('X', 'eid', 14),) ) 'WHERE X eid 14' @@ -75,7 +75,7 @@ >>> s = RQLGenerator() >>> s.where( (('X', 'eid', 14),) ) 'WHERE X eid 14' - >>> s.where( ( ('X','work_for','S'), ('S','name','"Logilab"'), + >>> s.where( ( ('X','work_for','S'), ('S','name','"Logilab"'), ... ('X','firstname','F'), ('X','surname','S') ) ) 'WHERE X work_for S , S name "Logilab" , X firstname F , X surname S' """ @@ -92,6 +92,6 @@ result.append(',') return ' '.join(result) - + def groupby(self, groups): """Return a GROUPBY statement. @@ -96,6 +96,6 @@ def groupby(self, groups): """Return a GROUPBY statement. - + :param groups: a list of variables to use in groups Example: @@ -99,10 +99,10 @@ :param groups: a list of variables to use in groups Example: - + >>> s = RQLGenerator() >>> s.groupby(('F', 'S')) 'GROUPBY F, S' """ return 'GROUPBY %s' % ', '.join(groups) @@ -103,9 +103,9 @@ >>> s = RQLGenerator() >>> s.groupby(('F', 'S')) 'GROUPBY F, S' """ return 'GROUPBY %s' % ', '.join(groups) - + def sortby(self, sorts): """Return a SORTBY statement. @@ -110,6 +110,6 @@ def sortby(self, sorts): """Return a SORTBY statement. - + :param sorts: a list of sort term. A sort term is a string designing a variable and optionnaly the sort order ('ASC' or 'DESC'). If the sort order is omitted default to 'ASC' @@ -184,7 +184,7 @@ for attr_name, attr_value in new_descr] return 'SET %s WHERE %s' % (', '.join(new_restrictions), ', '.join(old_restrictions)) - + RQLGENERATOR = RQLGenerator() def _test(): diff --git a/setup.py b/setup.py index 9608f5a83b22dac97d2f6f0a8e7d5fc23e5975c1_c2V0dXAucHk=..cba0eb99537b1dd0afe56fb1be2d60123f394f4b_c2V0dXAucHk= 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # pylint: disable-msg=W0404,W0622,W0704,W0613,E0611,C0103 -"""Generic Setup script, takes package info from __pkginfo__.py file. +"""Generic Setup script, takes package info from __pkginfo__.py file. :copyright: 2003-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved. :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr @@ -45,7 +45,7 @@ BASE_BLACKLIST = ('CVS', 'debian', 'dist', 'build', '__buildlog') IGNORED_EXTENSIONS = ('.pyc', '.pyo', '.elc') - + def ensure_scripts(linux_scripts): """ @@ -140,7 +140,7 @@ ext_modules=ext_modules, **kwargs ) - + if dist.have_run.get('install_lib'): _install = dist.get_command_obj('install_lib') if subpackage_of: @@ -151,7 +151,7 @@ stream = open(product_init, 'w') stream.write(EMPTY_FILE) stream.close() - + # manually install included directories if any if include_dirs: if subpackage_of: @@ -162,6 +162,6 @@ dest = join(_install.install_dir, base, directory) export(directory, dest) return dist - + if __name__ == '__main__' : install() diff --git a/test/unittest_parser.py b/test/unittest_parser.py index 9608f5a83b22dac97d2f6f0a8e7d5fc23e5975c1_dGVzdC91bml0dGVzdF9wYXJzZXIucHk=..cba0eb99537b1dd0afe56fb1be2d60123f394f4b_dGVzdC91bml0dGVzdF9wYXJzZXIucHk= 100644 --- a/test/unittest_parser.py +++ b/test/unittest_parser.py @@ -21,7 +21,7 @@ '(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 - + 'Any X, X/Y FROM (Any X WHERE X is) WHERE X is Person;', # missing AS for subquery ) @@ -77,5 +77,5 @@ "Any X ORDERBY RANDOM();", "Any X ORDERBY F(1, 2);", - + "Any X, COUNT(B) GROUPBY X ORDERBY 1 WHERE B concerns X HAVING COUNT(B) > 2;", @@ -81,5 +81,5 @@ "Any X, COUNT(B) GROUPBY X ORDERBY 1 WHERE B concerns X HAVING COUNT(B) > 2;", - + 'Any X, MAX(COUNT(B)) GROUPBY X WHERE B concerns X;', # syntaxically correct 'Any X WHERE X eid > 12;', @@ -92,7 +92,7 @@ '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));', - + 'Any T2, COUNT(T1)' ' GROUPBY T1' ' ORDERBY 2 DESC, T2;' @@ -119,7 +119,7 @@ if print_errors: print string, ex raise - + def test_precedence_1(self): tree = self.parse("Any X WHERE X firstname 'lulu' AND X name 'toto' OR X name 'tutu';") base = tree.children[0].where @@ -150,7 +150,7 @@ self.assertEqual(isinstance(base, nodes.Or), 1) self.assertEqual(isinstance(base.children[0], nodes.Relation), 1) self.assertEqual(isinstance(base.children[1], nodes.And), 1) - + def test_not_precedence_0(self): tree = self.parse("Any X WHERE NOT X firstname 'lulu', X name 'toto';") self.assertEqual(str(tree), "Any X WHERE NOT X firstname 'lulu', X name 'toto'") @@ -269,6 +269,6 @@ except: raise - + if __name__ == '__main__': unittest_main() diff --git a/undo.py b/undo.py index 9608f5a83b22dac97d2f6f0a8e7d5fc23e5975c1_dW5kby5weQ==..cba0eb99537b1dd0afe56fb1be2d60123f394f4b_dW5kby5weQ== 100644 --- a/undo.py +++ b/undo.py @@ -11,8 +11,8 @@ class SelectionManager(object): """Manage the operation stacks.""" - + def __init__(self, selection): self._selection = selection # The selection tree self.op_list = [] # The operations we'll have to undo self.state_stack = [] # The save_state()'s index stack @@ -15,8 +15,8 @@ def __init__(self, selection): self._selection = selection # The selection tree self.op_list = [] # The operations we'll have to undo self.state_stack = [] # The save_state()'s index stack - + def push_state(self): """defines current state as the new 'start' state""" self.state_stack.append(len(self.op_list)) @@ -20,10 +20,10 @@ def push_state(self): """defines current state as the new 'start' state""" self.state_stack.append(len(self.op_list)) - + def recover(self): """recover to the latest pushed state""" last_state_index = self.state_stack.pop() # if last_index == 0, then there's no intermediate state => undo all ! for i in self.op_list[:-last_state_index] or self.op_list[:]: self.undo() @@ -24,11 +24,11 @@ def recover(self): """recover to the latest pushed state""" last_state_index = self.state_stack.pop() # if last_index == 0, then there's no intermediate state => undo all ! for i in self.op_list[:-last_state_index] or self.op_list[:]: self.undo() - + def add_operation(self, operation): """add an operation to the current ones""" # stores operations in reverse order : self.op_list.insert(0, operation) @@ -31,8 +31,8 @@ def add_operation(self, operation): """add an operation to the current ones""" # stores operations in reverse order : self.op_list.insert(0, operation) - + def undo(self): """undo the latest operation""" assert len(self.op_list) > 0 @@ -50,6 +50,6 @@ def __init__(self, node): self.node = node self.stmt = node.stmt - + def __str__(self): """undo the operation on the selection""" @@ -54,5 +54,5 @@ def __str__(self): """undo the operation on the selection""" - return "%s %s" % (self.__class__.__name__, self.node) + return "%s %s" % (self.__class__.__name__, self.node) # Undo for variable manipulation operations ################################## @@ -57,6 +57,6 @@ # Undo for variable manipulation operations ################################## - + class MakeVarOperation(NodeOperation): """Defines how to undo make_variable().""" @@ -120,7 +120,7 @@ class RemoveNodeOperation(NodeOperation): """Defines how to undo remove_node().""" - + def __init__(self, node): NodeOperation.__init__(self, node) self.node_parent = node.parent @@ -137,7 +137,7 @@ assert self.node_parent is self.gd_parent.where else: self.parent_index = self.gd_parent.children.index(self.node_parent) - + def undo(self, selection): """undo the operation on the selection""" if self.binary_remove: @@ -162,10 +162,10 @@ # register reference from the removed node for varref in self.node.iget_nodes(VariableRef): varref.register_reference() - + class AddSortOperation(NodeOperation): """Defines how to undo 'add sort'.""" def undo(self, selection): """undo the operation on the selection""" self.stmt.remove_sort_term(self.node) @@ -166,10 +166,10 @@ class AddSortOperation(NodeOperation): """Defines how to undo 'add sort'.""" def undo(self, selection): """undo the operation on the selection""" self.stmt.remove_sort_term(self.node) - + class RemoveSortOperation(NodeOperation): """Defines how to undo 'remove sort'.""" def __init__(self, node): @@ -179,6 +179,6 @@ def undo(self, selection): """undo the operation on the selection""" self.stmt.add_sort_term(self.node, self.index) - + class AddGroupOperation(NodeOperation): """Defines how to undo 'add group'.""" @@ -183,6 +183,6 @@ class AddGroupOperation(NodeOperation): """Defines how to undo 'add group'.""" - + def undo(self, selection): """undo the operation on the selection""" self.stmt.remove_group_var(self.node) @@ -186,6 +186,6 @@ def undo(self, selection): """undo the operation on the selection""" self.stmt.remove_group_var(self.node) - + class RemoveGroupOperation(NodeOperation): """Defines how to undo 'remove group'.""" @@ -190,6 +190,6 @@ class RemoveGroupOperation(NodeOperation): """Defines how to undo 'remove group'.""" - + def __init__(self, node): NodeOperation.__init__(self, node) self.index = self.stmt.groupby.index(self.node) @@ -193,7 +193,7 @@ def __init__(self, node): NodeOperation.__init__(self, node) self.index = self.stmt.groupby.index(self.node) - + def undo(self, selection): """undo the operation on the selection""" self.stmt.add_group_var(self.node, self.index) @@ -207,10 +207,10 @@ class SetDistinctOperation(ChangeValueOperation): """Defines how to undo 'set_distinct'.""" - + def undo(self, selection): """undo the operation on the selection""" self.node.distinct = self.value class SetOffsetOperation(ChangeValueOperation): """Defines how to undo 'set_offset'.""" @@ -211,13 +211,13 @@ def undo(self, selection): """undo the operation on the selection""" self.node.distinct = self.value class SetOffsetOperation(ChangeValueOperation): """Defines how to undo 'set_offset'.""" - + def undo(self, selection): """undo the operation on the selection""" self.node.offset = self.value class SetLimitOperation(ChangeValueOperation): """Defines how to undo 'set_limit'.""" @@ -218,10 +218,10 @@ def undo(self, selection): """undo the operation on the selection""" self.node.offset = self.value class SetLimitOperation(ChangeValueOperation): """Defines how to undo 'set_limit'.""" - + def undo(self, selection): """undo the operation on the selection""" self.node.limit = self.value @@ -231,7 +231,7 @@ def __init__(self, rel, previous_value): self.rel = rel self.value = previous_value - + def undo(self, selection): """undo the operation on the selection""" self.rel.optional = self.value @@ -248,7 +248,7 @@ """undo the operation on the union's children""" self.select.parent = self.union self.union.children.remove(self.select) - + class RemoveSelectOperation(AppendSelectOperation): """Defines how to undo append_select().""" def __init__(self, union, select, origindex): @@ -261,6 +261,6 @@ __all__ = ('SelectionManager', 'MakeVarOperation', 'UndefineVarOperation', 'SelectVarOperation', 'UnselectVarOperation', 'AddNodeOperation', - 'ReplaceNodeOperation', 'RemoveNodeOperation', + 'ReplaceNodeOperation', 'RemoveNodeOperation', 'AddSortOperation', 'AddGroupOperation', 'SetOptionalOperation', 'SetDistinctOperation')