Git Product home page Git Product logo

gray's Introduction

gray

Package Version Build Status

Less uncompromising Python code formatter.

Gray stands on the shoulders of giants:

  • isort - imports sorting and more
  • pyupgrade - automatically upgrades syntax for newer versions of Python
  • autoflake - remove unused imports and variables
  • add-trailing-comma
  • trim - remove trailing whitespaces
  • unify - unify quotes style
  • fixit - various code formatters on LibCST
  • black - optional - the uncompromising Python code formatter

Usage

usage:
            gray myapp.py
            gray myproj/ tests/
            gray --log-level debug --formatters isort,unify ~/app


Less uncompromising Python code formatter.

positional arguments:
  paths                 Paths to format (default: (PosixPath('.'),))

optional arguments:
  -h, --help            show this help message and exit
  --exclude EXCLUDE     A regular expression matching files and directories that should be
                        excluded from formatting. Passing an explicit empty value means not paths
                        get excluded. Use '/' as directory separator, including on Windows.
                        [default: (.*/)?(\.direnv|\.eggs|\.git|\.hg|\.mypy_cache|\.nox|\.tox|\.ven
                        v|venv|\.svn|_build|buck-out|build|dist|__pypackages__)$] (default: (.*/)?
                        (\.direnv|\.eggs|\.git|\.hg|\.mypy_cache|\.nox|\.tox|\.venv|venv|\.svn|_bu
                        ild|buck-out|build|dist|__pypackages__)$)
  --extend-exclude EXTEND_EXCLUDE
                        An additional regular expression to use besides --exclude. This allows to
                        keep the default regex from --exclude. (default: None)
  --pool-size POOL_SIZE
                        process pool size (default: 8)
  --do-not-detect-venv  Don't try to detect virtualenv (default: False)

Logging options:
  --log-level {debug,info,warning,error,fatal}

Formatters options:
  -f FORMATTERS, --formatters FORMATTERS
                        Enabled formatters separated by comma (optional: black) (default: add-
                        trailing-comma,autoflake,fixit,isort,pyupgrade,trim,unify)
  --min-python-version MIN_PYTHON_VERSION
                        Minimum python version to support (default: (3, 9))

pyupgrade options:
  --pyupgrade-keep-percent-format PYUPGRADE_KEEP_PERCENT_FORMAT
                        Do not upgrade percent formatted strings to f-strings (default: False)
  --pyupgrade-keep-mock PYUPGRADE_KEEP_MOCK
                        Disable rewrite of mock imports (default: False)
  --pyupgrade-keep-runtime-typing PYUPGRADE_KEEP_RUNTIME_TYPING
                        Disable pep 585 typing rewrites (default: False)

