Code Monkey home page Code Monkey logo

black-macchiato's Introduction

black-macchiato

https://circleci.com/gh/wbolster/black-macchiato.svg?style=svg
I see some Python and I want it painted black
Mick Jagger (The Rolling Stones)

What?

This is a small utility built on top of the black Python code formatter to enable formatting of partial files.

Why?

Python code should be black, just like coffee. However, sometimes other people insist on adding milk for unexplicable reasons. Since caffè latte is undrinkable, you eventually settle for caffè macchiato as a compromise.

In other words, you want to use black for the code you write, but for some reason you cannot convert whole files, e.g. when contributing to upstream codebases that are not under your complete control.

However, partial formatting is not supported by black itself, for various good reasons, and it won't be implemented either (134, 142, 245, 370, 511).

This is where black-macchiato enters the stage. This tool is for those who want to do partial formatting anyway. It also accepts indented blocks, which means that you can format an indented method inside a class, or a small block of code.

Note that this tool is a stopgap measure, and you should avoid using it if you can.

How?

To install, use:

pip install black-macchiato

The black-macchiato command reads from standard input, and writes to standard output. Any command line flags are forwarded to black.

Alternatively, you can invoke the module directly through the python executable, which may be preferable depending on your setup. Use python -m macchiato instead of black-macchiato in that case.

Example:

$ echo "    if True: print('hi')" | black-macchiato
    if True:
        print("hi")

Integrating this piping of input and output with your editor is left as an exercise to the reader. For instance, Vim users can use vim-black-macchiato, and Emacs users can use python-black.el.

History

  • 1.3.0 (2020-05-14)
    • Refactor so that wrapping functionality can be reused more easily (7)
    • Use project config file, if any (4, 7)
    • Improved Vim integration (6)
  • 1.2.0 (2020-03-23)
    • Handle else/elif/except/finally and indented functions better (5)
  • 1.1.0 (2019-05-17)
    • Handle lines ending with a colon
    • Add tests
  • 1.0.1 (2019-02-06)
    • Add more metadata
  • 1.0.0 (2019-02-06)
    • Initial release

License

BSD. See LICENSE.rst.

black-macchiato's People

Contributors

alex-lee avatar chmreid avatar janverb avatar smbl64 avatar wbolster avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

black-macchiato's Issues

It seems to fail on Windows

It seems that when tempfile.NamedTemporaryFile open the file it can't be open at the same time by black.

To avoid that problem I have rewritten the format_line method to avoid that problem.

Let me know if you prefer I create a pull request.

def format_lines(lines: List[str], black_args=None) -> List[str]:
    if black_args is None:
        black_args = []

    with tempfile.NamedTemporaryFile(
        suffix=".py", dir=os.getcwd(), mode="wt+", delete=False
    ) as fp:
        # Copy the input.
        fp.writelines(lines)
        fp.flush()

    # Run black.
    if "--quiet" not in black_args:
        black_args.append("--quiet")
    black_args.append(fp.name)

    try:
        exit_code = black.main(args=black_args)
    except SystemExit as exc:
        exit_code = exc.code

    if exit_code == 0:
        # Write output.
        lines = []
        with open(fp.name, mode="rt") as f:
            # fp.seek(0)
            lines = f.readlines()

        os.remove(fp.name)
        return cast(List[str], lines)

    os.remove(fp.name)

    raise RuntimeError("black failed", exit_code)

Best regards,
Vivian.

Do not block reading stdin if the user passes --help

I was wondering if black-macchiato would allow me to specify -S to pass through to black (so it would skip string literal normalization), so naturally I ran black-machiatto --help to see if it accepts options.

Instead black-machiatto blocked reading stdin from the terminal.

It would be great if black-machiatto handled this a little bit better. E.g. it could check whether sys.argv contains -h/--help and then print a short help message telling the user that all command-line arguments will be passed to black.

Multiple of four spaces

Hi,

I'm using black-macchiato to format python code in reStructuredText code chunks. Unfortunately that code is not always indented by a multiple a four spaces and an exception is raised. Would it be possible to allow it? Looking at the code, the multiple four spaces are required to be able to prepend some if True: to have legit code for black. Is there a reason not to dedent that code first and reindent it at the end?

Thanks,

black-macchiato fail if it is asked to format a block of indented comment line

If black-macchiato is asked to comment a block of comment line it fails.

e.g.:

    # First comment line
    # Second comment line

To solve the issue I have changed the _fake_before_lines function as follow:

def _fake_before_lines(first_line: str) -> List[str]:
    """Construct the fake lines that should go before the text."""

    fake_lines = []
    indent_levels = _indent_levels(first_line)

    # Handle regular indent
    for i in range(indent_levels):
        prefix = SINGLE_INDENT * i
        fake_lines.append(f"{prefix}if True:\n")
    if indent_levels:
        prefix = SINGLE_INDENT * indent_levels
        fake_lines.append(f"{prefix}pass\n")

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.