<s> import re <EOL> class UnsupportedExpression ( Exception ) : <EOL> def __init__ ( self , expression ) : <EOL> self . expression = expression <EOL> def __unicode__ ( self ) : <EOL> return u'<STR_LIT>' + self . expression <EOL> class BadExpression ( Exception ) : <EOL> def __init__ ( self , expression ) : <EOL> self . expression = expression <EOL> def __unicode__ ( self ) : <EOL> return u'<STR_LIT>' + self . expression <EOL> class BadVariable ( Exception ) : <EOL> def __init__ ( self , variable ) : <EOL> self . variable = variable <EOL> def __unicode__ ( self ) : <EOL> return u'<STR_LIT>' + self . variable <EOL> class URITemplate ( object ) : <EOL> alpha = '<STR_LIT>' <EOL> digit = '<STR_LIT>' <EOL> hexdigit = '<STR_LIT>' <EOL> genDelims = '<STR_LIT>' <EOL> subDelims = "<STR_LIT>" <EOL> varstart = alpha + digit + '<STR_LIT:_>' <EOL> varchar = varstart + '<STR_LIT:.>' <EOL> unreserved = alpha + digit + '<STR_LIT>' <EOL> reserved = genDelims + subDelims <EOL> def __init__ ( self , template ) : <EOL> self . template = template <EOL> self . parts = [ ] <EOL> parts = re . split ( r'<STR_LIT>' , self . template ) <EOL> for part in parts : <EOL> if ( part ) : <EOL> if ( ( '<STR_LIT:{>' == part [ <NUM_LIT:0> ] ) and ( '<STR_LIT:}>' == part [ - <NUM_LIT:1> ] ) ) : <EOL> expression = part [ <NUM_LIT:1> : - <NUM_LIT:1> ] <EOL> if ( re . match ( '<STR_LIT>' , expression ) ) : <EOL> self . parts . append ( SimpleExpansion ( expression ) ) <EOL> elif ( '<STR_LIT:+>' == part [ <NUM_LIT:1> ] ) : <EOL> self . parts . append ( ReservedExpansion ( expression ) ) <EOL> elif ( '<STR_LIT:#>' == part [ <NUM_LIT:1> ] ) : <EOL> self . parts . append ( FragmentExpansion ( expression ) ) <EOL> elif ( '<STR_LIT:.>' == part [ <NUM_LIT:1> ] ) : <EOL> self . parts . append ( LabelExpansion ( expression ) ) <EOL> elif ( '<STR_LIT:/>' == part [ <NUM_LIT:1> ] ) : <EOL> self . parts . append ( PathExpansion ( expression ) ) <EOL> elif ( '<STR_LIT:;>' == part [ <NUM_LIT:1> ] ) : <EOL> self . parts . append ( PathStyleExpansion ( expression ) ) <EOL> elif ( '<STR_LIT:?>' == part [ <NUM_LIT:1> ] ) : <EOL> self . parts . append ( FormStyleQueryExpansion ( expression ) ) <EOL> elif ( '<STR_LIT:&>' == part [ <NUM_LIT:1> ] ) : <EOL> self . parts . append ( FormStyleQueryContinuation ( expression ) ) <EOL> elif ( part [ <NUM_LIT:1> ] in '<STR_LIT>' ) : <EOL> raise UnsupportedExpression ( part ) <EOL> else : <EOL> raise BadExpression ( part ) <EOL> else : <EOL> if ( ( '<STR_LIT:{>' not in part ) and ( '<STR_LIT:}>' not in part ) ) : <EOL> self . parts . append ( Literal ( part ) ) <EOL> else : <EOL> raise BadExpression ( part ) <EOL> @ property <EOL> def variables ( self ) : <EOL> vars = set ( ) <EOL> for part in self . parts : <EOL> vars . update ( part . variables ) <EOL> return vars <EOL> def expand ( self , ** kwargs ) : <EOL> expanded = [ part . expand ( kwargs ) for part in self . parts ] <EOL> return '<STR_LIT>' . join ( [ expandedPart for expandedPart in expanded if ( expandedPart is not None ) ] ) <EOL> def __str__ ( self ) : <EOL> return self . template . encode ( '<STR_LIT:ascii>' , '<STR_LIT:replace>' ) <EOL> def __unicode__ ( self ) : <EOL> return unicode ( self . template ) <EOL> class Variable ( object ) : <EOL> def __init__ ( self , name ) : <EOL> self . name = '<STR_LIT>' <EOL> self . maxLength = None <EOL> self . explode = False <EOL> self . array = False <EOL> if ( name [ <NUM_LIT:0> : <NUM_LIT:1> ] not in URITemplate . varstart ) : <EOL> raise BadVariable ( name ) <EOL> if ( '<STR_LIT::>' in name ) : <EOL> name , maxLength = name . split ( '<STR_LIT::>' , <NUM_LIT:1> ) <EOL> if ( ( <NUM_LIT:0> < len ( maxLength ) ) and ( len ( maxLength ) < <NUM_LIT:4> ) ) : <EOL> for digit in maxLength : <EOL> if ( digit not in URITemplate . digit ) : <EOL> raise BadVariable ( name + '<STR_LIT::>' + maxLength ) <EOL> self . maxLength = int ( maxLength ) <EOL> if ( not self . maxLength ) : <EOL> raise BadVariable ( name + '<STR_LIT::>' + maxLength ) <EOL> else : <EOL> raise BadVariable ( name + '<STR_LIT::>' + maxLength ) <EOL> elif ( '<STR_LIT:*>' == name [ - <NUM_LIT:1> ] ) : <EOL> name = name [ : - <NUM_LIT:1> ] <EOL> self . explode = True <EOL> elif ( '<STR_LIT>' == name [ - <NUM_LIT:2> : ] ) : <EOL> name = name [ : - <NUM_LIT:2> ] <EOL> self . array = True <EOL> self . explode = True <EOL> index = <NUM_LIT:0> <EOL> while ( index < len ( name ) ) : <EOL> codepoint = name [ index ] <EOL> if ( ( '<STR_LIT:%>' == codepoint ) and <EOL> ( ( index + <NUM_LIT:2> ) < len ( name ) ) and <EOL> ( name [ index + <NUM_LIT:1> ] in URITemplate . hexdigit ) and <EOL> ( name [ index + <NUM_LIT:2> ] in URITemplate . hexdigit ) ) : <EOL> self . name += name [ index : index + <NUM_LIT:3> ] <EOL> index += <NUM_LIT:2> <EOL> elif ( codepoint in URITemplate . varchar ) : <EOL> self . name += codepoint <EOL> else : <EOL> raise BadVariable ( name + ( ( '<STR_LIT::>' + self . maxLength ) if ( self . maxLength ) else '<STR_LIT>' ) + ( '<STR_LIT>' if ( self . array ) else ( '<STR_LIT:*>' if ( self . explode ) else '<STR_LIT>' ) ) ) <EOL> index += <NUM_LIT:1> <EOL> class Expression ( object ) : <EOL> def __init__ ( self ) : <EOL> pass <EOL> @ property <EOL> def variables ( self ) : <EOL> return [ ] <EOL> def _encode ( self , value , legal , pctEncoded ) : <EOL> output = '<STR_LIT>' <EOL> index = <NUM_LIT:0> <EOL> while ( index < len ( value ) ) : <EOL> codepoint = value [ index ] <EOL> if ( codepoint in legal ) : <EOL> output += codepoint <EOL> elif ( pctEncoded and ( '<STR_LIT:%>' == codepoint ) and <EOL> ( ( index + <NUM_LIT:2> ) < len ( value ) ) and <EOL> ( value [ index + <NUM_LIT:1> ] in URITemplate . hexdigit ) and <EOL> ( value [ index + <NUM_LIT:2> ] in URITemplate . hexdigit ) ) : <EOL> output += value [ index : index + <NUM_LIT:3> ] <EOL> index += <NUM_LIT:2> <EOL> else : <EOL> utf8 = codepoint . encode ( '<STR_LIT:utf8>' ) <EOL> for byte in utf8 : <EOL> output += '<STR_LIT:%>' + URITemplate . hexdigit [ ord ( byte ) / <NUM_LIT:16> ] + URITemplate . hexdigit [ ord ( byte ) % <NUM_LIT:16> ] <EOL> index += <NUM_LIT:1> <EOL> return output <EOL> def _uriEncodeValue ( self , value ) : <EOL> return self . _encode ( value , URITemplate . unreserved , False ) <EOL> def _uriEncodeName ( self , name ) : <EOL> return self . _encode ( unicode ( name ) , URITemplate . unreserved + URITemplate . reserved , True ) if ( name ) else '<STR_LIT>' <EOL> def _join ( self , prefix , joiner , value ) : <EOL> if ( prefix ) : <EOL> return prefix + joiner + value <EOL> return value <EOL> def _encodeStr ( self , variable , name , value , prefix , joiner , first ) : <EOL> if ( first and variable . maxLength ) : <EOL> return self . _join ( prefix , joiner , self . _uriEncodeValue ( value [ : variable . maxLength ] ) ) <EOL> return self . _join ( prefix , joiner , self . _uriEncodeValue ( value ) ) <EOL> def _encodeDictItem ( self , variable , name , key , item , delim , prefix , joiner , first ) : <EOL> joiner = '<STR_LIT:=>' if ( variable . explode ) else '<STR_LIT:U+002C>' <EOL> if ( variable . array ) : <EOL> prefix = ( prefix + '<STR_LIT:[>' + self . _uriEncodeName ( key ) + '<STR_LIT:]>' ) if ( prefix and not first ) else self . _uriEncodeName ( key ) <EOL> else : <EOL> prefix = self . _join ( prefix , '<STR_LIT:.>' , self . _uriEncodeName ( key ) ) <EOL> return self . _encodeVar ( variable , key , item , delim , prefix , joiner , False ) <EOL> def _encodeListItem ( self , variable , name , index , item , delim , prefix , joiner , first ) : <EOL> if ( variable . array ) : <EOL> prefix = prefix + '<STR_LIT:[>' + unicode ( index ) + '<STR_LIT:]>' if ( prefix ) else '<STR_LIT>' <EOL> return self . _encodeVar ( variable , None , item , delim , prefix , joiner , False ) <EOL> return self . _encodeVar ( variable , name , item , delim , prefix , '<STR_LIT:.>' , False ) <EOL> def _encodeVar ( self , variable , name , value , delim = '<STR_LIT:U+002C>' , prefix = '<STR_LIT>' , joiner = '<STR_LIT:=>' , first = True ) : <EOL> if ( isinstance ( value , basestring ) ) : <EOL> return self . _encodeStr ( variable , name , value , prefix , joiner , first ) <EOL> elif ( hasattr ( value , '<STR_LIT>' ) and hasattr ( value , '<STR_LIT>' ) ) : <EOL> if ( len ( value ) ) : <EOL> encodedItems = [ self . _encodeDictItem ( variable , name , key , value [ key ] , delim , prefix , joiner , first ) for key in value . keys ( ) ] <EOL> return delim . join ( [ item for item in encodedItems if ( item is not None ) ] ) <EOL> return None <EOL> elif ( hasattr ( value , '<STR_LIT>' ) ) : <EOL> if ( len ( value ) ) : <EOL> encodedItems = [ self . _encodeListItem ( variable , name , index , item , delim , prefix , joiner , first ) for index , item in enumerate ( value ) ] <EOL> return delim . join ( [ item for item in encodedItems if ( item is not None ) ] ) <EOL> return None <EOL> else : <EOL> return self . _encodeStr ( variable , name , unicode ( value ) . lower ( ) , prefix , joiner , first ) <EOL> def expand ( self , values ) : <EOL> return None <EOL> class Literal ( Expression ) : <EOL> def __init__ ( self , value ) : <EOL> Expression . __init__ ( self ) <EOL> self . value = value <EOL> def expand ( self , values ) : <EOL> return self . _encode ( self . value , ( URITemplate . unreserved + URITemplate . reserved ) , True ) <EOL> class Expansion ( Expression ) : <EOL> operator = '<STR_LIT>' <EOL> varJoiner = '<STR_LIT:U+002C>' <EOL> def __init__ ( self , variables ) : <EOL> Expression . __init__ ( self ) <EOL> self . vars = [ Variable ( var ) for var in variables . split ( '<STR_LIT:U+002C>' ) ] <EOL> @ property <EOL> def variables ( self ) : <EOL> return [ var . name for var in self . vars ] <EOL> def _expandVar ( self , variable , value ) : <EOL> return self . _encodeVar ( variable , self . _uriEncodeName ( variable . name ) , value ) <EOL> def expand ( self , values ) : <EOL> expandedVars = [ ] <EOL> for var in self . vars : <EOL> if ( ( var . name in values ) and ( values [ var . name ] is not None ) ) : <EOL> expandedVar = self . _expandVar ( var , values [ var . name ] ) <EOL> if ( expandedVar is not None ) : <EOL> expandedVars . append ( expandedVar ) <EOL> if ( len ( expandedVars ) ) : <EOL> expanded = self . varJoiner . join ( expandedVars ) <EOL> if ( expanded is not None ) : <EOL> return self . operator + expanded <EOL> return None <EOL> class SimpleExpansion ( Expansion ) : <EOL> def __init__ ( self , variables ) : <EOL> Expansion . __init__ ( self , variables ) <EOL> class ReservedExpansion ( Expansion ) : <EOL> def __init__ ( self , variables ) : <EOL> Expansion . __init__ ( self , variables [ <NUM_LIT:1> : ] ) <EOL> def _uriEncodeValue ( self , value ) : <EOL> return self . _encode ( value , ( URITemplate . unreserved + URITemplate . reserved ) , True ) <EOL> class FragmentExpansion ( ReservedExpansion ) : <EOL> operator = '<STR_LIT:#>' <EOL> def __init__ ( self , variables ) : <EOL> ReservedExpansion . __init__ ( self , variables ) <EOL> class LabelExpansion ( Expansion ) : <EOL> operator = '<STR_LIT:.>' <EOL> varJoiner = '<STR_LIT:.>' <EOL> def __init__ ( self , variables ) : <EOL> Expansion . __init__ ( self , variables [ <NUM_LIT:1> : ] ) <EOL> def _expandVar ( self , variable , value ) : <EOL> return self . _encodeVar ( variable , self . _uriEncodeName ( variable . name ) , value , delim = ( '<STR_LIT:.>' if variable . explode else '<STR_LIT:U+002C>' ) ) <EOL> class PathExpansion ( Expansion ) : <EOL> operator = '<STR_LIT:/>' <EOL> varJoiner = '<STR_LIT:/>' <EOL> def __init__ ( self , variables ) : <EOL> Expansion . __init__ ( self , variables [ <NUM_LIT:1> : ] ) <EOL> def _expandVar ( self , variable , value ) : <EOL> return self . _encodeVar ( variable , self . _uriEncodeName ( variable . name ) , value , delim = ( '<STR_LIT:/>' if variable . explode else '<STR_LIT:U+002C>' ) ) <EOL> class PathStyleExpansion ( Expansion ) : <EOL> operator = '<STR_LIT:;>' <EOL> varJoiner = '<STR_LIT:;>' <EOL> def __init__ ( self , variables ) : <EOL> Expansion . __init__ ( self , variables [ <NUM_LIT:1> : ] ) <EOL> def _encodeStr ( self , variable , name , value , prefix , joiner , first ) : <EOL> if ( variable . array ) : <EOL> if ( name ) : <EOL> prefix = prefix + '<STR_LIT:[>' + name + '<STR_LIT:]>' if ( prefix ) else name <EOL> elif ( variable . explode ) : <EOL> prefix = self . _join ( prefix , '<STR_LIT:.>' , name ) <EOL> return Expansion . _encodeStr ( self , variable , name , value , prefix , joiner , first ) <EOL> def _encodeDictItem ( self , variable , name , key , item , delim , prefix , joiner , first ) : <EOL> if ( variable . array ) : <EOL> if ( name ) : <EOL> prefix = prefix + '<STR_LIT:[>' + name + '<STR_LIT:]>' if ( prefix ) else name <EOL> prefix = ( prefix + '<STR_LIT:[>' + self . _uriEncodeName ( key ) + '<STR_LIT:]>' ) if ( prefix and not first ) else self . _uriEncodeName ( key ) <EOL> elif ( variable . explode ) : <EOL> prefix = self . _join ( prefix , '<STR_LIT:.>' , name ) if ( not first ) else '<STR_LIT>' <EOL> else : <EOL> prefix = self . _join ( prefix , '<STR_LIT:.>' , self . _uriEncodeName ( key ) ) <EOL> joiner = '<STR_LIT:U+002C>' <EOL> return self . _encodeVar ( variable , self . _uriEncodeName ( key ) if ( not variable . array ) else '<STR_LIT>' , item , delim , prefix , joiner , False ) <EOL> def _encodeListItem ( self , variable , name , index , item , delim , prefix , joiner , first ) : <EOL> if ( variable . array ) : <EOL> if ( name ) : <EOL> prefix = prefix + '<STR_LIT:[>' + name + '<STR_LIT:]>' if ( prefix ) else name <EOL> return self . _encodeVar ( variable , unicode ( index ) , item , delim , prefix , joiner , False ) <EOL> return self . _encodeVar ( variable , name , item , delim , prefix , '<STR_LIT:=>' if ( variable . explode ) else '<STR_LIT:.>' , False ) <EOL> def _expandVar ( self , variable , value ) : <EOL> if ( variable . explode ) : <EOL> return self . _encodeVar ( variable , self . _uriEncodeName ( variable . name ) , value , delim = '<STR_LIT:;>' ) <EOL> value = self . _encodeVar ( variable , self . _uriEncodeName ( variable . name ) , value , delim = '<STR_LIT:U+002C>' ) <EOL> return ( self . _uriEncodeName ( variable . name ) + '<STR_LIT:=>' + value ) if ( value ) else variable . name <EOL> class FormStyleQueryExpansion ( PathStyleExpansion ) : <EOL> operator = '<STR_LIT:?>' <EOL> varJoiner = '<STR_LIT:&>' <EOL> def __init__ ( self , variables ) : <EOL> PathStyleExpansion . __init__ ( self , variables ) <EOL> def _expandVar ( self , variable , value ) : <EOL> if ( variable . explode ) : <EOL> return self . _encodeVar ( variable , self . _uriEncodeName ( variable . name ) , value , delim = '<STR_LIT:&>' ) <EOL> value = self . _encodeVar ( variable , self . _uriEncodeName ( variable . name ) , value , delim = '<STR_LIT:U+002C>' ) <EOL> return ( self . _uriEncodeName ( variable . name ) + '<STR_LIT:=>' + value ) if ( value is not None ) else None <EOL> class FormStyleQueryContinuation ( FormStyleQueryExpansion ) : <EOL> operator = '<STR_LIT:&>' <EOL> def __init__ ( self , variables ) : <EOL> FormStyleQueryExpansion . __init__ ( self , variables ) </s>
