(query, func, globals, locals, order_by=False, original_names=False)
| 6033 | query._database._translator_cache[new_key] = new_translator |
| 6034 | return query._clone(_key=new_key, _filters=new_filters, _translator=new_translator) |
| 6035 | def _process_lambda(query, func, globals, locals, order_by=False, original_names=False): |
| 6036 | prev_translator = query._translator |
| 6037 | argnames = () |
| 6038 | if isinstance(func, str): |
| 6039 | func_id = func |
| 6040 | func_ast = string2ast(func) |
| 6041 | if isinstance(func_ast, ast.Lambda): |
| 6042 | argnames = get_lambda_args(func_ast) |
| 6043 | func_ast = func_ast.body |
| 6044 | cells = None |
| 6045 | elif type(func) is types.FunctionType: |
| 6046 | argnames = get_lambda_args(func) |
| 6047 | func_id = id(func.__code__) |
| 6048 | func_ast, external_names, cells = decompile(func) |
| 6049 | elif not order_by: throw(TypeError, |
| 6050 | 'Argument of filter() method must be a lambda function or its text. Got: %r' % func) |
| 6051 | else: assert False # pragma: no cover |
| 6052 | |
| 6053 | if argnames: |
| 6054 | if original_names: |
| 6055 | for name in argnames: |
| 6056 | if name not in prev_translator.namespace: throw(TypeError, |
| 6057 | 'Lambda argument `%s` does not correspond to any variable in original query' % name) |
| 6058 | else: |
| 6059 | expr_type = prev_translator.expr_type |
| 6060 | expr_count = len(expr_type) if type(expr_type) is tuple else 1 |
| 6061 | if len(argnames) != expr_count: |
| 6062 | throw(TypeError, 'Incorrect number of lambda arguments. ' |
| 6063 | 'Expected: %d, got: %d' % (expr_count, len(argnames))) |
| 6064 | else: |
| 6065 | original_names = True |
| 6066 | |
| 6067 | new_filter_num = query._filter_num + 1 |
| 6068 | func_ast, extractors = create_extractors( |
| 6069 | func_id, func_ast, globals, locals, special_functions, const_functions, argnames or prev_translator.namespace) |
| 6070 | if extractors: |
| 6071 | vars, vartypes = extract_vars(func_id, new_filter_num, extractors, globals, locals, cells) |
| 6072 | query._database.provider.normalize_vars(vars, vartypes) |
| 6073 | new_vars = query._vars.copy() |
| 6074 | new_vars.update(vars) |
| 6075 | else: new_vars, vartypes = query._vars, HashableDict() |
| 6076 | tup = (('order_by' if order_by else 'where' if original_names else 'filter', func_id, vartypes),) |
| 6077 | new_key = HashableDict(query._key, filters=query._key['filters'] + tup) |
| 6078 | new_filters = query._filters + (('apply_lambda', func_id, new_filter_num, order_by, func_ast, argnames, original_names, extractors, None, vartypes),) |
| 6079 | |
| 6080 | new_translator, new_vars = query._get_translator(new_key, new_vars) |
| 6081 | if new_translator is None: |
| 6082 | prev_optimized = prev_translator.optimize |
| 6083 | new_translator = prev_translator.apply_lambda(func_id, new_filter_num, order_by, func_ast, argnames, original_names, extractors, new_vars, vartypes) |
| 6084 | if not prev_optimized: |
| 6085 | name_path = new_translator.can_be_optimized() |
| 6086 | if name_path: |
| 6087 | tree_copy = unpickle_ast(prev_translator.pickled_tree) # tree = deepcopy(tree) |
| 6088 | translator_cls = prev_translator.__class__ |
| 6089 | try: |
| 6090 | new_translator = translator_cls( |
| 6091 | tree_copy, None, prev_translator.original_code_key, prev_translator.original_filter_num, |
| 6092 | prev_translator.extractors, None, prev_translator.vartypes.copy(), |
no test coverage detected