src/black/output.py
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | """Nice output for Black.
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | The double calls are for patching purposes in tests.
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | """
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | import json
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | import re
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | import tempfile
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | from typing import Any, List, Optional
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | from click import echo, style
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | from mypy_extensions import mypyc_attr
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | @mypyc_attr(patchable=True)
0007 0007 0007 0000 0000 0000 0000 -- 03 002 004 002 004 006 006 0015.51 0015.51 0001.00 | def _out(message: Optional[str] = None, nl: bool = True, **styles: Any) -> None:
0007 0007 0007 0000 0000 0000 0000 -- 03 002 004 002 004 006 006 0015.51 0015.51 0001.00 | if message is not None:
0007 0007 0007 0000 0000 0000 0000 -- 03 002 004 002 004 006 006 0015.51 0015.51 0001.00 | if "bold" not in styles:
0007 0007 0007 0000 0000 0000 0000 -- 03 002 004 002 004 006 006 0015.51 0015.51 0001.00 | styles["bold"] = True
0007 0007 0007 0000 0000 0000 0000 -- 03 002 004 002 004 006 006 0015.51 0015.51 0001.00 | message = style(message, **styles)
0007 0007 0007 0000 0000 0000 0000 -- 03 002 004 002 004 006 006 0015.51 0015.51 0001.00 | echo(message, nl=nl, err=True)
0007 0007 0007 0000 0000 0000 0000 -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | @mypyc_attr(patchable=True)
0007 0007 0007 0000 0000 0000 0000 -- 03 002 004 002 004 006 006 0015.51 0015.51 0001.00 | def _err(message: Optional[str] = None, nl: bool = True, **styles: Any) -> None:
0007 0007 0007 0000 0000 0000 0000 -- 03 002 004 002 004 006 006 0015.51 0015.51 0001.00 | if message is not None:
0007 0007 0007 0000 0000 0000 0000 -- 03 002 004 002 004 006 006 0015.51 0015.51 0001.00 | if "fg" not in styles:
0007 0007 0007 0000 0000 0000 0000 -- 03 002 004 002 004 006 006 0015.51 0015.51 0001.00 | styles["fg"] = "red"
0007 0007 0007 0000 0000 0000 0000 -- 03 002 004 002 004 006 006 0015.51 0015.51 0001.00 | message = style(message, **styles)
0007 0007 0007 0000 0000 0000 0000 -- 03 002 004 002 004 006 006 0015.51 0015.51 0001.00 | echo(message, nl=nl, err=True)
0007 0007 0007 0000 0000 0000 0000 -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | @mypyc_attr(patchable=True)
0003 0003 0003 0000 0000 0000 0000 -- 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | def out(message: Optional[str] = None, nl: bool = True, **styles: Any) -> None:
0003 0003 0003 0000 0000 0000 0000 -- 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | _out(message, nl=nl, **styles)
0003 0003 0003 0000 0000 0000 0000 -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0002 0002 0002 0000 0000 0000 0000 -- 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | def err(message: Optional[str] = None, nl: bool = True, **styles: Any) -> None:
0002 0002 0002 0000 0000 0000 0000 -- 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | _err(message, nl=nl, **styles)
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0015 0006 0014 0000 0000 0000 0001 -- 03 002 005 003 006 007 009 0025.27 0030.32 0001.20 | def ipynb_diff(a: str, b: str, a_name: str, b_name: str) -> str:
0015 0006 0014 0000 0000 0000 0001 -- 03 002 005 003 006 007 009 0025.27 0030.32 0001.20 | """Return a unified diff string between each cell in notebooks `a` and `b`."""
0015 0006 0014 0000 0000 0000 0001 -- 03 002 005 003 006 007 009 0025.27 0030.32 0001.20 | a_nb = json.loads(a)
0015 0006 0014 0000 0000 0000 0001 -- 03 002 005 003 006 007 009 0025.27 0030.32 0001.20 | b_nb = json.loads(b)
0015 0006 0014 0000 0000 0000 0001 -- 03 002 005 003 006 007 009 0025.27 0030.32 0001.20 | diff_lines = [
0015 0006 0014 0000 0000 0000 0001 -- 03 002 005 003 006 007 009 0025.27 0030.32 0001.20 | diff(
0015 0006 0014 0000 0000 0000 0001 -- 03 002 005 003 006 007 009 0025.27 0030.32 0001.20 | "".join(a_nb["cells"][cell_number]["source"]) + "\n",
0015 0006 0014 0000 0000 0000 0001 -- 03 002 005 003 006 007 009 0025.27 0030.32 0001.20 | "".join(b_nb["cells"][cell_number]["source"]) + "\n",
0015 0006 0014 0000 0000 0000 0001 -- 03 002 005 003 006 007 009 0025.27 0030.32 0001.20 | f"{a_name}:cell_{cell_number}",
0015 0006 0014 0000 0000 0000 0001 -- 03 002 005 003 006 007 009 0025.27 0030.32 0001.20 | f"{b_name}:cell_{cell_number}",
0015 0006 0014 0000 0000 0000 0001 -- 03 002 005 003 006 007 009 0025.27 0030.32 0001.20 | )
0015 0006 0014 0000 0000 0000 0001 -- 03 002 005 003 006 007 009 0025.27 0030.32 0001.20 | for cell_number, cell in enumerate(a_nb["cells"])
0015 0006 0014 0000 0000 0000 0001 -- 03 002 005 003 006 007 009 0025.27 0030.32 0001.20 | if cell["cell_type"] == "code"
0015 0006 0014 0000 0000 0000 0001 -- 03 002 005 003 006 007 009 0025.27 0030.32 0001.20 | ]
0015 0006 0014 0000 0000 0000 0001 -- 03 002 005 003 006 007 009 0025.27 0030.32 0001.20 | return "".join(diff_lines)
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | _line_pattern = re.compile(r"(.*?(?:\r\n|\n|\r|$))")
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0011 0006 0005 0000 0004 0002 0000 -- 03 002 003 003 004 005 007 0016.25 0021.67 0001.33 | def _splitlines_no_ff(source: str) -> List[str]:
0011 0006 0005 0000 0004 0002 0000 -- 03 002 003 003 004 005 007 0016.25 0021.67 0001.33 | """Split a string into lines ignoring form feed and other chars.
0011 0006 0005 0000 0004 0002 0000 -- 03 002 003 003 004 005 007 0016.25 0021.67 0001.33 |
0011 0006 0005 0000 0004 0002 0000 -- 03 002 003 003 004 005 007 0016.25 0021.67 0001.33 | This mimics how the Python parser splits source code.
0011 0006 0005 0000 0004 0002 0000 -- 03 002 003 003 004 005 007 0016.25 0021.67 0001.33 |
0011 0006 0005 0000 0004 0002 0000 -- 03 002 003 003 004 005 007 0016.25 0021.67 0001.33 | A simplified version of the function with the same name in Lib/ast.py
0011 0006 0005 0000 0004 0002 0000 -- 03 002 003 003 004 005 007 0016.25 0021.67 0001.33 | """
0011 0006 0005 0000 0004 0002 0000 -- 03 002 003 003 004 005 007 0016.25 0021.67 0001.33 | result = [match[0] for match in _line_pattern.finditer(source)]
0011 0006 0005 0000 0004 0002 0000 -- 03 002 003 003 004 005 007 0016.25 0021.67 0001.33 | if result[-1] == "":
0011 0006 0005 0000 0004 0002 0000 -- 03 002 003 003 004 005 007 0016.25 0021.67 0001.33 | result.pop(-1)
0011 0006 0005 0000 0004 0002 0000 -- 03 002 003 003 004 005 007 0016.25 0021.67 0001.33 | return result
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0019 0013 0014 0003 0000 0001 0004 -- 03 003 004 003 005 007 008 0022.46 0042.11 0001.88 | def diff(a: str, b: str, a_name: str, b_name: str) -> str:
0019 0013 0014 0003 0000 0001 0004 -- 03 003 004 003 005 007 008 0022.46 0042.11 0001.88 | """Return a unified diff string between strings `a` and `b`."""
0019 0013 0014 0003 0000 0001 0004 -- 03 003 004 003 005 007 008 0022.46 0042.11 0001.88 | import difflib
0019 0013 0014 0003 0000 0001 0004 -- 03 003 004 003 005 007 008 0022.46 0042.11 0001.88 |
0019 0013 0014 0003 0000 0001 0004 -- 03 003 004 003 005 007 008 0022.46 0042.11 0001.88 | a_lines = _splitlines_no_ff(a)
0019 0013 0014 0003 0000 0001 0004 -- 03 003 004 003 005 007 008 0022.46 0042.11 0001.88 | b_lines = _splitlines_no_ff(b)
0019 0013 0014 0003 0000 0001 0004 -- 03 003 004 003 005 007 008 0022.46 0042.11 0001.88 | diff_lines = []
0019 0013 0014 0003 0000 0001 0004 -- 03 003 004 003 005 007 008 0022.46 0042.11 0001.88 | for line in difflib.unified_diff(
0019 0013 0014 0003 0000 0001 0004 -- 03 003 004 003 005 007 008 0022.46 0042.11 0001.88 | a_lines, b_lines, fromfile=a_name, tofile=b_name, n=5
0019 0013 0014 0003 0000 0001 0004 -- 03 003 004 003 005 007 008 0022.46 0042.11 0001.88 | ):
0019 0013 0014 0003 0000 0001 0004 -- 03 003 004 003 005 007 008 0022.46 0042.11 0001.88 | # Work around https://bugs.python.org/issue2142
0019 0013 0014 0003 0000 0001 0004 -- 03 003 004 003 005 007 008 0022.46 0042.11 0001.88 | # See:
0019 0013 0014 0003 0000 0001 0004 -- 03 003 004 003 005 007 008 0022.46 0042.11 0001.88 | # https://www.gnu.org/software/diffutils/manual/html_node/Incomplete-Lines.html
0019 0013 0014 0003 0000 0001 0004 -- 03 003 004 003 005 007 008 0022.46 0042.11 0001.88 | if line[-1] == "\n":
0019 0013 0014 0003 0000 0001 0004 -- 03 003 004 003 005 007 008 0022.46 0042.11 0001.88 | diff_lines.append(line)
0019 0013 0014 0003 0000 0001 0004 -- 03 003 004 003 005 007 008 0022.46 0042.11 0001.88 | else:
0019 0013 0014 0003 0000 0001 0004 -- 03 003 004 003 005 007 008 0022.46 0042.11 0001.88 | diff_lines.append(line + "\n")
0019 0013 0014 0003 0000 0001 0004 -- 03 003 004 003 005 007 008 0022.46 0042.11 0001.88 | diff_lines.append("\\ No newline at end of file\n")
0019 0013 0014 0003 0000 0001 0004 -- 03 003 004 003 005 007 008 0022.46 0042.11 0001.88 | return "".join(diff_lines)
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0014 0014 0013 0004 0000 0000 0001 -- 07 002 012 009 018 014 027 0102.80 0154.20 0001.50 | def color_diff(contents: str) -> str:
0014 0014 0013 0004 0000 0000 0001 -- 07 002 012 009 018 014 027 0102.80 0154.20 0001.50 | """Inject the ANSI color codes to the diff."""
0014 0014 0013 0004 0000 0000 0001 -- 07 002 012 009 018 014 027 0102.80 0154.20 0001.50 | lines = contents.split("\n")
0014 0014 0013 0004 0000 0000 0001 -- 07 002 012 009 018 014 027 0102.80 0154.20 0001.50 | for i, line in enumerate(lines):
0014 0014 0013 0004 0000 0000 0001 -- 07 002 012 009 018 014 027 0102.80 0154.20 0001.50 | if line.startswith("+++") or line.startswith("---"):
0014 0014 0013 0004 0000 0000 0001 -- 07 002 012 009 018 014 027 0102.80 0154.20 0001.50 | line = "\033[1m" + line + "\033[0m" # bold, reset
0014 0014 0013 0004 0000 0000 0001 -- 07 002 012 009 018 014 027 0102.80 0154.20 0001.50 | elif line.startswith("@@"):
0014 0014 0013 0004 0000 0000 0001 -- 07 002 012 009 018 014 027 0102.80 0154.20 0001.50 | line = "\033[36m" + line + "\033[0m" # cyan, reset
0014 0014 0013 0004 0000 0000 0001 -- 07 002 012 009 018 014 027 0102.80 0154.20 0001.50 | elif line.startswith("+"):
0014 0014 0013 0004 0000 0000 0001 -- 07 002 012 009 018 014 027 0102.80 0154.20 0001.50 | line = "\033[32m" + line + "\033[0m" # green, reset
0014 0014 0013 0004 0000 0000 0001 -- 07 002 012 009 018 014 027 0102.80 0154.20 0001.50 | elif line.startswith("-"):
0014 0014 0013 0004 0000 0000 0001 -- 07 002 012 009 018 014 027 0102.80 0154.20 0001.50 | line = "\033[31m" + line + "\033[0m" # red, reset
0014 0014 0013 0004 0000 0000 0001 -- 07 002 012 009 018 014 027 0102.80 0154.20 0001.50 | lines[i] = line
0014 0014 0013 0004 0000 0000 0001 -- 07 002 012 009 018 014 027 0102.80 0154.20 0001.50 | return "\n".join(lines)
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | @mypyc_attr(patchable=True)
0011 0009 0010 0000 0000 0000 0001 -- 05 003 006 003 006 009 009 0028.53 0042.79 0001.50 | def dump_to_file(*output: str, ensure_final_newline: bool = True) -> str:
0011 0009 0010 0000 0000 0000 0001 -- 05 003 006 003 006 009 009 0028.53 0042.79 0001.50 | """Dump `output` to a temporary file. Return path to the file."""
0011 0009 0010 0000 0000 0000 0001 -- 05 003 006 003 006 009 009 0028.53 0042.79 0001.50 | with tempfile.NamedTemporaryFile(
0011 0009 0010 0000 0000 0000 0001 -- 05 003 006 003 006 009 009 0028.53 0042.79 0001.50 | mode="w", prefix="blk_", suffix=".log", delete=False, encoding="utf8"
0011 0009 0010 0000 0000 0000 0001 -- 05 003 006 003 006 009 009 0028.53 0042.79 0001.50 | ) as f:
0011 0009 0010 0000 0000 0000 0001 -- 05 003 006 003 006 009 009 0028.53 0042.79 0001.50 | for lines in output:
0011 0009 0010 0000 0000 0000 0001 -- 05 003 006 003 006 009 009 0028.53 0042.79 0001.50 | f.write(lines)
0011 0009 0010 0000 0000 0000 0001 -- 05 003 006 003 006 009 009 0028.53 0042.79 0001.50 | if ensure_final_newline and lines and lines[-1] != "\n":
0011 0009 0010 0000 0000 0000 0001 -- 05 003 006 003 006 009 009 0028.53 0042.79 0001.50 | f.write("\n")
0011 0009 0010 0000 0000 0000 0001 -- 05 003 006 003 006 009 009 0028.53 0042.79 0001.50 | return f.name