unify options:
  --unify-quote UNIFY_QUOTE
                        preferred quote (default: ")

isort options:
  --isort-profile ISORT_PROFILE
                        Base profile type to use for configuration. (default: None)
  --isort-line-length ISORT_LINE_LENGTH
                        The max length of an import line (used for wrapping long imports)
                        (default: 80)
  --isort-wrap-length ISORT_WRAP_LENGTH
                        Specifies how long lines that are wrapped should be, if not set
                        line_length is used. NOTE: wrap_length must be LOWER than or equal to
                        line_length (default: None)
  --isort-multi-line-output ISORT_MULTI_LINE_OUTPUT
                        Multi line output (0-grid, 1-vertical, 2-hanging, 3-vert-hanging, 4-vert-
                        grid, 5-vert-grid-grouped, 6-deprecated-alias-for-5, 7-noqa, 8-vertical-
                        hanging-indent-bracket, 9-vertical-prefix-from-module-import, 10-hanging-
                        indent-with-parentheses). (default: 5)
  --isort-known-third-party ISORT_KNOWN_THIRD_PARTY
                        Force isort to recognize a module as being part of a third party library.
                        (default: None)
  --isort-known-first-party ISORT_KNOWN_FIRST_PARTY
                        Force isort to recognize a module as being part of the current python
                        project. (default: None)
  --isort-known-local-folder ISORT_KNOWN_LOCAL_FOLDER
                        Force isort to recognize a module as being a local folder. Generally, this
                        is reserved for relative imports (from . import module). (default: None)
  --isort-virtual-env ISORT_VIRTUAL_ENV
                        virtual env path (default: env)
  --isort-include-trailing-comma ISORT_INCLUDE_TRAILING_COMMA
                        Includes a trailing comma on multi line imports that include parentheses.
                        (default: True)
  --isort-lines-after-imports ISORT_LINES_AFTER_IMPORTS
                        empty lines after imports (default: 2)
  --isort-skip-gitignore ISORT_SKIP_GITIGNORE
                        Treat project as a git repository and ignore files listed in .gitignore.
                        (default: True)
  --isort-use-parentheses ISORT_USE_PARENTHESES
                        Use parentheses for line continuation on length limit instead of slashes.
                        **NOTE**: This is separate from wrap modes, and only affects how
                        individual lines that are too long get continued, not sections of multiple
                        imports.. (default: True)
  --isort-length-sort ISORT_LENGTH_SORT
                        Sort imports by their string length. (default: False)

autoflake options:
  --autoflake-ignore-init-module-imports AUTOFLAKE_IGNORE_INIT_MODULE_IMPORTS
  --autoflake-expand-star-imports AUTOFLAKE_EXPAND_STAR_IMPORTS
  --autoflake-remove-all-unused-imports AUTOFLAKE_REMOVE_ALL_UNUSED_IMPORTS
  --autoflake-remove-duplicate-keys AUTOFLAKE_REMOVE_DUPLICATE_KEYS
  --autoflake-remove-unused-variables AUTOFLAKE_REMOVE_UNUSED_VARIABLES

trim options:
  --trim-leading-newlines TRIM_LEADING_NEWLINES

fixit options:
  --fixit-redundant-fstrings FIXIT_REDUNDANT_FSTRINGS
  --fixit-redundant-lambdas FIXIT_REDUNDANT_LAMBDAS
  --fixit-redundant-list-comprehensions FIXIT_REDUNDANT_LIST_COMPREHENSIONS
  --fixit-to-comprehensions FIXIT_TO_COMPREHENSIONS
  --fixit-to-literals FIXIT_TO_LITERALS
  --fixit-to-fstrings FIXIT_TO_FSTRINGS

black options:
  --black-line-length BLACK_LINE_LENGTH
                        How many characters per line to allow. (default: 88)
  --black-skip-magic-trailing-comma BLACK_SKIP_MAGIC_TRAILING_COMMA
                        Don't use trailing commas as a reason to split lines. (default: False)
  --black-skip-string-normalization BLACK_SKIP_STRING_NORMALIZATION
                        Don't normalize string quotes or prefixes. (default: False)

Args that start with '--' (eg. --exclude) can also be set in a config file (/Users/stephane/.gray
or /etc/gray.conf or ./gray.conf). Config file syntax allows: key=value, flag=true, stuff=[a,b,c]
(for details, see syntax at https://goo.gl/R74nmi). If an arg is specified in more than one place,
then commandline values override config file values which override defaults.

Git Hook

You can setup gray formatting before each commit with pre-commit git hook. Add following file to .git/hooks/pre-commit and make it executable with chmod +x .git/hooks/pre-commit.

#!/usr/bin/env python
from gray.hooks import git_pre_commit

exit(git_pre_commit(stop_on_modify=True))

If stop_on_modify argument is True, hook will prevent commit if there are any unstaged changes in files you about to commit.

Otherwise, any unstaged changes in this files will be added to the index by the hook.

Config file

Gray is looking for config file in ./gray.conf, /etc/gray.conf or ~/.gray.

Example of grayconf:

formatters = add-trailing-comma,isort,unify
min-python-version = 3.5

Features

  • TODO

Git pre-commit hook

Use pre-commit. Once you have it installed, add this to the .pre-commit-config.yaml in your repository:

repos:
  - repo: https://github.com/dizballanze/gray
    rev: master # Replace by any tag/branch: https://github.com/dizballanze/gray/tags
    hooks:
      - id: gray

and run pre-commit install.

Using with Sourcetree

Sourcetree may run without gray being available via PATH.

MacOS

Make sure gray is available via PATH and run open /Applications/Sourcetree.app. Or better create an Automator workflow with source ~/.bash_profile && open /Applications/Sourcetree.app script.

gray's People

Contributors

alviner avatar dizballanze avatar mosquito avatar sobolevn avatar sodul avatar thomasfaivre 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  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

gray's Issues

Add support for Black

I understand the idea is a bit counter to what gray intents to offer but we think this can make sense.

We use the following to format our code:

  • pyupgrade
  • black -S -l 100
  • isort (with google profile)
  • unify

We have now added all of this as part of our CI pipeline and have a small script wrapping all that.
If we were to use gray, it would be able to handle all of this in a more straightforward manner and have better pre-commit support.

We settled on using Black as it turns out to be both pretty fast and quite compatible with modern python syntax, working on code where yapf would simply crash for example. The consistency of the formatted code is good as it removes the distraction of the formatting from PR reviews.

Since each formatter is optional in Gray, I think supporting black is actually natural. And black is just a very dark shade of gray, right?

If you are open to the idea I can look into submitting a PR.

Add support for per folder rules

It would be good to be able to tune the rules to be different in some subfolders while still be compatible with a single pre-commit hook.

The use case is that we have a mono repo where most of our python code will run with Python 3.10. As such we want to take advantage of the newer Python 3.10 syntax and other improvements.

Unfortunately in some of that repo we have some test scripts and lambdas that need to run with older versions of Python. AWS Lambdas got support for 3.9 only recently and it will probably be months before 3.10 support is available. The testing scripts are meant to run on various OS versions and some of them only have python 3.6 available.

I suppose a workaround would be to wrap gray to 'exclude' the directories with code older than the versions picked for the majority of the code base, and that will be addressed in #11, but supporting different rules per folder would be very convenient.

Report which files were modified

We want to use unify through the gray project as a pre-commit hook.

It works well but we are getting feedback from our developers that the output is confusing when files are changed:

gray.....................................................................Failed
- hook id: gray
- files were modified by this hook

For example with black more details are provided:

black....................................................................Failed
    - hook id: black
    - files were modified by this hook

reformatted <filename>
...
All done! ✨ 🍰 ✨
15 files reformatted, 1 file left unchanged.

It would be informative to have an output such as:

gray.....................................................................Failed
- hook id: gray
- files were modified by this hook

Unified quotes in <filename>.

This relates to myint/unify#19

Lack of git tags/releases is confusing pre-commit

We get this warning from pre-commit after adding gray:

[WARNING] The 'rev' field of repo 'https://github.com/dizballanze/gray' appears to be a mutable reference (moving tag / branch).  Mutable references are never updated after first install and are not supported.  See https://pre-commit.com/#using-the-latest-version-for-a-repository for more details.  Hint: `pre-commit autoupdate` often fixes this.

No need to add older releases but it would be good to create a Git release/tag each time gray is released on pypi.org.

Thank you!

gray fails with autoflake >= 1.5

Code that is used from autoflake in gray has changed.

From 1.5 version, args are expected to be dict.

Steps to reproduce:

mkdir gray-test
cd $_
python3.9 -m venv env
. env/bin/activate
touch example.py
gray example.py

Failed to reformat file "example.py"
Traceback (most recent call last):
  File ".../gray-test/env/lib/python3.9/site-packages/gray/processing.py", line 124, in worker
    fade_file(fname, formatter)
  File ".../gray-test/env/lib/python3.9/site-packages/gray/processing.py", line 114, in fade_file
    formatter.process(file_path)
  File ".../gray-test/env/lib/python3.9/site-packages/gray/formatters/composite.py", line 16, in process
    formatter.process(file_path)
  File ".../gray-test/env/lib/python3.9/site-packages/gray/formatters/autoflake.py", line 25, in process
    fix_file(file_path, args=self._args, standard_out=sys.stdout)
  File ".../gray-test/env/lib/python3.9/site-packages/autoflake.py", line 901, in fix_file
    args["write_to_stdout"],
TypeError: 'Namespace' object is not subscriptable
[T:MainThread] ERROR:gray.processing: Failed when processing "example.py"

Can't run pip-compile against gray

I created a blank directory, setup a virtualenv with the latest pip and pip-tools. created a requirements.in with only 'gray' in it. and pip-compile fails.

└─> ls -al
drwxrwxr-x waboring waboring 4.0 KB Fri Nov 25 09:11:27 2022  .
drwxr-xr-x waboring waboring 4.0 KB Fri Nov 25 09:10:12 2022 ..
drwxrwxr-x waboring waboring 4.0 KB Fri Nov 25 09:11:27 2022  .venv
.rw-rw-r-- waboring waboring   5 B  Fri Nov 25 09:10:21 2022  dev-requirements.in
╭─waboring in dl360-1 in aprsd/tmp/test on [$!?] via 🐍 v3.8.15 (.venv)❯
└─> python --version
Python 3.8.15
╭─waboring in dl360-1 in aprsd/tmp/test on  [$!?] via 🐍 v3.8.15 (.venv)❯
└─> pip --version
pip 22.3.1 from /home/waboring/aprsd/tmp/test/.venv/lib/python3.8/site-packages/pip (python 3.8)
╭─waboring in dl360-1 in aprsd/tmp/test on  [$!?] via 🐍 v3.8.15 (.venv)❯
└─> pip freeze |grep pip-tools
pip-tools==6.10.0
╭─waboring in dl360-1 in aprsd/tmp/test on  [$!?] via 🐍 v3.8.15 (.venv)❯
└─> cat dev-requirements.in
gray
└─> pip-compile dev-requirements.in
WARNING: using legacy resolver is deprecated and will be removed in future versions. The default resolver will be change to 'backtracking' in 7.0.0 version. Specify --resolver=backtracking to silence this warning.
Using legacy resolver. Consider using backtracking resolver with `--resolver=backtracking`.
Could not find a version that matches pyflakes<3,<3.1.0,>=1.1.0,>=3.0.0 (from autoflake==1.7.8->gray==0.12.0->-r dev-requirements.in (line 1))
Tried: 0.3.0, 0.4.0, 0.5.0, 0.6.0, 0.6.1, 0.7, 0.7.1, 0.7.2, 0.7.3, 0.8, 0.8.1, 0.8.1, 0.9.0, 0.9.0, 0.9.1, 0.9.1, 0.9.2, 0.9.2, 1.0.0, 1.0.0, 1.1.0, 1.1.0, 1.2.0, 1.2.0, 1.2.1, 1.2.1, 1.2.2, 1.2.2, 1.2.3, 1.2.3, 1.3.0, 1.3.0, 1.4.0, 1.4.0, 1.5.0, 1.5.0, 1.6.0, 1.6.0, 2.0.0, 2.0.0, 2.1.0, 2.1.0, 2.1.1, 2.1.1, 2.2.0, 2.2.0, 2.3.0, 2.3.0, 2.3.1, 2.3.1, 2.4.0, 2.4.0, 2.5.0, 2.5.0, 3.0.0, 3.0.0, 3.0.1, 3.0.1
There are incompatible versions in the resolved dependencies:
  pyflakes<3,>=1.1.0 (from autoflake==1.7.8->gray==0.12.0->-r dev-requirements.in (line 1))
  pyflakes<3.1.0,>=3.0.0 (from flake8==6.0.0->fixit==0.1.4->gray==0.12.0->-r dev-requirements.in (line 1))

Fixit v2 and Python 3.12 support

Gray is not compatible with fixit v2 and fixit v1 is not compatible with python 3.12. As such for gray to be compatible with Python 3.12 the dependency on fixit needs to be updated.

python3.12/site-packages/fixit/common/config.py", line 6, in <module>
    import distutils.spawn
ModuleNotFoundError: No module named 'distutils'

I confirmed that distutil was removed in Python 3.12 and fixit v2 does not call distutil.

Add Blue as an alternative to Black

We use gray with black and unify so that we can get the formatting from Black yet use single quotes. Since Blue is a more direct solution to use single quotes (it patches Black to do so), I was thinking that Blue could be added.

Since I did the work to add Black in v0.10.0 I should be able to submit a PR for this as well.

https://github.com/grantjenks/blue

Add --dry-run/--check-only support

isort as a feature called --check-only which allows you to run the tool and find out what files are out of compliance and would be modified. This is a very useful feature for finding out what files need to be fixed.

gray --check-only src

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.