def _fix_eval_field_params(self): """Replace f-string field ID placeholders with the actual field expressions.""" for node in ast.walk(self.res): if not ( isinstance(node, ast.Call) and node.func.value.id == "__xonsh__" and node.func.attr == "eval_fstring_field" and len(node.args) > 0 ): continue if PYTHON_VERSION_INFO > (3, 8): if isinstance(node.args[0], ast.Constant) and isinstance( node.args[0].value, int ): field = self.fields.pop(node.args[0].value, None) if field is None: continue lineno = node.args[0].lineno col_offset = node.args[0].col_offset field_node = ast.Tuple( elts=[ ast.Constant( value=field[0], lineno=lineno, col_offset=col_offset ), ast.Constant( value=field[1], lineno=lineno, col_offset=col_offset ), ], ctx=ast.Load(), lineno=lineno, col_offset=col_offset, ) node.args[0] = field_node elif isinstance(node.args[0], ast.Num): field = self.fields.pop(node.args[0].n, None) if field is None: continue lineno = node.args[0].lineno col_offset = node.args[0].col_offset elts = [ast.Str(s=field[0], lineno=lineno, col_offset=col_offset)] if field[1] is not None: elts.append( ast.Str(s=field[1], lineno=lineno, col_offset=col_offset) ) else: elts.append( ast.NameConstant( value=None, lineno=lineno, col_offset=col_offset ) ) field_node = ast.Tuple( elts=elts, ctx=ast.Load(), lineno=lineno, col_offset=col_offset, ) node.args[0] = field_node
def _unpatch_strings(self): """Reverts false-positive field matches within strings.""" reparse = False for node in ast.walk(self.res): if isinstance(node, ast.Constant) and isinstance(node.value, str): value = node.value elif isinstance(node, ast.Str): value = node.s else: continue match = RE_FSTR_FIELD_WRAPPER.search(value) if match is None: continue field = self.fields.pop(int(match.group(2)), None) if field is None: continue self.repl = self.repl.replace(match.group(1), field[0], 1) reparse = True if reparse: self.res = pyparse(self.repl).body[0].value
def _unpatch_selfdoc_strings(self): """Reverts false-positive matches within Python 3.8 sef-documenting f-string expressions.""" for node in ast.walk(self.res): if isinstance(node, ast.Constant) and isinstance(node.value, str): value = node.value elif isinstance(node, ast.Str): value = node.s else: continue match = RE_FSTR_SELF_DOC_FIELD_WRAPPER.search(value) if match is None: continue field = self.fields.get(int(match.group(2)), None) if field is None: continue value = value.replace(match.group(1), field[0], 1) if isinstance(node, ast.Str): node.s = value else: node.value = value