def test_mixed_quote_types_unsafe(): """Test that a multiline, mixed-quotes expression is transformed.""" # expected = '''f"one is {one} and two is {two}"''' out, count = process.fstringify_code_by_line(s_in_mixed_quotes_unsafe) assert out == s_in_mixed_quotes_unsafe
def test_equiv_expressions_hex(): a = 17 # noqa: F841 s_in = """'%.3x' % a""" out, count = process.fstringify_code_by_line(s_in) assert eval(out) == eval(s_in)
def test_unknown_mod_percend_dictionary(): """Unknown modifier must not result in partial conversion!""" s_in = """\"%(a)-6d %(a)s" % d""" out, count = process.fstringify_code_by_line(s_in) assert out == s_in
def test_str_in_str_single_quote(): s_in = """a = 'beautiful numbers to follow: {}'.format(" ".join(lst))""" s_expected = """a = f"beautiful numbers to follow: {' '.join(lst)}\"""" s_out, count = process.fstringify_code_by_line(s_in) assert count == 1 assert s_out == s_expected
def test_chain_fmt(): s_in = """a = "Hello {}".format(d["a{}".format(key)])""" s_expected = """a = f"Hello {d[f'a{key}']}\"""" s_out, count = process.fstringify_code_by_line(s_in) assert count == 1 assert s_out == s_expected
def test_openpyxl(): s_in = """sheet['B{}'.format(i) : 'E{}'.format(i)]""" s_expected = """sheet[f'B{i}' : f'E{i}']""" s_out, count = process.fstringify_code_by_line(s_in) assert count == 2 assert s_out == s_expected
def test_double_percent_2(): s_in = """print("p = %.3f%%" % (100 * p))""" s_expected = """print(f"p = {100 * p:.3f}%")""" s_out, count = process.fstringify_code_by_line(s_in) assert count == 1 assert s_out == s_expected
def test_invalid_conversion_names(): s_in = """a = 'my string {var}, but also {f!b} and {cada_bra!a}'.format(var, f, cada_bra)""" s_expected = s_in s_out, count = process.fstringify_code_by_line(s_in) assert s_out == s_expected
def test_equiv_expressions_repr(): name = 'bla' s_in = """'Setting %20r must be uppercase.' % name""" out, count = process.fstringify_code_by_line(s_in) assert eval(out) == eval(s_in)
def test_equiv_expressions_s(): name = "bla" # noqa: F841 s_in = """'Setting %20s must be uppercase.' % name""" out, count = process.fstringify_code_by_line(s_in) assert eval(out) == eval(s_in)
def test_multiline_tuple(): s_in = """s = '%s' % ( v['key'])""" expected = """s = f"{v['key']}\"""" out, count = process.fstringify_code_by_line(s_in) assert out == expected
def test_percent_newline(): s_in = """a = '%s\\n' % var""" s_expected = """a = f'{var}\\n'""" s_out, count = process.fstringify_code_by_line(s_in) print(s_out) print(s_expected) assert s_out == s_expected
def test_str_in_str_methods(): s_in = r"""string += '{} = {}\n'.format(('.').join(listKeys), json.JSONEncoder().encode(val))""" s_out = ( """string += f"{'.'.join(listKeys)} = {json.JSONEncoder().encode(val)}\\n\"""" ) out, count = process.fstringify_code_by_line(s_in) assert out == s_out assert count > 0
def test_super_call(): """Regression for https://github.com/ikamensh/flynt/issues/103 - """ s_in = '"{}/{}".format(super(SuggestEndpoint, self).path, self.facet.suggest)' expected = 'f"{super(SuggestEndpoint, self).path}/{self.facet.suggest}"' out, count = process.fstringify_code_by_line(s_in) assert count == 1 assert out == expected
def try_on_file(filename: str, multiline): """ Given a file name (something.py) find this file in test/integration/samples_in, run flint_str on its content, write result to test/integration/actual_out/something.py, and compare the result with test/integration/expected_out/something.py""" txt_in = read_in(filename) out, edits = fstringify_code_by_line(txt_in, multiline=multiline) write_output_file(filename, out) return out, read_expected(filename)
def fstringify_file(filename, multiline, len_limit, pyup=False) -> Tuple[bool, int, int, int]: """ :return: tuple: (changes_made, n_changes, length of original code, length of new code) """ try: with open(filename, encoding='utf-8') as f: contents = f.read() new_code, changes = fstringify_code_by_line(contents, multiline=multiline, len_limit=len_limit) except Exception as e: print(f"Skipping fstrings transform of file {filename} due to {e}") traceback.print_exc() result = False, 0, len(contents), len(contents) else: if new_code == contents: result = False, 0, len(contents), len(contents) else: with open(filename, "w", encoding="utf-8") as f: f.write(new_code) result = True, changes, len(contents), len(new_code) if not pyup: return result else: class Args: def __init__(self, **kwargs): self.__dict__.update(kwargs) args = Args(py36_plus=True, py3_plus=True, keep_percent_format=False, exit_zero_even_if_changed=False) with spy_on_file_io(): changed = pyupgrade.fix_file(filename, args) if changed: len_before, len_after = charcount_stats(filename) return True, result[1], result[2], len_after else: return result
def test_noqa(): s_in = """a = 'my string {}, but also {} and {}'.format(var, f, cada_bra) # noqa: flynt""" s_expected = """a = 'my string {}, but also {} and {}'.format(var, f, cada_bra) # noqa: flynt""" s_out, count = process.fstringify_code_by_line(s_in) assert s_out == s_expected
def test_one_string(): s_in = """a = 'my string {}, but also {} and {}'.format(var, f, cada_bra)""" s_expected = """a = f'my string {var}, but also {f} and {cada_bra}'""" s_out, count = process.fstringify_code_by_line(s_in) assert s_out == s_expected
def test_nonatomic(): s_in = """'blah{0}'.format(thing - 1)""" s_expected = """f'blah{thing - 1}'""" s_out, count = process.fstringify_code_by_line(s_in) assert s_out == s_expected
def test_percent_tuple(): s_in = """print("%s %s " % (var+var, abc))""" s_expected = """print(f"{var + var} {abc} ")""" s_out, count = process.fstringify_code_by_line(s_in) assert s_out == s_expected
def test_part_of_concat(): s_in = """print('blah{}'.format(thing) + 'blah' + otherThing + "is %f" % x)""" s_expected = """print(f'blah{thing}' + 'blah' + otherThing + f"is {x:f}")""" s_out, count = process.fstringify_code_by_line(s_in) assert s_out == s_expected
def test_str_in_str_curly(): s_in = """desired_info += ["'clusters_options' items: {}. ".format({'random_option'})]""" out, count = process.fstringify_code_by_line(s_in) assert count == 0
def test_string_in_string_single(): s_in = """print('getlivejpg: %s: %s' % (camera['name'], errmsg))""" s_expected = """print(f"getlivejpg: {camera['name']}: {errmsg}")""" s_out, count = process.fstringify_code_by_line(s_in) assert s_out == s_expected
def test_width_spec(aggressive): s_in = "{'r': '%03f' % row_idx}" s_expected = """{'r': f'{row_idx:03f}'}""" assert process.fstringify_code_by_line(s_in)[0] == s_expected
def test_decimal_precision(): s_in = """e = '%.03f' % var""" s_expected = """e = f'{var:.03f}'""" out, count = process.fstringify_code_by_line(s_in) assert out == s_expected
def test_kv_loop(): s_in = """', '.join('{}={}'.format(k, v) for k, v in d)""" expected = """', '.join(f'{k}={v}' for k, v in d)""" out, count = process.fstringify_code_by_line(s_in) assert out == expected
def test_string_specific_len(aggressive): s_in = """'%5s' % CLASS_NAMES[labels[j]]""" s_expected = """f'{CLASS_NAMES[labels[j]]:5}'""" s_out, count = process.fstringify_code_by_line(s_in) assert s_out == s_expected
def test_call(): s_in = """'%s' % fn(var)""" s_expected = """f'{fn(var)}'""" s_out, count = process.fstringify_code_by_line(s_in) assert s_out == s_expected
def test_floats_precision_equiv(number, fmt_spec): percent_fmt_string = f"""'Setting %{fmt_spec} must be uppercase.' % number""" out, count = process.fstringify_code_by_line(percent_fmt_string) assert eval(out) == eval(percent_fmt_string)
def test_integers_equivalence(number, fmt_spec): percent_fmt_string = f"""'Setting %{fmt_spec} must be uppercase.' % number""" out, count = process.fstringify_code_by_line(percent_fmt_string) assert eval(out) == eval(percent_fmt_string)