<s> from __future__ import absolute_import <EOL> import six <EOL> import re <EOL> from collections import namedtuple <EOL> SCALAR_TYPES = tuple ( list ( six . string_types ) + [ int , float , bool ] ) <EOL> ECMA_TO_PYTHON_FLAGS = { <EOL> '<STR_LIT:i>' : re . I , <EOL> '<STR_LIT:m>' : re . M , <EOL> } <EOL> PYTHON_TO_ECMA_FLAGS = dict ( <EOL> ( value , key ) for key , value in ECMA_TO_PYTHON_FLAGS . items ( ) <EOL> ) <EOL> PythonRegex = namedtuple ( '<STR_LIT>' , [ '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> def _normalize_string_type ( value ) : <EOL> if isinstance ( value , six . string_types ) : <EOL> return six . text_type ( value ) <EOL> else : <EOL> return value <EOL> def _compare_dicts ( one , two ) : <EOL> if len ( one ) != len ( two ) : <EOL> return False <EOL> for key , value in one . items ( ) : <EOL> if key not in one or key not in two : <EOL> return False <EOL> if not compare_schemas ( one [ key ] , two [ key ] ) : <EOL> return False <EOL> return True <EOL> def _compare_lists ( one , two ) : <EOL> if len ( one ) != len ( two ) : <EOL> return False <EOL> they_match = False <EOL> for first_item in one : <EOL> for second_item in two : <EOL> if they_match : <EOL> continue <EOL> they_match = compare_schemas ( first_item , second_item ) <EOL> return they_match <EOL> def _assert_same_types ( one , two ) : <EOL> if not isinstance ( one , type ( two ) ) or not isinstance ( two , type ( one ) ) : <EOL> raise RuntimeError ( '<STR_LIT>' . format ( <EOL> type1 = type ( one ) . __name__ , type2 = type ( two ) . __name__ ) ) <EOL> def compare_schemas ( one , two ) : <EOL> """<STR_LIT>""" <EOL> one = _normalize_string_type ( one ) <EOL> two = _normalize_string_type ( two ) <EOL> _assert_same_types ( one , two ) <EOL> if isinstance ( one , list ) : <EOL> return _compare_lists ( one , two ) <EOL> elif isinstance ( one , dict ) : <EOL> return _compare_dicts ( one , two ) <EOL> elif isinstance ( one , SCALAR_TYPES ) : <EOL> return one == two <EOL> else : <EOL> raise RuntimeError ( '<STR_LIT>' . format ( <EOL> type = type ( one ) . __name__ ) ) <EOL> def is_ecma_regex ( regex ) : <EOL> """<STR_LIT>""" <EOL> parts = regex . split ( '<STR_LIT:/>' ) <EOL> if len ( parts ) == <NUM_LIT:1> : <EOL> return False <EOL> if len ( parts ) < <NUM_LIT:3> : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> parts . pop ( ) <EOL> parts . append ( '<STR_LIT>' ) <EOL> raw_regex = '<STR_LIT:/>' . join ( parts ) <EOL> if raw_regex . startswith ( '<STR_LIT:/>' ) and raw_regex . endswith ( '<STR_LIT:/>' ) : <EOL> return True <EOL> return False <EOL> def convert_ecma_regex_to_python ( value ) : <EOL> """<STR_LIT>""" <EOL> if not is_ecma_regex ( value ) : <EOL> return PythonRegex ( value , [ ] ) <EOL> parts = value . split ( '<STR_LIT:/>' ) <EOL> flags = parts . pop ( ) <EOL> try : <EOL> result_flags = [ ECMA_TO_PYTHON_FLAGS [ f ] for f in flags ] <EOL> except KeyError : <EOL> raise ValueError ( '<STR_LIT>' . format ( flags ) ) <EOL> return PythonRegex ( '<STR_LIT:/>' . join ( parts [ <NUM_LIT:1> : ] ) , result_flags ) <EOL> def convert_python_regex_to_ecma ( value , flags = [ ] ) : <EOL> """<STR_LIT>""" <EOL> if is_ecma_regex ( value ) : <EOL> return value <EOL> result_flags = [ PYTHON_TO_ECMA_FLAGS [ f ] for f in flags ] <EOL> result_flags = '<STR_LIT>' . join ( result_flags ) <EOL> return '<STR_LIT>' . format ( value = value , flags = result_flags ) </s>
