<s> import sys , weakref <EOL> from whoosh import query <EOL> from whoosh . qparser . common import get_single_text , QueryParserError , attach <EOL> class SyntaxNode ( object ) : <EOL> """<STR_LIT>""" <EOL> has_fieldname = False <EOL> has_text = False <EOL> has_boost = False <EOL> _parent = None <EOL> def __repr__ ( self ) : <EOL> r = "<STR_LIT:<>" <EOL> if self . has_fieldname : <EOL> r += "<STR_LIT>" % self . fieldname <EOL> r += self . r ( ) <EOL> if self . has_boost and self . boost != <NUM_LIT:1.0> : <EOL> r += "<STR_LIT>" % self . boost <EOL> r += "<STR_LIT:>>" <EOL> return r <EOL> def r ( self ) : <EOL> """<STR_LIT>""" <EOL> return "<STR_LIT>" % ( self . __class__ . __name__ , self . __dict__ ) <EOL> def apply ( self , fn ) : <EOL> return self <EOL> def accept ( self , fn ) : <EOL> def fn_wrapper ( n ) : <EOL> return fn ( n . apply ( fn_wrapper ) ) <EOL> return fn_wrapper ( self ) <EOL> def query ( self , parser ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( self . __class__ . __name__ ) <EOL> def is_ws ( self ) : <EOL> """<STR_LIT>""" <EOL> return False <EOL> def set_fieldname ( self , name , override = False ) : <EOL> """<STR_LIT>""" <EOL> if not self . has_fieldname : <EOL> return <EOL> if self . fieldname is None or override : <EOL> self . fieldname = name <EOL> return self <EOL> def set_boost ( self , boost ) : <EOL> """<STR_LIT>""" <EOL> if not self . has_boost : <EOL> return <EOL> self . boost = boost <EOL> return self <EOL> def set_range ( self , startchar , endchar ) : <EOL> """<STR_LIT>""" <EOL> self . startchar = startchar <EOL> self . endchar = endchar <EOL> return self <EOL> def parent ( self ) : <EOL> if self . _parent : <EOL> return self . _parent ( ) <EOL> def next_sibling ( self ) : <EOL> p = self . parent ( ) <EOL> if p : <EOL> return p . node_after ( self ) <EOL> def prev_sibling ( self ) : <EOL> p = self . parent ( ) <EOL> if p : <EOL> return p . node_before ( self ) <EOL> def bake ( self , parent ) : <EOL> self . _parent = weakref . ref ( parent ) <EOL> class MarkerNode ( SyntaxNode ) : <EOL> """<STR_LIT>""" <EOL> def r ( self ) : <EOL> return self . __class__ . __name__ <EOL> class Whitespace ( MarkerNode ) : <EOL> """<STR_LIT>""" <EOL> def r ( self ) : <EOL> return "<STR_LIT:U+0020>" <EOL> def is_ws ( self ) : <EOL> return True <EOL> class FieldnameNode ( SyntaxNode ) : <EOL> """<STR_LIT>""" <EOL> has_fieldname = True <EOL> def __init__ ( self , fieldname , original ) : <EOL> self . fieldname = fieldname <EOL> self . original = original <EOL> def __repr__ ( self ) : <EOL> return "<STR_LIT>" % self . fieldname <EOL> class GroupNode ( SyntaxNode ) : <EOL> """<STR_LIT>""" <EOL> has_boost = True <EOL> merging = True <EOL> qclass = None <EOL> def __init__ ( self , nodes = None , boost = <NUM_LIT:1.0> , ** kwargs ) : <EOL> self . nodes = nodes or [ ] <EOL> self . boost = boost <EOL> self . kwargs = kwargs <EOL> def r ( self ) : <EOL> return "<STR_LIT>" % ( self . __class__ . __name__ , <EOL> "<STR_LIT:U+002CU+0020>" . join ( repr ( n ) for n in self . nodes ) ) <EOL> @ property <EOL> def startchar ( self ) : <EOL> if not self . nodes : <EOL> return None <EOL> return self . nodes [ <NUM_LIT:0> ] . startchar <EOL> @ property <EOL> def endchar ( self ) : <EOL> if not self . nodes : <EOL> return None <EOL> return self . nodes [ - <NUM_LIT:1> ] . endchar <EOL> def apply ( self , fn ) : <EOL> return self . __class__ ( self . type , [ fn ( node ) for node in self . nodes ] , <EOL> boost = self . boost , ** self . kwargs ) <EOL> def query ( self , parser ) : <EOL> subs = [ ] <EOL> for node in self . nodes : <EOL> subq = node . query ( parser ) <EOL> if subq is not None : <EOL> subs . append ( subq ) <EOL> q = self . qclass ( subs , boost = self . boost , ** self . kwargs ) <EOL> return attach ( q , self ) <EOL> def empty_copy ( self ) : <EOL> """<STR_LIT>""" <EOL> c = self . __class__ ( ** self . kwargs ) <EOL> if self . has_boost : <EOL> c . boost = self . boost <EOL> if self . has_fieldname : <EOL> c . fieldname = self . fieldname <EOL> if self . has_text : <EOL> c . text = self . text <EOL> return c <EOL> def set_fieldname ( self , name , override = False ) : <EOL> SyntaxNode . set_fieldname ( self , name , override = override ) <EOL> for node in self . nodes : <EOL> node . set_fieldname ( name , override = override ) <EOL> def set_range ( self , startchar , endchar ) : <EOL> for node in self . nodes : <EOL> node . set_range ( startchar , endchar ) <EOL> return self <EOL> def __nonzero__ ( self ) : <EOL> return bool ( self . nodes ) <EOL> __bool__ = __nonzero__ <EOL> def __iter__ ( self ) : <EOL> return iter ( self . nodes ) <EOL> def __len__ ( self ) : <EOL> return len ( self . nodes ) <EOL> def __getitem__ ( self , n ) : <EOL> return self . nodes . __getitem__ ( n ) <EOL> def __setitem__ ( self , n , v ) : <EOL> self . nodes . __setitem__ ( n , v ) <EOL> def __delitem__ ( self , n ) : <EOL> self . nodes . __delitem__ ( n ) <EOL> def insert ( self , n , v ) : <EOL> self . nodes . insert ( n , v ) <EOL> def append ( self , v ) : <EOL> self . nodes . append ( v ) <EOL> def extend ( self , vs ) : <EOL> self . nodes . extend ( vs ) <EOL> def pop ( self ) : <EOL> return self . nodes . pop ( ) <EOL> def reverse ( self ) : <EOL> self . nodes . reverse ( ) <EOL> def index ( self , v ) : <EOL> return self . nodes . index ( v ) <EOL> def bake ( self , parent ) : <EOL> SyntaxNode . bake ( self , parent ) <EOL> for node in self . nodes : <EOL> node . bake ( self ) <EOL> def node_before ( self , n ) : <EOL> try : <EOL> i = self . nodes . index ( n ) <EOL> except ValueError : <EOL> return <EOL> if i > <NUM_LIT:0> : <EOL> return self . nodes [ i - <NUM_LIT:1> ] <EOL> def node_after ( self , n ) : <EOL> try : <EOL> i = self . nodes . index ( n ) <EOL> except ValueError : <EOL> return <EOL> if i < len ( self . nodes ) - <NUM_LIT:2> : <EOL> return self . nodes [ i + <NUM_LIT:1> ] <EOL> class BinaryGroup ( GroupNode ) : <EOL> """<STR_LIT>""" <EOL> merging = False <EOL> has_boost = False <EOL> def query ( self , parser ) : <EOL> assert len ( self . nodes ) == <NUM_LIT:2> <EOL> q = self . qclass ( self . nodes [ <NUM_LIT:0> ] . query ( parser ) , <EOL> self . nodes [ <NUM_LIT:1> ] . query ( parser ) ) <EOL> return attach ( q , self ) <EOL> class Wrapper ( GroupNode ) : <EOL> """<STR_LIT>""" <EOL> merging = False <EOL> def query ( self , parser ) : <EOL> return attach ( self . qclass ( self . nodes [ <NUM_LIT:0> ] . query ( parser ) ) , self ) <EOL> class ErrorNode ( SyntaxNode ) : <EOL> def __init__ ( self , message , node = None ) : <EOL> self . message = message <EOL> self . node = node <EOL> def r ( self ) : <EOL> return "<STR_LIT>" % ( self . node , self . message ) <EOL> @ property <EOL> def startchar ( self ) : <EOL> return self . node . startchar <EOL> @ property <EOL> def endchar ( self ) : <EOL> return self . node . endchar <EOL> def query ( self , parser ) : <EOL> if self . node : <EOL> q = self . node . query ( parser ) <EOL> else : <EOL> q = query . NullQuery <EOL> return attach ( query . error_query ( self . message , q ) , self ) <EOL> class AndGroup ( GroupNode ) : <EOL> qclass = query . And <EOL> class OrGroup ( GroupNode ) : <EOL> qclass = query . Or <EOL> class DisMaxGroup ( GroupNode ) : <EOL> qclass = query . DisjunctionMax <EOL> class OrderedGroup ( GroupNode ) : <EOL> qclass = query . Ordered <EOL> class AndNotGroup ( BinaryGroup ) : <EOL> qclass = query . AndNot <EOL> class AndMaybeGroup ( BinaryGroup ) : <EOL> qclass = query . AndMaybe <EOL> class RequireGroup ( BinaryGroup ) : <EOL> qclass = query . Require <EOL> class NotGroup ( Wrapper ) : <EOL> qclass = query . Not <EOL> class RangeNode ( SyntaxNode ) : <EOL> """<STR_LIT>""" <EOL> has_fieldname = True <EOL> def __init__ ( self , start , end , startexcl , endexcl ) : <EOL> self . start = start <EOL> self . end = end <EOL> self . startexcl = startexcl <EOL> self . endexcl = endexcl <EOL> self . boost = <NUM_LIT:1.0> <EOL> self . fieldname = None <EOL> self . kwargs = { } <EOL> def r ( self ) : <EOL> b1 = "<STR_LIT:{>" if self . startexcl else "<STR_LIT:[>" <EOL> b2 = "<STR_LIT:}>" if self . endexcl else "<STR_LIT:]>" <EOL> return "<STR_LIT>" % ( b1 , self . start , self . end , b2 ) <EOL> def query ( self , parser ) : <EOL> fieldname = self . fieldname or parser . fieldname <EOL> start = self . start <EOL> end = self . end <EOL> if parser . schema and fieldname in parser . schema : <EOL> field = parser . schema [ fieldname ] <EOL> if field . self_parsing ( ) : <EOL> try : <EOL> q = field . parse_range ( fieldname , start , end , <EOL> self . startexcl , self . endexcl , <EOL> boost = self . boost ) <EOL> if q is not None : <EOL> return attach ( q , self ) <EOL> except QueryParserError : <EOL> e = sys . exc_info ( ) [ <NUM_LIT:1> ] <EOL> return attach ( query . error_query ( e ) , self ) <EOL> if start : <EOL> start = get_single_text ( field , start , tokenize = False , <EOL> removestops = False ) <EOL> if end : <EOL> end = get_single_text ( field , end , tokenize = False , <EOL> removestops = False ) <EOL> q = query . TermRange ( fieldname , start , end , self . startexcl , <EOL> self . endexcl , boost = self . boost ) <EOL> return attach ( q , self ) <EOL> class TextNode ( SyntaxNode ) : <EOL> """<STR_LIT>""" <EOL> has_fieldname = True <EOL> has_text = True <EOL> has_boost = True <EOL> qclass = None <EOL> tokenize = False <EOL> removestops = False <EOL> def __init__ ( self , text ) : <EOL> self . fieldname = None <EOL> self . text = text <EOL> self . boost = <NUM_LIT:1.0> <EOL> def r ( self ) : <EOL> return "<STR_LIT>" % ( self . __class__ . __name__ , self . text ) <EOL> def query ( self , parser ) : <EOL> fieldname = self . fieldname or parser . fieldname <EOL> termclass = self . qclass or parser . termclass <EOL> q = parser . term_query ( fieldname , self . text , termclass , <EOL> boost = self . boost , tokenize = self . tokenize , <EOL> removestops = self . removestops ) <EOL> return attach ( q , self ) <EOL> class WordNode ( TextNode ) : <EOL> """<STR_LIT>""" <EOL> tokenize = True <EOL> removestops = True <EOL> def r ( self ) : <EOL> return repr ( self . text ) <EOL> class Operator ( SyntaxNode ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , text , grouptype , leftassoc = True ) : <EOL> """<STR_LIT>""" <EOL> self . text = text <EOL> self . grouptype = grouptype <EOL> self . leftassoc = leftassoc <EOL> def r ( self ) : <EOL> return "<STR_LIT>" % self . text <EOL> def replace_self ( self , parser , group , position ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError <EOL> class PrefixOperator ( Operator ) : <EOL> def replace_self ( self , parser , group , position ) : <EOL> length = len ( group ) <EOL> del group [ position ] <EOL> if position < length - <NUM_LIT:1> : <EOL> group [ position ] = self . grouptype ( [ group [ position ] ] ) <EOL> return position <EOL> class PostfixOperator ( Operator ) : <EOL> def replace_self ( self , parser , group , position ) : <EOL> del group [ position ] <EOL> if position > <NUM_LIT:0> : <EOL> group [ position - <NUM_LIT:1> ] = self . grouptype ( [ group [ position - <NUM_LIT:1> ] ] ) <EOL> return position <EOL> class InfixOperator ( Operator ) : <EOL> def replace_self ( self , parser , group , position ) : <EOL> la = self . leftassoc <EOL> gtype = self . grouptype <EOL> merging = gtype . merging <EOL> if position > <NUM_LIT:0> and position < len ( group ) - <NUM_LIT:1> : <EOL> left = group [ position - <NUM_LIT:1> ] <EOL> right = group [ position + <NUM_LIT:1> ] <EOL> if merging and la and isinstance ( left , gtype ) : <EOL> left . append ( right ) <EOL> del group [ position : position + <NUM_LIT:2> ] <EOL> elif merging and not la and isinstance ( right , gtype ) : <EOL> right . insert ( <NUM_LIT:0> , left ) <EOL> del group [ position - <NUM_LIT:1> : position + <NUM_LIT:1> ] <EOL> return position - <NUM_LIT:1> <EOL> else : <EOL> group [ position - <NUM_LIT:1> : position + <NUM_LIT:2> ] = [ gtype ( [ left , right ] ) ] <EOL> else : <EOL> del group [ position ] <EOL> return position <EOL> def to_word ( n ) : <EOL> node = WordNode ( n . original ) <EOL> node . startchar = n . startchar <EOL> node . endchar = n . endchar <EOL> return node </s>
