Best Python code snippet using Kiwi_python
twsp.py
Source:twsp.py  
1#!/usr/bin/env python32# (C) 2021 gomachssm3import logging4import os5import pathlib6from copy import deepcopy7from uuid import uuid48from functools import lru_cache9from .internal_exceptions import Msg, TwspException, TwspExecuteError, TwspValidateError10from .enums import ParamStyle, CommentType11logger = logging.getLogger(__name__)12NEWLINE_CHAR = '\n'13_TN = 'tmpnm'14_VL = 'value'15_DMY = '...dummy...'16_END = '/*end*/'17_FIND_TARGETS = ('"', "'", '(', '[', '{', '--', '/*', )18_BRACKET_PARE = {'[': ']', '(': ')', '{': '}'}19# ([{'"\ 以å¤ã®ä¸è¬çãªè¨å·ã¨ç©ºç½æå20_EOP_SIMPLE_PARAM = ('!', '#', '$', '%', '&', ')', '-', '=', '^', '~',21                     '|', '@', '`', ';', '+', ':', '*', ']', '}',22                     ',', '/', '<', '>', '?', ' ',     # '.', '(', '_',23                     '\t', '\n', '\r', )24_EOP_END = (_END, )25def parse_file(file_path: str, query_params=None, delete_comment=True, encoding='utf-8', newline='\n',26               paramstyle: ParamStyle = None) -> (str, dict):27    """SQLãã¡ã¤ã«ãèªã¿è¾¼ã¿ãè§£æãè¡ã28    Args:29        file_path (str): å®è¡å¯¾è±¡SQLã®ãã¡ã¤ã«ãã¹(å¿
é )30        query_params (dict): SQLå®è¡æã«å©ç¨ãããã©ã¡ã¼ã¿31        delete_comment (bool): True ã®å ´åãé常ã³ã¡ã³ããåé¤ã False ã®å ´åã¯åé¤ããªã32            ããã©ã«ã㯠True33        encoding (str): 対象ãã¡ã¤ã«ã®æåã³ã¼ã ããã©ã«ã㯠utf-834        newline (str): 対象ãã¡ã¤ã«ã®æ¹è¡ã³ã¼ã (ããã©ã«ã㯠'\n')35        paramstyle (ParamStyle): è§£æå¾ã®SQLãã©ã¡ã¼ã¿æ¸å¼ã決ãããæªæå®æã¯ `NAMED` ã¨åãæ±ã36    Returns:37        tuple(str, dict):38            str: è§£æå¾ã®SQL39            dict: ãã©ã¡ã¼ã¿æ´æ°å¾ã®dict40    """41    try:42        base_sql = _open_file(file_path, encoding=encoding)43        sql, qparams = parse_sql(base_sql, query_params, delete_comment=delete_comment, newline=newline,44                                 paramstyle=paramstyle)45        return sql, qparams46    except TwspException as e:47        logger.error(e.msg_txt)48def parse_sql(base_sql: str, query_params=None, delete_comment=True, newline='\n',49              paramstyle: ParamStyle = None) -> (str, dict):50    """SQLã®è§£æãè¡ã.51    Args :52        base_sql (str): è§£æå¯¾è±¡SQL(å¿
é )53        query_params (dict): SQLå®è¡æã«å©ç¨ãããã©ã¡ã¼ã¿54        delete_comment (bool): True ã®å ´åãé常ã³ã¡ã³ããåé¤ã False ã®å ´åã¯åé¤ããªã (ããã©ã«ã㯠True)55        newline (str): SQLã«å«ã¾ããæ¹è¡ã³ã¼ã (ããã©ã«ã㯠'\n')56        paramstyle (ParamStyle): è§£æå¾ã®SQLãã©ã¡ã¼ã¿æ¸å¼ã決ãããæªæå®æã¯ `NAMED` ã¨åãæ±ã57    Returns:58        tuple(str, dict):59            str: è§£æå¾ã®SQL60            dict: ãã©ã¡ã¼ã¿æ´æ°å¾ã®dict61    """62    global NEWLINE_CHAR63    NEWLINE_CHAR = newline64    pstyle = paramstyle or ParamStyle.NAMED65    _validate_paramstyle(pstyle)66    # PARAMSTYLEã®å¤ã«å¿ãããã©ã¡ã¼ã¿æ¸å¼ã®ã»ãã67    # TODO: ã°ãã¼ãã«ã§ã¯ãªãã弿°ã§æã¡åããããã«ããã68    prmfmt = pstyle.value69    try:70        qparams = deepcopy(query_params) if query_params else {}71        _is_collect_type('base_sql', base_sql, str)72        _is_collect_type('query_params', qparams, dict)73        # base_sql = _format_line_forifend(base_sql)74        sql, _, _ = _parse(base_sql, qparams, delete_comment, prmfmt)75        return sql, qparams76    except TwspException as e:77        logger.error(e)78        # logger.error(e.msg_txt)79def _parse(base_sql: str, qparams: dict, delete_comment: bool, prmfmt: str, eop=None, tmp_params=None,80           after_pcmt=False, ldng_sp_cnt=0) -> (str, int, int):81    """ SQLãè§£æãã¦ãã©ã¡ã¼ã¿ãåãè¾¼ã82    Args:83        base_sql (str): å
ã¨ãªãSQL84        qparams (dict): ãã©ã¡ã¼ã¿85        delete_comment (bool): ã³ã¡ã³ãåé¤ãã©ã°86        eop (tuple->str or None): è§£æçµäºæå End of parse87        tmp_params (dict): forå
ã®ä¸æãã©ã¡ã¼ã¿ default: None88        after_pcmt (bool): ãã©ã¡ã¼ã¿ç´å¾ãã©ã° default: False89        ldng_sp_cnt (int): è¡é ããç¶ãç©ºç½æåã®åæ° default: 090    Returns:91        tuple:92            str: æ§ç¯ããSQL93            int: æå¾ã®æ¹è¡ããé£ç¶ããã¹ãã¼ã¹ã®åæ°94                1以ä¸: ãã®åæ°åã®ã¹ãã¼ã¹ãæ«å°¾ã«åå¨ãã95                0以ä¸: æ«å°¾ã«ã¹ãã¼ã¹ãåå¨ããªã96            int: returnæã®ã¤ã³ããã¯ã¹97    """98    q = []99    max_idx = len(base_sql)100    i = 0101    tmp_params = tmp_params if tmp_params else {}102    while i < max_idx and not _startswith_eop(base_sql, i, eop):103        c, cc, i = _next_chars(base_sql, i, max_idx, eop)104        c, i, del_last_sp = _parse_switch_by_char(base_sql, c, cc, i, qparams, delete_comment, tmp_params, after_pcmt,105                                                  ldng_sp_cnt, prmfmt)106        if del_last_sp:107            q = _delete_last_space(q)108        ldng_sp_cnt = _update_blank_line(ldng_sp_cnt, c)109        q.append(c)110    result = ''.join(q)111    return result, ldng_sp_cnt, i112def _parse_switch_by_char(base_sql: str, c: str, cc: str, i: int, qparams: dict, delete_comment: bool,113                          tmp_params: dict, after_pcmt: bool, ldng_sp_cnt: int, prmfmt: str) -> (str, int, bool):114    del_last_sp = False115    if c in ("'", '"', '(', '[', '{'):116        c, i = _nextstring(c, base_sql, i, qparams, delete_comment, after_pcmt)117    elif cc == '--':118        # è¡ã³ã¡ã³ã -- ã®å ´å119        c, addi = _get_single_line_comment(base_sql[i - 1:], delete_comment)120        i += addi - 1121    elif cc == '/*':122        # è¤æ°è¡ã³ã¡ã³ã /*...*/ ã®å ´å123        c, addi, del_last_sp = _get_multi_line_comment(base_sql[i - 1:], qparams, delete_comment, tmp_params,124                                                       ldng_sp_cnt, prmfmt)125        i += addi - 1126    return c, i, del_last_sp127def _nxtchr(string: str, idx: int):128    return string[idx], idx + 1129def _fnd(string: str, target: str):130    index = string.find(target)131    return index if 0 <= index else len(string)132def _next_chars(string: str, idx: int, mxidx: int, eop=None) -> (str, str, int):133    targets = _FIND_TARGETS + eop if eop else _FIND_TARGETS134    min_idx = min([_fnd(string[idx:], tgt) for tgt in targets])135    if min_idx == 0:136        c, i = _nxtchr(string, idx)137        cc = f'{c}{string[i]}' if i < mxidx else None138    else:139        i = idx + min_idx140        c = string[idx:i]141        cc = c142    return c, cc, i143def _nextstring(c: str, base_sql: str, i: int, qparams: dict, delete_comment: bool, after_pcmt: bool) -> (str, int):144    addi = 0145    if c in ("'", '"'):146        # ' ã " ã®æååã®å ´å147        c, addi = _nextquote(c, base_sql[i:])148    elif after_pcmt and c in ('(', '[', '{'):149        # ãã©ã¡ã¼ã¿ç´å¾ãæ¬å¼§ã®å ´å150        c, addi = _nextbracket(c, base_sql[i:], qparams, delete_comment)151    return c, i + addi152def _nextquote(quote: str, sql_after_quote: str) -> (str, int):153    chars = [quote]154    max_idx = len(sql_after_quote) - 1155    addi = 0156    while addi <= max_idx:157        c, addi = _nxtchr(sql_after_quote, addi)158        if c == quote:159            # 2é£ç¶ã®ã¯ã©ã¼ã以å¤ã®å ´åãæååã¯ããã¾ã§160            if max_idx <= addi or sql_after_quote[addi + 1] != quote:161                chars.append(c)162                break163            chars.append(c)164            c, addi = _nxtchr(sql_after_quote, addi)165        chars.append(c)166    quote_string = ''.join(chars)167    return quote_string, addi168def _nextbracket(openbrkt: str, sql_after_brkt: str, qparams: dict, delete_comment: bool) -> (str, int):169    closingbrkt = _BRACKET_PARE.get(openbrkt)170    chars = [openbrkt]171    max_idx = len(sql_after_brkt) - 1172    addi = 0173    while addi <= max_idx:174        c, addi = _nxtchr(sql_after_brkt, addi)175        chars.append(c)176        if c == closingbrkt:177            break178    bracket_strings = ''.join(chars)179    return bracket_strings, addi180def _get_single_line_comment(sql_comment: str, delete_comment: bool) -> (str, int):181    c, addi = _single_line_comment(sql_comment)182    if delete_comment:183        c = ''184    return c, addi185def _single_line_comment(sql_comment: str) -> (str, int):186    # ãã®é¢æ°ãå¼ã³åºãããæãæååã¯å¿
ã -- ããå§ã¾ã187    maxlen = len(sql_comment)188    new_line_idx = sql_comment.find(NEWLINE_CHAR)189    new_line_idx = maxlen if new_line_idx < 0 else new_line_idx190    comment_string = sql_comment[:new_line_idx]191    return comment_string, new_line_idx192def _get_multi_line_comment(sql_comment: str, qparams: dict, delete_comment: bool, tmp_params: dict,193                            ldng_sp_cnt: int, prmfmt: str) -> (str, int, bool):194    c, addi, is_comment, delete_last_sp = _multi_line_comment(sql_comment, qparams, delete_comment, tmp_params,195                                                              ldng_sp_cnt, prmfmt)196    if is_comment and delete_comment:197        c = ''198    return c, addi, delete_last_sp199def _multi_line_comment(sql_comment: str, qparams: dict, delete_comment: bool, tmp_params: dict,200                        ldng_sp_cnt: int, prmfmt: str) -> (str, int, bool):201    # ãã®é¢æ°ãå¼ã³åºãããæãæååã¯å¿
ã /* ããå§ã¾ã202    cmtype, comment_string = _check_comment_type(sql_comment)203    is_comment = False204    del_last_sp = False205    # ex: comment_string : "/*:parameter*/"206    #     after_comment  : "'hogehoge' from xxx"207    after_comment = sql_comment[len(comment_string):]208    if cmtype is CommentType.PARAM:        # /*:param*/209        comment_string, idx = _parse_param_comment(comment_string, after_comment, qparams, tmp_params, prmfmt)210    elif cmtype is CommentType.DIRECT:     # /*$param*/211        comment_string, idx = _parse_direct_comment(comment_string, after_comment, qparams, tmp_params, prmfmt)212    elif cmtype is CommentType.IFEND:      # /*%if ~*/213        # TODO: ELSE対å¿214        comment_string, idx, del_last_sp = _parse_if_comment(215            comment_string, after_comment, qparams, delete_comment, tmp_params, ldng_sp_cnt, prmfmt)216    elif cmtype is CommentType.FOREND:     # /*%for ~*/217        comment_string, idx, del_last_sp = _parse_for_comment(218            comment_string, after_comment, qparams, delete_comment, tmp_params, ldng_sp_cnt, prmfmt)219    elif cmtype is CommentType.NORMAL:220        is_comment = True221        idx = len(comment_string)222    else:223        raise TwspException(Msg.E0003, sql_comment)224    return comment_string, idx, is_comment, del_last_sp225def _parse_param_comment(comment_string: str, after_comment: str, qparams: dict, tmp_params: dict,226                         prmfmt: str) -> (str, int):227    """228    Args:229        comment_string (str): ã³ã¡ã³ãé¨åã®æåå230            ex: /*:any_parameter*/231        after_comment (str): ã³ã¡ã³ãç´å¾ã®æåå232    Returns:233        tuple:234            str:235            int:236    """237    bind_name, _, load_len = _parse_simple_comment(comment_string, after_comment, qparams, tmp_params, prmfmt)238    return bind_name, load_len239def _parse_direct_comment(comment_string: str, after_comment: str, qparams: dict, tmp_params: dict,240                          prmfmt: str) -> (str, int):241    """242    Args:243        comment_string (str): ã³ã¡ã³ãé¨åã®æåå244            ex: /*$any_parameter*/245        after_comment (str): ã³ã¡ã³ãç´å¾ã®æåå246        qparams (dict): SQLå®è¡æã«å©ç¨ãããã©ã¡ã¼ã¿247    Returns:248        tuple:249            str:250            int:251    """252    merged_params = _merge_qparams(qparams, tmp_params)253    _, value, load_len = _parse_simple_comment(comment_string, after_comment, merged_params, {}, prmfmt)254    return value, load_len255def _parse_simple_comment(comment_string: str, after_comment: str, qparams: dict, tmp_params: dict,256                          prmfmt: str) -> (str, str, int):257    # comment_string: '/*:param*/' or '/*$param*/'258    param_name = comment_string[3:-2]259    bind_name, value = _update_qparams_if_exist_tmp(param_name, qparams, tmp_params, prmfmt)260    dummy_value, _, _ = _parse(after_comment, {}, False, prmfmt, eop=_EOP_SIMPLE_PARAM, after_pcmt=True)261    load_len = len(comment_string) + len(dummy_value)262    return bind_name, value, load_len263def _update_qparams_if_exist_tmp(param: str, qparams: dict, tmp_params: dict, prmfmt: str):264    tmp_name = tmp_params.get(param, {}).get(_TN)265    if _tmpp_is_dummy(tmp_params):266        # tmp_paramsãããã¼ã®å ´å267        updated_bind_name = prmfmt.format(param)268        updated_param_value = ''269    elif tmp_name is not None:270        updated_bind_name = prmfmt.format(tmp_name)271        updated_param_value = tmp_params.get(param, {}).get(_VL)272        qparams[tmp_name] = updated_param_value273    else:274        updated_bind_name = prmfmt.format(param)275        updated_param_value = qparams.get(param)276    return updated_bind_name, f'{updated_param_value}'277def _parse_if_comment(comment_string: str, after_comment: str, qparams: dict, delete_comment: bool,278                      tmp_params: dict, ldng_sp_cnt: int, prmfmt: str) -> (str, int, bool):279    if_strings, after_idx, del_last_sp = _get_str_in_forif(after_comment, qparams, delete_comment, tmp_params,280                                                           ldng_sp_cnt, prmfmt)281    is_true = _execute_if_statement(comment_string[3:-2], qparams, tmp_params)282    output_value = ''.join(if_strings) if is_true else ''283    addi = len(comment_string) + after_idx284    return output_value, addi, del_last_sp285def _parse_for_comment(comment_string: str, after_comment: str, qparams: dict, delete_comment: bool,286                       tmp_params: dict, ldng_sp_cnt: int, prmfmt: str) -> (str, int, bool):287    # comment_string: /*%for x in list_obj*/288    # after_comment: .*/*end*/289    for_strings, after_idx, del_last_sp = [], 0, False290    # æå¾ã®1åã¯for~endã¾ã§ã®æåæ°ã«ã¦ã³ãã®ãããããã¼ã§ç©ºdictãè¿ããã291    for tmp_params in _get_for_variable_names(comment_string, qparams, tmp_params):292        _for_strings, after_idx, del_last_sp = _get_str_in_forif(after_comment, qparams, delete_comment, tmp_params,293                                                                 ldng_sp_cnt, prmfmt)294        for_strings.append(_for_strings)295    # æå¾ã®1ã«ã¼ãåã¯ç¡è¦296    output_value = ''.join(for_strings[:-1])297    addi = len(comment_string) + after_idx298    return output_value, addi, del_last_sp299def _get_for_variable_names(for_comment: str, qparams: dict, tmp_params: dict) -> dict:300    """301    Args:302        for_comment (str): '/*%for x in xxx*/'303        qparams (dict):304        tmp_params (dict):305            ex1: {}306            ex2:307            ex3: {__DMY: True}308    Returns:309    """310    vnames = [v.strip() for v in for_comment[7:-2].split(' in ')[0].split(',')]311    merged_params = _merge_qparams(qparams, tmp_params)312    vnames_str = ",".join(vnames)313    for_statement = f'for {vnames_str} in []' if _tmpp_is_dummy(tmp_params) else for_comment[3:-2]314    try:315        values_list = eval(f'[({vnames_str}) {for_statement}]', {}, merged_params)316    except Exception as e:317        raise TwspExecuteError(Msg.E0008, e, for_statement)318    prefix = str(uuid4()).replace('-', '_')319    for tmp_variable in _enum_temp_variables(vnames, values_list, prefix):320        yield {**tmp_params, **tmp_variable}321    yield {_DMY: True}322    # 夿°åã®ãªã¹ã323    # for a in range(3)ãªã324    # -> {'a': {'tmpnm': 'xxxxxxxxxxxx_0_a', 'value': 0}}325    # -> {'a': {'tmpnm': 'xxxxxxxxxxxx_1_a', 'value': 1}}326    # -> {'a': {'tmpnm': 'xxxxxxxxxxxx_2_a', 'value': 2}}327    # -> {__DMY: True}328    # for a,b,c in zip(['A', 'b'], ['I', 'j'], ['X', 'y'])ãªãã329    # -> {'a': {'tmpnm': 'xxxxxxxxxxxx_0_a', 'value': 'A'},330    #     'b': {'tmpnm': 'xxxxxxxxxxxx_0_b', 'value': 'I'},331    #     'c': {'tmpnm': 'xxxxxxxxxxxx_0_c', 'value': 'X'}}332    # -> {'a': {'tmpnm': 'xxxxxxxxxxxx_1_a', 'value': 'b'},333    #     'b': {'tmpnm': 'xxxxxxxxxxxx_1_b', 'value': 'j'},334    #     'c': {'tmpnm': 'xxxxxxxxxxxx_1_c', 'value': 'y'}}335    # -> {__DMY: True}336def _enum_temp_variables(vnames: list, values_list: list, prefix: str):337    if len(vnames) == 1:338        for vi, values in enumerate(values_list):339            vname = vnames[0]340            tmp_name = _gen_tmp_name(vname, vi, prefix)341            yield {vname: {_TN: tmp_name, _VL: values}}342    else:343        for vi, values in enumerate(values_list):344            tmpdct = {}345            for ni, vname in enumerate(vnames):346                tmp_name = _gen_tmp_name(vname, vi, prefix)347                tmpdct[vname] = {_TN: tmp_name, _VL: values[ni]}348            yield tmpdct349def _gen_tmp_name(vname: str, loop_count: int, prefix: str) -> str:350    name = f'{prefix}_{loop_count}_{vname}'351    return name352def _get_str_in_forif(after_comment: str, qparams: dict, delete_comment: bool, tmp_params: dict,353                      ldng_sp_cnt: int, prmfmt: str) -> (str, int, bool):354    """355    Args:356        after_comment (str): /*%for ~*/ã¾ãã¯/*%if ~*/ã®ç´å¾ã«ç¶ãæåå357        qparams (dict): ãã©ã¡ã¼ã¿358        delete_comment (bool):359        tmp_params (dict):360        ldng_sp_cnt (int):361    Returns:362    """363    # for ~ endãã if ~ end ã«æã¾ããæåãåå¾ãã364    nextq, after_idx, del_last_sp = _nxtq_in_forif(after_comment, ldng_sp_cnt)365    # æ¹è¡å餿¸ã¿ã®å ´åã ldng_sp_cnt 㯠0 ãã366    ldng_sp_cnt = -1 if after_comment == nextq else 0367    output_value, _, vlen = _parse(nextq, qparams, delete_comment, prmfmt, _EOP_END, tmp_params=tmp_params,368                                   ldng_sp_cnt=ldng_sp_cnt)369    nextq = nextq[vlen:]370    after_idx += vlen371    output_value, addi = _end_in_forif(output_value, nextq)372    after_idx += addi373    return output_value, after_idx, del_last_sp374def _nxtq_in_forif(nextq: str, ldng_sp_cnt: int) -> (str, int, bool):375    if 0 <= ldng_sp_cnt:376        nlidx = nextq.find(NEWLINE_CHAR) + 1377        if nextq[:nlidx].strip() == '':378            return nextq[nlidx:], nlidx, True379    return nextq, 0, False380def _end_in_forif(output_value: str, nextq: str) -> (str, int):381    # /*end*/ãè¦ã¤ãããSQLã®æ«å°¾ã«å°éããå ´å382    if not nextq:383        return output_value, 0384    # nextq: '/*end*/\n   order by ~'385    # /*end*/ ã§splitããã®ã¯1åã®ã¿386    target_last_line = output_value.split(NEWLINE_CHAR)[-1]387    next_first_line = nextq.split(NEWLINE_CHAR, 1)[0]388    sp_stripped = f'{target_last_line}{next_first_line}'.strip(' ')389    if sp_stripped == _END:390        # /*end*/ã®è¡ã«å«ã¾ããæåãã¹ãã¼ã¹ã®ã¿ã®å ´åãæ¬¡ã®è¡ããèªã¿è¾¼ã¾ãã391        newline_len = len(NEWLINE_CHAR)392        output_idx = len(output_value) - len(target_last_line)393        forif_string = output_value[:output_idx]394        add_idx = len(next_first_line) + newline_len395        return forif_string, add_idx396    else:397        # /*end*/ã¾ã§ã®æåæ°ãè¿ã len('/*end*/')398        return output_value, 7399def _is_continue(string: str, end_str: str):400    if not string or string.startswith(end_str):401        return False402    return True403def _execute_if_statement(statement: str, qparams: dict, tmp_params: dict) -> bool:404    # statement: "if BOOL_EXPRESSION"405    if _tmpp_is_dummy(tmp_params):406        return True407    try:408        tparams = {}409        for key, value in _tmpp_items(tmp_params):410            tparams[key] = value411        is_true = eval(f'True {statement} else False', {}, {**qparams, **tparams})412    except NameError as e:413        raise TwspExecuteError(Msg.E0005, e, statement)414    if type(is_true) != bool:415        raise TwspExecuteError(Msg.E0006, statement)416    return is_true417def _check_comment_type(sql_after_comment: str) -> (CommentType, str):418    # /*:param*/                    -> :param       å©ç¨ã§ããæåã¯è±æ°åã¨ã¢ã³ãã¼ã¹ã³ã¢419    # /*$param*/                    -> {param}      å©ç¨ã§ããæåã¯è±æ°åã¨ã¢ã³ãã¼ã¹ã³ã¢420    # /*%if a == b*/hoge/*end*/     -> æ¡ä»¶ãTrueã®å ´åã/*end*/ã¾ã§ã«æã¾ããé¨åãåºå421    # /*%for a in b*/and a /*end*/  -> and a and a and a and a ... iterate by b422    # other patterns are multi line comment.423    for ctyp in CommentType:424        matched = ctyp.value.findall(sql_after_comment)425        if len(matched) > 0:426            return ctyp, matched[0]427def __get_cache_maxsize() -> int:428    default_size = 20429    env_size = os.getenv('TWSP_CACHE_SIZE')430    try:431        size = int(env_size)432    except Exception:433        size = None434    return size if size else default_size435@lru_cache(maxsize=__get_cache_maxsize())436def _open_file(file_path, encoding='utf-8'):437    _is_collect_type('file_path', file_path, str)438    if not _is_absolute(file_path):439        raise TwspValidateError(Msg.E0002, file_path)440    with open(file_path, 'r', encoding=encoding) as f:441        return f.read()442def _is_absolute(path):443    p = pathlib.Path(path)444    return p.is_absolute()445def _is_collect_type(argname, value, expected_type):446    if type(value) != expected_type:447        raise TwspValidateError(Msg.E0001, argname, expected_type, type(value))448def _startswith_eop(base_sql: str, i: int, eop: list) -> bool:449    if not eop:450        return False451    for e in eop:452        if base_sql[i:].startswith(f'{e}'):453            return True454    return False455def _update_blank_line(ldng_sp_cnt: int, c: str) -> int:456    if not c:457        return ldng_sp_cnt458    ridx = c.rfind(NEWLINE_CHAR)459    if ldng_sp_cnt < 0 and ridx < 0 == 1:460        return -1461    after_nl = c[ridx + 1:]462    if after_nl.lstrip(' ') == '':463        # æ¹è¡å¾ãå
¨é¨ã¹ãã¼ã¹ã®å ´å464        return len(after_nl)465    else:466        return -1467def _delete_last_space(q: list) -> list:468    idx = len(q) - 1469    while -1 < idx:470        idx_str = q[idx].rstrip(' ')471        if idx_str:472            q[idx] = idx_str473            break474        del q[idx]475        idx -= 1476    return q477# #######################################478# temp_params479# #######################################480def _tmpp_is_dummy(tmpp: dict) -> bool:481    return True if tmpp.get(_DMY) is True else False482def _tmpp_items(tmpp: dict) -> (any, any):483    for key, v in tmpp.items():484        value = v.get(_VL)485        yield key, value486def _merge_qparams(qparams: dict, tmp_params: dict) -> dict:487    if _tmpp_is_dummy(tmp_params):488        return {**qparams}489    merged_params = {**qparams}490    for key, value in _tmpp_items(tmp_params):491        merged_params[key] = value492    return merged_params493def _validate_paramstyle(paramstyle):494    if (not isinstance(paramstyle, ParamStyle)) or paramstyle not in ParamStyle:495        ps = [f'{p.__class__.__name__}.{p.name}' for p in ParamStyle]496        raise TwspValidateError(Msg.E0009, f'{", ".join(ps[:-1])}', ps[-1], paramstyle)...urls.py
Source:urls.py  
1"""2    @author:Mindfire3    @dateCreated:4    url container file  which contaiins all the url variables of blog apps.5"""6from django.conf.urls.defaults import *7from blog.models import *8from django.core.urlresolvers import reverse9from blog import views10urlpatterns = patterns('',11   url(r"^(\d+)/$", views.post, name='post'),12   url(r"^add_comment/(\d+)/$", views.add_comment, name='add_comment'),13   url(r"^delete_comment/(\d+)/$", views.delete_comment, name='delete_comment'),14   url(r"^delete_comment/(\d+)/(\d+)/$", views.delete_comment, name='delete_comment'),15   url(r"^month/(\d+)/(\d+)/$", "month"),16   url(r'^$', views.main, name='main'),...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
