Giter Club home page Giter Club logo

brunette's Introduction

brunette

๐ŸŸค A best practice Python code formatter

PyPI version

This is the "black" formatter but with some improvements:

  1. --config option supports setup.cfg format.
    • Where a single-quotes option enables single quotes as the preferred.
  2. --single-quotes option to make single quotes the preferred.

Installation

pip install brunette

Usage

Use in the same way you would the 'black' formatter.

brunette **/*.py
brunette *.py --config=setup.cfg
brunette *.py --line-length=79 --single-quotes

Example setup.cfg:

[tool:brunette]
line-length = 79
verbose = true
single-quotes = false
# etc, etc...

This can also be combined with Flake8's configuration:

[flake8]
# This section configures `flake8`, the python linting utility.
# See also https://flake8.pycqa.org/en/latest/user/configuration.html
ignore = E201,E202,E203
# E201 - whitespace after โ€˜(โ€˜
# E202 - whitespace before โ€˜)โ€™
# E203 - whitespace before โ€˜:โ€™

# Exclude the git directory and virtualenv directory (as `.env`)
exclude = .git,.env

[tool:brunette]
line-length = 79
# etc, etc...

Why does this need to exist?

  • The current maintainer of Black, refuses to allow a single-quotes option. Due to his own personal preference (a preference which most of the Python community do not share).

  • The current maintainer of Black, refuses to add setup.cfg support. Setup.cfg is the most widely used configuration file for Python projects. The maintainer of that library prefers "pyproject.toml" few people use at this time due to it's inflexibility and it requiring you to use Poetry, whatever that is.

  • The current configuration file format as adopted by Black may conflict with the new build isolation context with pip. To avoid this, the use of a setup.cfg file is preferred but the policy is under review by the maintainers (pypa/pip#8437 (comment)).

How to configure in VSCode

  1. Get the full path to your brunette installation. In your terminal type:
  • which brunette (Linux)
  • where brunette (Windows)

In my case this looks like /home/work/.pyenv/shims/brunette. On Windows thats more like C:\Python39\Scripts\brunette.exe. Now copy whatever that value is.\

  1. Open the setttings UI.

  2. Search for black.

  • Paste that path into Black Path.
  • Set black as the Python Formatting Provider.
  • Add arguments as --single-quotes you like to the Black Args

https://i.imgur.com/6EXoamM.png

  1. That's it! Now whenever you format your Python code brunette will be used.

How to configure with Pre-Commit (https://pre-commit.com)

  1. Run pip install pre-commit to install

  2. Add a local repo option for brunette in .pre-commit-config.yaml

# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
  - repo: https://github.com/odwyersoftware/brunette
    rev: 0.2.7
    hooks:
      - id: brunette
  # Drop-in replacement for black with brunette
  # - repo: https://github.com/psf/black
  #   rev: stable
  #   hooks:
  #     - id: black
  #       language_version: python3.6
  - repo: https://gitlab.com/pycqa/flake8
    rev: 3.8.1
    hooks:
      - id: flake8
  1. Run pre-commit install to install the Git pre-commit hook

  2. Run pre-commit run to validate all files

brunette's People

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  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  avatar  avatar

brunette's Issues

brunette is not changing to single quotes

brunette . --target-version py36 --config setup.cfg (within the checked out brunette repo).
==> All single quotes are changed into double quotes.

Very likely this is because black is starting some kind of daemon process in which the black module is re-loaded... Causing the single-quote implementation you had to be ignored (again).

target-version is not configurable

Or at the very least I wasn't able to get it through :-).
I tried in the setup.cfg file: target-version = py36. But in click it will loop over the characters (p, y, 3, 6) and didn't find p in the list py27, py36, ...
As such it failed.

So I tried to figure out how black is doing it and they need this setting: ['py36'] in their toml file.

Setting this value (with or without the quotes) in the setup.cfg failed as well...

How could I define the target version in the setup.cfg file?

Thanks!

--single-quotes option

Hello, so far one needs to provide a .cgf file with the --config option, right?

Would it be possible to append an option for the --single-quotes option right away?

Like creating an according click.Option() and adding it here? ๐Ÿค”

I mean. I tried exactly this but I'm getting a TypeError

TypeError: main() got an unexpected keyword argument 'single_quotes'

My monkeypatching skills seem worthless here... any ideas?

Support both tool:brunette and brunette section in setup.ini

Hi,

isort supports both isort and tool:isort of the setup.cfg file. Can we also add support for both brunette and tool:brunette? Currently only tool:brunette is supported AFAIK. It's a small change, but it would be more consistent with tools that don't use tool: prefix in the setup.ini file.

Thanks!

black version pin is restrictive. necessary?

Thank you for writing this wrapper for black . I wanted to raise one small suggestion: your requirements file should not pin the black version.

Perhaps your tool can concern itself only with its compatibility with the parts of the Black api and application surface area that it needs to use, but aside from setting a minimum Black version (and possibly a max version, if necessary) I'd argue that you can leave the specific Black version up to your users.

I'm suggesting changing

requirements.txt

setuptools
wheel
black==20.8b1
click

to

setuptools
wheel
black>=20.8b1
click

Hopefully, you can pin the dev copy, so that formatting of brunette source code remains fixed. Ie. hopefully there's nothing wrong with this change:

requirements-dev.txt

black==20.8b1

INTERNAL ERROR: `root` must be absolute but is .

pip install -U brunette: v 0.1.7 installed.

The following commands I all ran in the latest cloned git master of brunette:

Reformat the current directory with default settings with black:

(base) E:\brunette>black .
reformatted E:\brunette\setup.py
reformatted E:\brunette\brunette\brunette.py
All done! โœจ ๐Ÿฐ โœจ
2 files reformatted, 2 files left unchanged.

Same but with brunette:

(base) E:\brunette>brunette .
Using configuration from E:\brunette\setup.cfg.
.git ignored: matches the --exclude regular expression
E:\brunette\brunette\__init__.py already well formatted, good job.
E:\brunette\brunette\__main__.py already well formatted, good job.
E:\brunette\setup.py already well formatted, good job.
reformatted E:\brunette\brunette\brunette.py
All done! โœจ ๐Ÿฐ โœจ
1 file reformatted, 3 files left unchanged.

Now use the config file provided within git:

(base) E:\brunette>brunette --config setup.cfg .
Using configuration from setup.cfg.
Traceback (most recent call last):
  File "c:\programdata\miniconda3\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "c:\programdata\miniconda3\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\ProgramData\Miniconda3\Scripts\brunette.exe\__main__.py", line 7, in <module>
  File "c:\programdata\miniconda3\lib\site-packages\brunette\brunette.py", line 150, in main
    return BLACK_MAIN()
  File "c:\programdata\miniconda3\lib\site-packages\click\core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "c:\programdata\miniconda3\lib\site-packages\click\core.py", line 782, in main
    rv = self.invoke(ctx)
  File "c:\programdata\miniconda3\lib\site-packages\click\core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "c:\programdata\miniconda3\lib\site-packages\click\core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "c:\programdata\miniconda3\lib\site-packages\click\decorators.py", line 21, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "c:\programdata\miniconda3\lib\site-packages\black.py", line 463, in main
    p, root, include_regex, exclude_regex, report, get_gitignore(root)
  File "c:\programdata\miniconda3\lib\site-packages\black.py", line 3559, in gen_python_files
    assert root.is_absolute(), f"INTERNAL ERROR: `root` must be absolute but is {root}"
AssertionError: INTERNAL ERROR: `root` must be absolute but is .

Ok, maybe it's the directory?

(base) E:\brunette>brunette --config setup.cfg brunette
Using configuration from setup.cfg.
Traceback (most recent call last):
  File "c:\programdata\miniconda3\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "c:\programdata\miniconda3\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\ProgramData\Miniconda3\Scripts\brunette.exe\__main__.py", line 7, in <module>
  File "c:\programdata\miniconda3\lib\site-packages\brunette\brunette.py", line 150, in main
    return BLACK_MAIN()
  File "c:\programdata\miniconda3\lib\site-packages\click\core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "c:\programdata\miniconda3\lib\site-packages\click\core.py", line 782, in main
    rv = self.invoke(ctx)
  File "c:\programdata\miniconda3\lib\site-packages\click\core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "c:\programdata\miniconda3\lib\site-packages\click\core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "c:\programdata\miniconda3\lib\site-packages\click\decorators.py", line 21, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "c:\programdata\miniconda3\lib\site-packages\black.py", line 463, in main
    p, root, include_regex, exclude_regex, report, get_gitignore(root)
  File "c:\programdata\miniconda3\lib\site-packages\black.py", line 3559, in gen_python_files
    assert root.is_absolute(), f"INTERNAL ERROR: `root` must be absolute but is {root}"
AssertionError: INTERNAL ERROR: `root` must be absolute but is .

Ok, maybe it needs to be absolute like it says in the error?

(base) E:\brunette>brunette --config setup.cfg e:\brunette
Using configuration from setup.cfg.
Traceback (most recent call last):
  File "c:\programdata\miniconda3\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "c:\programdata\miniconda3\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\ProgramData\Miniconda3\Scripts\brunette.exe\__main__.py", line 7, in <module>
  File "c:\programdata\miniconda3\lib\site-packages\brunette\brunette.py", line 150, in main
    return BLACK_MAIN()
  File "c:\programdata\miniconda3\lib\site-packages\click\core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "c:\programdata\miniconda3\lib\site-packages\click\core.py", line 782, in main
    rv = self.invoke(ctx)
  File "c:\programdata\miniconda3\lib\site-packages\click\core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "c:\programdata\miniconda3\lib\site-packages\click\core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "c:\programdata\miniconda3\lib\site-packages\click\decorators.py", line 21, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "c:\programdata\miniconda3\lib\site-packages\black.py", line 463, in main
    p, root, include_regex, exclude_regex, report, get_gitignore(root)
  File "c:\programdata\miniconda3\lib\site-packages\black.py", line 3559, in gen_python_files
    assert root.is_absolute(), f"INTERNAL ERROR: `root` must be absolute but is {root}"
AssertionError: INTERNAL ERROR: `root` must be absolute but is .

What actually breaks in later Black versions?

brunette >= 2.6.0 is pinning black to older versions, but in my (light) testing everything seems to work fine for me with black-22.3.0. I assume there's some corner-case that my codebase isn't triggering. Would you be willing to share more details about what's going on? I'm happy to take a look at fixing it as keeping black up to date is important for us. Thanks!

How to add exclude?

I would like to exclude directories like */migrations/*
How to do this in setup.cfg?

Import error

On a fresh install:

ImportError: cannot import name 'PY36_VERSIONS' from 'black' (/venv/lib/python3.9/site-packages/black/init.py)

pyproject.toml

Black supports pyproject.toml now but brunette does not seem to yet. Would be nice to have. Thanks!

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.