python-dev-tools
Advanced tools
+32
-10
| Metadata-Version: 2.1 | ||
| Name: python-dev-tools | ||
| Version: 2022.5.20 | ||
| Version: 2022.5.26 | ||
| Summary: Needed and up-to-date tools to develop in Python | ||
@@ -17,3 +17,2 @@ Home-page: https://github.com/vpoulailleau/python-dev-tools | ||
| Classifier: Programming Language :: Python :: 3.10 | ||
| Classifier: Programming Language :: Python :: 3.6 | ||
| Classifier: Programming Language :: Python :: 3.7 | ||
@@ -25,9 +24,8 @@ Classifier: Programming Language :: Python :: 3.8 | ||
| Requires-Dist: autoflake (>=1,<2) | ||
| Requires-Dist: bandit (==1.7.2) | ||
| Requires-Dist: black (>=22,<23) | ||
| Requires-Dist: cohesion (>=1,<2) | ||
| Requires-Dist: coverage (>=6,<7) | ||
| Requires-Dist: coverage[toml] (>=6,<7) | ||
| Requires-Dist: darglint (>=1,<2) | ||
| Requires-Dist: dlint (>=0,<1) | ||
| Requires-Dist: doc8 (>=0,<1) | ||
| Requires-Dist: docformatter (>=1,<2) | ||
| Requires-Dist: flake8 (>=4,<5) | ||
@@ -38,6 +36,6 @@ Requires-Dist: flake8-2020 (>=1,<2) | ||
| Requires-Dist: flake8-annotations-coverage (>=0,<1) | ||
| Requires-Dist: flake8-bandit (>=2,<3) | ||
| Requires-Dist: flake8-bandit (>=3,<4) | ||
| Requires-Dist: flake8-black (>=0,<1) | ||
| Requires-Dist: flake8-broken-line (>=0,<1) | ||
| Requires-Dist: flake8-bugbear (>=21,<22) | ||
| Requires-Dist: flake8-bugbear (>=22,<23) | ||
| Requires-Dist: flake8-builtins (>=1,<2) | ||
@@ -65,2 +63,4 @@ Requires-Dist: flake8-comprehensions (>=3,<4) | ||
| Requires-Dist: pip (>=22,<23) | ||
| Requires-Dist: pybetter (>=0,<1) | ||
| Requires-Dist: pycln (>=1,<2) | ||
| Requires-Dist: pycodestyle (>=2,<3) | ||
@@ -73,2 +73,4 @@ Requires-Dist: pydocstyle (>=6,<7) | ||
| Requires-Dist: pyupgrade (>=2,<3) | ||
| Requires-Dist: removestar (>=1,<2) | ||
| Requires-Dist: ssort (>=0,<1) | ||
| Requires-Dist: tox (>=3,<4) | ||
@@ -93,5 +95,8 @@ Requires-Dist: tox-travis (>=0,<1) | ||
| .. image:: https://travis-ci.com/vpoulailleau/python-dev-tools.svg?branch=master | ||
| :target: https://travis-ci.com/vpoulailleau/python-dev-tools | ||
| .. image:: https://img.shields.io/pypi/pyversions/python_dev_tools.svg?style=flat-square&logo=python&logoColor=fff | ||
| :target: https://pypi.python.org/pypi/python_dev_tools | ||
| .. image:: https://github.com/vpoulailleau/python-dev-tools/actions/workflows/tests.yml/badge.svg | ||
| :target: https://github.com/vpoulailleau/python-dev-tools/actions/workflows/tests.yml | ||
| .. image:: https://readthedocs.org/projects/python-dev-tools/badge/?version=latest | ||
@@ -173,3 +178,2 @@ :target: https://python-dev-tools.readthedocs.io/en/latest/?badge=latest | ||
| * cohesion: https://github.com/mschwager/cohesion | ||
| * darglint: https://github.com/terrencepreilly/darglint | ||
@@ -214,3 +218,9 @@ * dlint: https://github.com/dlint-py/dlint | ||
| * black: https://github.com/python/black | ||
| * docformatter: https://github.com/PyCQA/docformatter | ||
| * isort: https://github.com/PyCQA/isort | ||
| * pybetter: https://github.com/lensvol/pybetter | ||
| * pycln: https://github.com/hadialqattan/pycln | ||
| * pyupgrade: https://github.com/asottile/pyupgrade | ||
| * removestar: https://github.com/asmeurer/removestar | ||
| * ssort: https://github.com/bwhmather/ssort | ||
@@ -229,2 +239,3 @@ * Simple precommit hook | ||
| * flake8 formatter to add URL to information on a warning | ||
| * documentation | ||
@@ -236,2 +247,13 @@ * precommit | ||
| 2022.5.26 | ||
| ^^^^^^^^^ | ||
| * Add ``docformatter`` formatter | ||
| * Add ``isort`` formatter | ||
| * Add ``pybetter`` formatter | ||
| * Add ``pycln`` formatter | ||
| * Add ``removestar`` formatter | ||
| * Add ``ssort`` formatter | ||
| * Remove ``cohesion`` linter (false warnings on pure data classes such as ``NamedTuple``) | ||
| 2022.5.20 | ||
@@ -238,0 +260,0 @@ ^^^^^^^^^ |
+22
-31
| [tool.poetry] | ||
| name = "python_dev_tools" | ||
| version = "2022.5.20" | ||
| version = "2022.5.26" | ||
| description = "Needed and up-to-date tools to develop in Python" | ||
@@ -11,6 +11,6 @@ classifiers=[ | ||
| "Programming Language :: Python :: 3", | ||
| "Programming Language :: Python :: 3.6", | ||
| "Programming Language :: Python :: 3.7", | ||
| "Programming Language :: Python :: 3.8", | ||
| "Programming Language :: Python :: 3.9", | ||
| "Programming Language :: Python :: 3.10", | ||
| "Topic :: Utilities", | ||
@@ -30,9 +30,8 @@ ] | ||
| autoflake = "^1" | ||
| bandit = "1.7.2" # https://github.com/tylerwince/flake8-bandit/issues/24 | ||
| black = "^22" | ||
| cohesion = "^1" | ||
| coverage = "^6" | ||
| coverage = {version = "^6", extras = ["toml"]} | ||
| darglint = "^1" | ||
| dlint = "^0" | ||
| doc8 = "^0" | ||
| docformatter = "^1" | ||
| flake8 = "^4" | ||
@@ -43,6 +42,6 @@ flake8-2020 = "^1" | ||
| flake8-annotations-coverage = "^0" | ||
| flake8-bandit = "^2" | ||
| flake8-bandit = "^3" | ||
| flake8-black = "^0" | ||
| flake8-broken-line = "^0" | ||
| flake8-bugbear = "^21" | ||
| flake8-bugbear = "^22" | ||
| flake8-builtins = "^1" | ||
@@ -70,2 +69,4 @@ flake8-comprehensions = "^3" | ||
| pep8-naming = "^0" | ||
| pybetter = "^0" | ||
| pycln = "^1" | ||
| pycodestyle = "^2" | ||
@@ -78,3 +79,5 @@ pydocstyle = "^6" | ||
| pyupgrade = "^2" | ||
| removestar = "^1" | ||
| Sphinx = "^4" | ||
| ssort = "^0" | ||
| tox = "^3" | ||
@@ -87,32 +90,20 @@ tox-travis = "^0" | ||
| [tool.tox] | ||
| legacy_tox_ini = """ | ||
| [tox] | ||
| isolated_build = True | ||
| envlist = py37, py38, py39, p310 | ||
| [testenv] | ||
| whitelist_externals = | ||
| poetry | ||
| echo | ||
| sed | ||
| cp | ||
| changedir = {toxinidir}/tests | ||
| commands = | ||
| poetry install -v | ||
| poetry run pytest -s -vv --cov=python_dev_tools | ||
| poetry run coverage xml | ||
| echo 'fix travis bug' | ||
| sed --in-place -e 's#//home#/home#g' coverage.xml | ||
| echo 'fix codeclimate bug, use relative path' | ||
| sed --in-place -e 's#/home.*vpoulailleau/python-dev-tools/##g' coverage.xml | ||
| cp coverage.xml ../coverage.xml | ||
| """ | ||
| [tool.poetry.plugins."flake8.extension"] | ||
| WAL = "python_dev_tools.whatalinter:WhatALinter" | ||
| [tool.pytest.ini_options] | ||
| minversion = "7.0" | ||
| addopts = "-ra -q -s -vv --cov=python_dev_tools" | ||
| testpaths = [ | ||
| "tests", | ||
| ] | ||
| [tool.coverage.report] | ||
| exclude_lines = [ | ||
| "pragma: no cover", | ||
| "if TYPE_CHECKING:", | ||
| ] | ||
| [build-system] | ||
| requires = ["poetry>=0.12"] | ||
| build-backend = "poetry.masonry.api" |
@@ -6,13 +6,86 @@ """Formatter module, aggregation of formatters.""" | ||
| import shutil | ||
| import subprocess # noqa: S404 | ||
| from pathlib import Path | ||
| from typing import List, NamedTuple | ||
| from python_dev_tools.formatters.format_file import format_file | ||
| class FormatterConfig(NamedTuple): | ||
| """Configuration of formatting tool.""" | ||
| def udpate_os_path(): | ||
| name: str | ||
| path: str | ||
| cli_args: List[str] | ||
| _formatters_configs: List[FormatterConfig] = [ | ||
| FormatterConfig( | ||
| name="autoflake", | ||
| path="autoflake", | ||
| cli_args=["--in-place", "--remove-unused-variables"], | ||
| ), | ||
| FormatterConfig(name="ssort", path="ssort", cli_args=[]), | ||
| FormatterConfig(name="docformatter", path="docformatter", cli_args=["--in-place"]), | ||
| FormatterConfig(name="removestar", path="removestar", cli_args=["-i"]), | ||
| FormatterConfig(name="pybetter", path="pybetter", cli_args=["--exclude", "B004"]), | ||
| FormatterConfig(name="pycln", path="pycln", cli_args=["--all"]), | ||
| FormatterConfig(name="pyupgrade", path="pyupgrade", cli_args=["--py37-plus"]), | ||
| FormatterConfig( | ||
| name="isort", | ||
| path="isort", | ||
| cli_args=[], | ||
| ), # Should be second to last config | ||
| FormatterConfig( | ||
| name="black", | ||
| path="black", | ||
| cli_args=["--target-version=py37"], | ||
| ), # Should be the last config | ||
| ] | ||
| def format_file(filepath: str) -> None: | ||
| """Format the file with known formatters. | ||
| Args: | ||
| filepath (str): path of the file to format | ||
| """ | ||
| for config in _formatters_configs: | ||
| try: | ||
| subprocess.run( # noqa: S603 | ||
| [config.path, *config.cli_args, filepath], | ||
| capture_output=True, | ||
| timeout=10, | ||
| encoding="utf-8", | ||
| ) | ||
| except FileNotFoundError as exc: | ||
| if exc.filename == config.path: | ||
| print(f"Formatter {config.name} not found: {config.path}") | ||
| def diff(orig_file: str) -> None: | ||
| """Print diff between original file and formatted file. | ||
| Args: | ||
| orig_file (str): path of the original file | ||
| """ | ||
| copy_file = f"{orig_file}.co.py" | ||
| shutil.copyfile(orig_file, copy_file) | ||
| format_file(filepath=copy_file) | ||
| print( | ||
| "".join( | ||
| difflib.unified_diff( | ||
| [f"{line}\n" for line in Path(orig_file).read_text().splitlines()], | ||
| [f"{line}\n" for line in Path(copy_file).read_text().splitlines()], | ||
| fromfile=orig_file, | ||
| tofile=orig_file, | ||
| ), | ||
| ), | ||
| ) | ||
| Path(copy_file).unlink() | ||
| def _udpate_os_path() -> None: | ||
| """Update PATH env variable to find linters.""" | ||
| paths = os.environ["PATH"].split(os.pathsep) | ||
| script_path = Path(__file__).resolve() | ||
| os.environ["PATH"] = "".join( | ||
| (str(script_path.parent), os.pathsep, os.environ["PATH"]), | ||
| ) | ||
| paths.insert(0, str(script_path.parent)) | ||
@@ -22,9 +95,8 @@ # replace /lib/ with /bin/, and add to PATH | ||
| if parent.stem == "lib": | ||
| os.environ["PATH"] = "".join( | ||
| (str(parent.parent / "bin"), os.pathsep, os.environ["PATH"]), | ||
| ) | ||
| paths.insert(0, str(parent.parent / "bin")) | ||
| os.environ["PATH"] = os.pathsep.join(paths) | ||
| def main(): | ||
| """Entry point.""" | ||
| def _cli_parser() -> argparse.ArgumentParser: | ||
| parser = argparse.ArgumentParser( | ||
@@ -57,23 +129,13 @@ description="Python formatter combining existing formatters", | ||
| ) | ||
| return parser | ||
| def main() -> None: | ||
| """Entry point.""" | ||
| # TODO passer cet argument à black et pyupgrade | ||
| args = parser.parse_args() | ||
| args = _cli_parser().parse_args() | ||
| udpate_os_path() | ||
| _udpate_os_path() | ||
| if args.diff: | ||
| copy_file = f"{args.file}.co.py" | ||
| shutil.copyfile(args.file, copy_file) | ||
| format_file(filepath=copy_file) | ||
| orig_content = Path(args.file).read_text() | ||
| copy_content = Path(copy_file).read_text() | ||
| print( | ||
| "".join( | ||
| difflib.unified_diff( | ||
| [line + "\n" for line in orig_content.splitlines()], | ||
| [line + "\n" for line in copy_content.splitlines()], | ||
| fromfile=args.file, | ||
| tofile=args.file, | ||
| ), | ||
| ), | ||
| ) | ||
| Path(copy_file).unlink() | ||
| diff(args.file) | ||
| else: | ||
@@ -80,0 +142,0 @@ format_file(filepath=args.file) |
@@ -0,21 +1,54 @@ | ||
| """Linter module, flake8 plugin.""" | ||
| import ast | ||
| from typing import TYPE_CHECKING, List, Type | ||
| import pkg_resources | ||
| from typing import TYPE_CHECKING | ||
| if TYPE_CHECKING: | ||
| import sys | ||
| from flake8.options.manager import OptionManager | ||
| if sys.version_info < (3, 8): | ||
| from typing import Any as Final # noqa: WPS433, WPS440 | ||
| else: | ||
| from typing import Final # noqa: WPS433, WPS440 | ||
| else: | ||
| from typing import Any as Final # noqa: WPS440 | ||
| MAX_LINE_LENGTH: Final = 88 | ||
| MAX_COMPLEXITY: Final = 10 | ||
| ERROR_CODE: Final = "WAL" | ||
| class WhatALinter: | ||
| """WhatALinter flake8 plugin.""" | ||
| name = "whatalinter" | ||
| version = pkg_resources.get_distribution("python_dev_tools").version | ||
| def __init__(self, tree): | ||
| pass | ||
| def __init__(self: "WhatALinter", tree: ast.AST) -> None: | ||
| """Empty method, needed by flake8. | ||
| def run(self): | ||
| Args: | ||
| tree (AST): unused | ||
| """ | ||
| def run(self: "WhatALinter") -> List: | ||
| """Empty method, needed by flake8. | ||
| Returns: | ||
| Empty list | ||
| """ | ||
| return [] | ||
| @classmethod | ||
| def add_options(cls, parser: "OptionManager"): | ||
| ERROR_CODE = "WAL" | ||
| def add_options(cls: Type["WhatALinter"], parser: "OptionManager") -> None: | ||
| """Add options to CLI parser. | ||
| Args: | ||
| parser (OptionManager): CLI parser | ||
| """ | ||
| parser.extend_default_select([ERROR_CODE]) | ||
@@ -28,7 +61,9 @@ parser.extend_default_ignore( | ||
| "WPS421", # Found wrong function call, useful in scripts | ||
| # "WPS602", # avoid @staticmethod (can be subclassed…) | ||
| ] | ||
| ], | ||
| ) | ||
| parser.parser.set_defaults( | ||
| max_line_length=88, max_complexity=10, inline_quotes='"' | ||
| min_python_version="3.7.0", | ||
| max_line_length=MAX_LINE_LENGTH, | ||
| max_complexity=MAX_COMPLEXITY, | ||
| inline_quotes='"', | ||
| ) |
+23
-3
@@ -13,5 +13,8 @@ Python Dev Tools | ||
| .. image:: https://travis-ci.com/vpoulailleau/python-dev-tools.svg?branch=master | ||
| :target: https://travis-ci.com/vpoulailleau/python-dev-tools | ||
| .. image:: https://img.shields.io/pypi/pyversions/python_dev_tools.svg?style=flat-square&logo=python&logoColor=fff | ||
| :target: https://pypi.python.org/pypi/python_dev_tools | ||
| .. image:: https://github.com/vpoulailleau/python-dev-tools/actions/workflows/tests.yml/badge.svg | ||
| :target: https://github.com/vpoulailleau/python-dev-tools/actions/workflows/tests.yml | ||
| .. image:: https://readthedocs.org/projects/python-dev-tools/badge/?version=latest | ||
@@ -93,3 +96,2 @@ :target: https://python-dev-tools.readthedocs.io/en/latest/?badge=latest | ||
| * cohesion: https://github.com/mschwager/cohesion | ||
| * darglint: https://github.com/terrencepreilly/darglint | ||
@@ -134,3 +136,9 @@ * dlint: https://github.com/dlint-py/dlint | ||
| * black: https://github.com/python/black | ||
| * docformatter: https://github.com/PyCQA/docformatter | ||
| * isort: https://github.com/PyCQA/isort | ||
| * pybetter: https://github.com/lensvol/pybetter | ||
| * pycln: https://github.com/hadialqattan/pycln | ||
| * pyupgrade: https://github.com/asottile/pyupgrade | ||
| * removestar: https://github.com/asmeurer/removestar | ||
| * ssort: https://github.com/bwhmather/ssort | ||
@@ -149,2 +157,3 @@ * Simple precommit hook | ||
| * flake8 formatter to add URL to information on a warning | ||
| * documentation | ||
@@ -156,2 +165,13 @@ * precommit | ||
| 2022.5.26 | ||
| ^^^^^^^^^ | ||
| * Add ``docformatter`` formatter | ||
| * Add ``isort`` formatter | ||
| * Add ``pybetter`` formatter | ||
| * Add ``pycln`` formatter | ||
| * Add ``removestar`` formatter | ||
| * Add ``ssort`` formatter | ||
| * Remove ``cohesion`` linter (false warnings on pure data classes such as ``NamedTuple``) | ||
| 2022.5.20 | ||
@@ -158,0 +178,0 @@ ^^^^^^^^^ |
+11
-8
@@ -5,3 +5,3 @@ # -*- coding: utf-8 -*- | ||
| packages = \ | ||
| ['python_dev_tools', 'python_dev_tools.formatters'] | ||
| ['python_dev_tools'] | ||
@@ -14,9 +14,8 @@ package_data = \ | ||
| 'autoflake>=1,<2', | ||
| 'bandit==1.7.2', | ||
| 'black>=22,<23', | ||
| 'cohesion>=1,<2', | ||
| 'coverage>=6,<7', | ||
| 'coverage[toml]>=6,<7', | ||
| 'darglint>=1,<2', | ||
| 'dlint>=0,<1', | ||
| 'doc8>=0,<1', | ||
| 'docformatter>=1,<2', | ||
| 'flake8-2020>=1,<2', | ||
@@ -26,6 +25,6 @@ 'flake8-annotations-complexity>=0,<1', | ||
| 'flake8-annotations>=2,<3', | ||
| 'flake8-bandit>=2,<3', | ||
| 'flake8-bandit>=3,<4', | ||
| 'flake8-black>=0,<1', | ||
| 'flake8-broken-line>=0,<1', | ||
| 'flake8-bugbear>=21,<22', | ||
| 'flake8-bugbear>=22,<23', | ||
| 'flake8-builtins>=1,<2', | ||
@@ -54,2 +53,4 @@ 'flake8-comprehensions>=3,<4', | ||
| 'pip>=22,<23', | ||
| 'pybetter>=0,<1', | ||
| 'pycln>=1,<2', | ||
| 'pycodestyle>=2,<3', | ||
@@ -62,2 +63,4 @@ 'pydocstyle>=6,<7', | ||
| 'pyupgrade>=2,<3', | ||
| 'removestar>=1,<2', | ||
| 'ssort>=0,<1', | ||
| 'tox-travis>=0,<1', | ||
@@ -73,5 +76,5 @@ 'tox>=3,<4', | ||
| 'name': 'python-dev-tools', | ||
| 'version': '2022.5.20', | ||
| 'version': '2022.5.26', | ||
| 'description': 'Needed and up-to-date tools to develop in Python', | ||
| 'long_description': 'Python Dev Tools\n================\n\nNeeded and up-to-date tools to develop in Python (*WORK IN PROGRESS*)\n\n\n.. image:: https://img.shields.io/pypi/v/python_dev_tools.svg\n :target: https://pypi.python.org/pypi/python_dev_tools\n\n.. image:: https://img.shields.io/pypi/l/python_dev_tools.svg\n :target: https://github.com/vpoulailleau/python_dev_tools/blob/master/LICENSE\n\n.. image:: https://travis-ci.com/vpoulailleau/python-dev-tools.svg?branch=master\n :target: https://travis-ci.com/vpoulailleau/python-dev-tools\n\n.. image:: https://readthedocs.org/projects/python-dev-tools/badge/?version=latest\n :target: https://python-dev-tools.readthedocs.io/en/latest/?badge=latest\n :alt: Documentation Status\n\n.. image:: https://pepy.tech/badge/python-dev-tools\n :target: https://pepy.tech/project/python-dev-tools\n :alt: Downloads\n\n.. image:: https://api.codeclimate.com/v1/badges/282fcd71714dabd6a847/test_coverage\n :target: https://codeclimate.com/github/vpoulailleau/python-dev-tools/test_coverage\n :alt: Test Coverage\n\n.. image:: https://api.codeclimate.com/v1/badges/282fcd71714dabd6a847/maintainability\n :target: https://codeclimate.com/github/vpoulailleau/python-dev-tools/maintainability\n :alt: Maintainability\n\n.. image:: https://bettercodehub.com/edge/badge/vpoulailleau/python-dev-tools?branch=master\n :target: https://bettercodehub.com/results/vpoulailleau/python-dev-tools\n :alt: Maintainability\n\n.. image:: https://img.shields.io/lgtm/grade/python/g/vpoulailleau/python-dev-tools.svg?logo=lgtm&logoWidth=1\n :target: https://lgtm.com/projects/g/vpoulailleau/python-dev-tools/context:python\n :alt: Maintainability\n\nSupported Python versions: the same as the classic Python interpreter (CPython)\n\nDocumentation\n-------------\n\nThe full documentation can be read at https://python-dev-tools.readthedocs.io.\n\nInstallation\n------------\n\nIn a terminal, run:\n\n.. code-block:: console\n\n $ python3 -m pip install python-dev-tools --user --upgrade\n\nFull documentation on installation: https://python-dev-tools.readthedocs.io/en/latest/installation.html\n\nThat\'s it! Use the provided linter (``flake8``), formatter (``whataformatter``) and\nprecommit hook (TODO) where applicable.\n\nInstallation with Visual Studio Code\n------------------------------------\n\n* Follow the installation procedure for python-dev-tools\n* Be sure to have the official Python extension installed in VS Code\n* Open VS Code from within your activated virtual environment (in fact, make sure that \n ``flake8`` from python-dev-tools is in your ``PYTHON_PATH``)\n* In VS Code, open settings (F1 key, then type "Open Settings (JSON)",\n then enter)\n* Add in the opened JSON file (before the closing ``}``):\n\n.. code:: javascript\n\n "python.linting.enabled": true,\n "python.linting.flake8Enabled": true,\n "python.linting.flake8Path": "flake8",\n "python.formatting.provider": "black",\n "python.formatting.blackPath": "whataformatter",\n "python.formatting.blackArgs": [],\n\nFeatures\n--------\n\nIntegrate features of commonly used tools. This package provides usual\ndependencies to develop Python software.\n\n* Simple linter\n\n * ``flake8 a_python_file.py`` lints a_python_file.py\n * based on flake8 and plugins: https://gitlab.com/pycqa/flake8\n\n * cohesion: https://github.com/mschwager/cohesion\n * darglint: https://github.com/terrencepreilly/darglint\n * dlint: https://github.com/dlint-py/dlint\n * flake8-2020: https://github.com/asottile/flake8-2020\n * flake8-annotations: https://github.com/sco1/flake8-annotations\n * flake8-annotations-complexity:\xa0https://github.com/best-doctor/flake8-annotations-complexity\n * flake8-annotations-coverage: https://github.com/best-doctor/flake8-annotations-coverage\n * flake8-bandit: https://github.com/tylerwince/flake8-bandit\n * flake8-broken-line: https://github.com/sobolevn/flake8-broken-line\n * flake8-bugbear: https://github.com/PyCQA/flake8-bugbear\n * flake8-builtins: https://github.com/gforcada/flake8-builtins\n * flake8-comprehensions: https://github.com/adamchainz/flake8-comprehensions\n * flake8-debugger: https://github.com/JBKahn/flake8-debugger\n * flake8-docstrings: https://gitlab.com/pycqa/flake8-docstrings\n * flake8-eradicate: https://github.com/sobolevn/flake8-eradicate\n * flake8-expression-complexity: https://pypi.org/project/flake8-expression-complexity/\n * flake8-fixme: https://github.com/tommilligan/flake8-fixme\n * flake8-functions: https://github.com/best-doctor/flake8-functions\n * flake8-isort: https://github.com/gforcada/flake8-isort\n * flake8-logging-format: https://github.com/globality-corp/flake8-logging-format\n * flake8-mutable: https://github.com/ebeweber/flake8-mutable\n * flake8-pytest-style: https://github.com/m-burst/flake8-pytest-style\n * flake8-quotes: https://github.com/zheller/flake8-quotes/\n * flake8-rst-docstrings: https://github.com/peterjc/flake8-rst-docstrings\n * flake8-simplify: https://github.com/MartinThoma/flake8-simplify\n * flake8-string-format: https://github.com/xZise/flake8-string-format\n * flake8-tidy-imports: https://github.com/adamchainz/flake8-tidy-imports\n * flake8-typing-imports: https://github.com/asottile/flake8-typing-imports\n * flake8-use-fstring: https://github.com/MichaelKim0407/flake8-use-fstring\n * flake8-variables-names: https://github.com/best-doctor/flake8-variables-names\n * pep8-naming: https://github.com/PyCQA/pep8-naming\n * wemake-python-styleguide: https://github.com/wemake-services/wemake-python-styleguide\n\n* Simple formatter\n\n * ``whataformatter a_python_file.py`` formats a_python_file.py\n * based on\n\n * autoflake: https://github.com/myint/autoflake\n * black: https://github.com/python/black\n * pyupgrade: https://github.com/asottile/pyupgrade\n\n* Simple precommit hook\n\n * TODO\n\nLicense\n-------\n\nBSD 3-Clause license, feel free to contribute: https://python-dev-tools.readthedocs.io/en/latest/contributing.html.\n\nTODO\n----\n\n* documentation\n* precommit\n\nChangelog\n---------\n\n2022.5.20\n^^^^^^^^^\n\n* Add ``cohesion`` linter\n* Add ``dlint`` linter\n* Add ``flake8-annotations`` linter\n* Add ``flake8-annotations-complexity`` linter\n* Add ``flake8-annotations-coverage`` linter\n* Add ``flake8-black`` linter\n* Add ``flake8-expression-complexity`` linter\n* Add ``flake8-functions`` linter\n* Add ``flake8-pytest-style`` linter\n* Add ``flake8-simplify`` linter\n* Add ``flake8-tidy-imports`` linter\n* Add ``flake8-typing-imports`` linter\n* Add ``flake8-use-fstring`` linter\n* Remove ``flake8-commas`` linter that is deprecated\n* Fix ``whataformatter`` and add ``--target-version`` option for VS Code compatibility\n\n2020.9.10\n^^^^^^^^^\n\n* The path provided to ``whatalinter`` can be the one of a directory\n (recursive search of Python files)\n\n2020.9.7\n^^^^^^^^\n\n* Remove E203 in ``flake8`` for ``black`` compatibility\n\n2020.9.4\n^^^^^^^^\n\n* Add ``whatalinter_vscode`` for Visual Studio Code integration\n\n2020.9.2\n^^^^^^^^\n\n* Remove some warnings of ``wemake-python-styleguide``, for instance allow f-strings\n\n2020.9.1\n^^^^^^^^\n\n* Use ``poetry``\n* Remove redundant linters\n* Change max line length to 88 (default value of ``black``)\n* Replace ``pydocstyle`` with ``flake8-docstrings``\n* Add ``wemake-python-styleguide``\n\n2019.10.22\n^^^^^^^^^^\n\n* Add ``flake8-2020`` linter\n\n2019.07.21\n^^^^^^^^^^\n\n* Add ``--quiet`` and ``--diff`` flags to ``whataformatter`` for VS Code compatibility\n\n2019.07.20\n^^^^^^^^^^\n\n* Add ``black`` formatter\n* Add ``autoflake`` formatter\n* Add ``pyupgrade`` formatter\n\n2019.04.08\n^^^^^^^^^^\n\n* Add ``flake8`` linter\n* Add ``flake8-isort`` linter\n* Add ``pep8-naming`` linter\n* Add ``flake8-comprehensions`` linter\n* Add ``flake8-logging-format`` linter\n* Add ``flake8-bugbear`` linter\n* Add ``flake8-builtins`` linter\n* Add ``flake8-broken-line`` linter\n* Add ``flake8-fixme`` linter\n* Add ``flake8-mutable`` linter\n* Add ``flake8-debugger`` linter\n* Add ``flake8-variables-names`` linter\n* Add ``flake8-bandit`` linter\n\n2019.03.02\n^^^^^^^^^^\n\n* Add ``pydocstyle`` linter\n\n2019.03.01\n^^^^^^^^^^\n\n* Add McCabe complexity checker\n\n2019.02.26\n^^^^^^^^^^\n\n* Add ``pyflakes`` linter\n* Add ``pycodestyle`` linter\n\n2019.02.23\n^^^^^^^^^^\n\n* First release on PyPI.\n', | ||
| 'long_description': 'Python Dev Tools\n================\n\nNeeded and up-to-date tools to develop in Python (*WORK IN PROGRESS*)\n\n\n.. image:: https://img.shields.io/pypi/v/python_dev_tools.svg\n :target: https://pypi.python.org/pypi/python_dev_tools\n\n.. image:: https://img.shields.io/pypi/l/python_dev_tools.svg\n :target: https://github.com/vpoulailleau/python_dev_tools/blob/master/LICENSE\n\n.. image:: https://img.shields.io/pypi/pyversions/python_dev_tools.svg?style=flat-square&logo=python&logoColor=fff\n :target: https://pypi.python.org/pypi/python_dev_tools\n\n.. image:: https://github.com/vpoulailleau/python-dev-tools/actions/workflows/tests.yml/badge.svg\n :target: https://github.com/vpoulailleau/python-dev-tools/actions/workflows/tests.yml\n\n.. image:: https://readthedocs.org/projects/python-dev-tools/badge/?version=latest\n :target: https://python-dev-tools.readthedocs.io/en/latest/?badge=latest\n :alt: Documentation Status\n\n.. image:: https://pepy.tech/badge/python-dev-tools\n :target: https://pepy.tech/project/python-dev-tools\n :alt: Downloads\n\n.. image:: https://api.codeclimate.com/v1/badges/282fcd71714dabd6a847/test_coverage\n :target: https://codeclimate.com/github/vpoulailleau/python-dev-tools/test_coverage\n :alt: Test Coverage\n\n.. image:: https://api.codeclimate.com/v1/badges/282fcd71714dabd6a847/maintainability\n :target: https://codeclimate.com/github/vpoulailleau/python-dev-tools/maintainability\n :alt: Maintainability\n\n.. image:: https://bettercodehub.com/edge/badge/vpoulailleau/python-dev-tools?branch=master\n :target: https://bettercodehub.com/results/vpoulailleau/python-dev-tools\n :alt: Maintainability\n\n.. image:: https://img.shields.io/lgtm/grade/python/g/vpoulailleau/python-dev-tools.svg?logo=lgtm&logoWidth=1\n :target: https://lgtm.com/projects/g/vpoulailleau/python-dev-tools/context:python\n :alt: Maintainability\n\nSupported Python versions: the same as the classic Python interpreter (CPython)\n\nDocumentation\n-------------\n\nThe full documentation can be read at https://python-dev-tools.readthedocs.io.\n\nInstallation\n------------\n\nIn a terminal, run:\n\n.. code-block:: console\n\n $ python3 -m pip install python-dev-tools --user --upgrade\n\nFull documentation on installation: https://python-dev-tools.readthedocs.io/en/latest/installation.html\n\nThat\'s it! Use the provided linter (``flake8``), formatter (``whataformatter``) and\nprecommit hook (TODO) where applicable.\n\nInstallation with Visual Studio Code\n------------------------------------\n\n* Follow the installation procedure for python-dev-tools\n* Be sure to have the official Python extension installed in VS Code\n* Open VS Code from within your activated virtual environment (in fact, make sure that \n ``flake8`` from python-dev-tools is in your ``PYTHON_PATH``)\n* In VS Code, open settings (F1 key, then type "Open Settings (JSON)",\n then enter)\n* Add in the opened JSON file (before the closing ``}``):\n\n.. code:: javascript\n\n "python.linting.enabled": true,\n "python.linting.flake8Enabled": true,\n "python.linting.flake8Path": "flake8",\n "python.formatting.provider": "black",\n "python.formatting.blackPath": "whataformatter",\n "python.formatting.blackArgs": [],\n\nFeatures\n--------\n\nIntegrate features of commonly used tools. This package provides usual\ndependencies to develop Python software.\n\n* Simple linter\n\n * ``flake8 a_python_file.py`` lints a_python_file.py\n * based on flake8 and plugins: https://gitlab.com/pycqa/flake8\n\n * darglint: https://github.com/terrencepreilly/darglint\n * dlint: https://github.com/dlint-py/dlint\n * flake8-2020: https://github.com/asottile/flake8-2020\n * flake8-annotations: https://github.com/sco1/flake8-annotations\n * flake8-annotations-complexity:\xa0https://github.com/best-doctor/flake8-annotations-complexity\n * flake8-annotations-coverage: https://github.com/best-doctor/flake8-annotations-coverage\n * flake8-bandit: https://github.com/tylerwince/flake8-bandit\n * flake8-broken-line: https://github.com/sobolevn/flake8-broken-line\n * flake8-bugbear: https://github.com/PyCQA/flake8-bugbear\n * flake8-builtins: https://github.com/gforcada/flake8-builtins\n * flake8-comprehensions: https://github.com/adamchainz/flake8-comprehensions\n * flake8-debugger: https://github.com/JBKahn/flake8-debugger\n * flake8-docstrings: https://gitlab.com/pycqa/flake8-docstrings\n * flake8-eradicate: https://github.com/sobolevn/flake8-eradicate\n * flake8-expression-complexity: https://pypi.org/project/flake8-expression-complexity/\n * flake8-fixme: https://github.com/tommilligan/flake8-fixme\n * flake8-functions: https://github.com/best-doctor/flake8-functions\n * flake8-isort: https://github.com/gforcada/flake8-isort\n * flake8-logging-format: https://github.com/globality-corp/flake8-logging-format\n * flake8-mutable: https://github.com/ebeweber/flake8-mutable\n * flake8-pytest-style: https://github.com/m-burst/flake8-pytest-style\n * flake8-quotes: https://github.com/zheller/flake8-quotes/\n * flake8-rst-docstrings: https://github.com/peterjc/flake8-rst-docstrings\n * flake8-simplify: https://github.com/MartinThoma/flake8-simplify\n * flake8-string-format: https://github.com/xZise/flake8-string-format\n * flake8-tidy-imports: https://github.com/adamchainz/flake8-tidy-imports\n * flake8-typing-imports: https://github.com/asottile/flake8-typing-imports\n * flake8-use-fstring: https://github.com/MichaelKim0407/flake8-use-fstring\n * flake8-variables-names: https://github.com/best-doctor/flake8-variables-names\n * pep8-naming: https://github.com/PyCQA/pep8-naming\n * wemake-python-styleguide: https://github.com/wemake-services/wemake-python-styleguide\n\n* Simple formatter\n\n * ``whataformatter a_python_file.py`` formats a_python_file.py\n * based on\n\n * autoflake: https://github.com/myint/autoflake\n * black: https://github.com/python/black\n * docformatter: https://github.com/PyCQA/docformatter\n * isort: https://github.com/PyCQA/isort\n * pybetter: https://github.com/lensvol/pybetter\n * pycln: https://github.com/hadialqattan/pycln\n * pyupgrade: https://github.com/asottile/pyupgrade\n * removestar: https://github.com/asmeurer/removestar\n * ssort: https://github.com/bwhmather/ssort\n\n* Simple precommit hook\n\n * TODO\n\nLicense\n-------\n\nBSD 3-Clause license, feel free to contribute: https://python-dev-tools.readthedocs.io/en/latest/contributing.html.\n\nTODO\n----\n\n* flake8 formatter to add URL to information on a warning\n* documentation\n* precommit\n\nChangelog\n---------\n\n2022.5.26\n^^^^^^^^^\n\n* Add ``docformatter`` formatter\n* Add ``isort`` formatter\n* Add ``pybetter`` formatter\n* Add ``pycln`` formatter\n* Add ``removestar`` formatter\n* Add ``ssort`` formatter\n* Remove ``cohesion`` linter (false warnings on pure data classes such as ``NamedTuple``)\n\n2022.5.20\n^^^^^^^^^\n\n* Add ``cohesion`` linter\n* Add ``dlint`` linter\n* Add ``flake8-annotations`` linter\n* Add ``flake8-annotations-complexity`` linter\n* Add ``flake8-annotations-coverage`` linter\n* Add ``flake8-black`` linter\n* Add ``flake8-expression-complexity`` linter\n* Add ``flake8-functions`` linter\n* Add ``flake8-pytest-style`` linter\n* Add ``flake8-simplify`` linter\n* Add ``flake8-tidy-imports`` linter\n* Add ``flake8-typing-imports`` linter\n* Add ``flake8-use-fstring`` linter\n* Remove ``flake8-commas`` linter that is deprecated\n* Fix ``whataformatter`` and add ``--target-version`` option for VS Code compatibility\n\n2020.9.10\n^^^^^^^^^\n\n* The path provided to ``whatalinter`` can be the one of a directory\n (recursive search of Python files)\n\n2020.9.7\n^^^^^^^^\n\n* Remove E203 in ``flake8`` for ``black`` compatibility\n\n2020.9.4\n^^^^^^^^\n\n* Add ``whatalinter_vscode`` for Visual Studio Code integration\n\n2020.9.2\n^^^^^^^^\n\n* Remove some warnings of ``wemake-python-styleguide``, for instance allow f-strings\n\n2020.9.1\n^^^^^^^^\n\n* Use ``poetry``\n* Remove redundant linters\n* Change max line length to 88 (default value of ``black``)\n* Replace ``pydocstyle`` with ``flake8-docstrings``\n* Add ``wemake-python-styleguide``\n\n2019.10.22\n^^^^^^^^^^\n\n* Add ``flake8-2020`` linter\n\n2019.07.21\n^^^^^^^^^^\n\n* Add ``--quiet`` and ``--diff`` flags to ``whataformatter`` for VS Code compatibility\n\n2019.07.20\n^^^^^^^^^^\n\n* Add ``black`` formatter\n* Add ``autoflake`` formatter\n* Add ``pyupgrade`` formatter\n\n2019.04.08\n^^^^^^^^^^\n\n* Add ``flake8`` linter\n* Add ``flake8-isort`` linter\n* Add ``pep8-naming`` linter\n* Add ``flake8-comprehensions`` linter\n* Add ``flake8-logging-format`` linter\n* Add ``flake8-bugbear`` linter\n* Add ``flake8-builtins`` linter\n* Add ``flake8-broken-line`` linter\n* Add ``flake8-fixme`` linter\n* Add ``flake8-mutable`` linter\n* Add ``flake8-debugger`` linter\n* Add ``flake8-variables-names`` linter\n* Add ``flake8-bandit`` linter\n\n2019.03.02\n^^^^^^^^^^\n\n* Add ``pydocstyle`` linter\n\n2019.03.01\n^^^^^^^^^^\n\n* Add McCabe complexity checker\n\n2019.02.26\n^^^^^^^^^^\n\n* Add ``pyflakes`` linter\n* Add ``pycodestyle`` linter\n\n2019.02.23\n^^^^^^^^^^\n\n* First release on PyPI.\n', | ||
| 'author': 'Vincent Poulailleau', | ||
@@ -78,0 +81,0 @@ 'author_email': 'vpoulailleau@gmail.com', |
| """Package.""" |
| """Autoflake formatter management.""" | ||
| from python_dev_tools.formatters.common import Formatter | ||
| class AutoflakeFormatter(Formatter): | ||
| """Autoflake formatter management.""" | ||
| name = "autoflake" | ||
| path = "autoflake" | ||
| cli_args = ["--in-place", "--remove-unused-variables"] |
| """Black formatter management.""" | ||
| from python_dev_tools.formatters.common import Formatter | ||
| class BlackFormatter(Formatter): | ||
| """Black formatter management.""" | ||
| name = "black" | ||
| path = "black" | ||
| cli_args = ["--target-version=py37"] |
| """Common constants and class to all linters.""" | ||
| import subprocess # noqa: S404 | ||
| from typing import List | ||
| class FormatterNotFound(FileNotFoundError): | ||
| """ | ||
| Exception to detect that a formatter is not found. | ||
| Note that this doesn't occur, except due to an installation error. | ||
| """ | ||
| class Formatter: | ||
| """Base formatter class.""" | ||
| name = "Formatter" | ||
| path = "/bin/unknownformatter" | ||
| cli_args = [] | ||
| @classmethod | ||
| def format_file(cls, filepath: str) -> None: | ||
| """Execute the formatter. | ||
| Args: | ||
| filepath (str): path of the file to format | ||
| """ | ||
| try: | ||
| cls._format_file(filepath) | ||
| except FormatterNotFound: | ||
| print(f"Formatter {cls.name} not found: {cls.path}") | ||
| @classmethod | ||
| def _format_file(cls, filepath: str): | ||
| args = [cls.path, *cls.cli_args, filepath] | ||
| cls._execute_command(args) | ||
| @classmethod | ||
| def _execute_command(cls, args: List[str]) -> subprocess.CompletedProcess: | ||
| """Execute the formatter. | ||
| Args: | ||
| args (list[str]): arguments of the command including command name | ||
| Raises: | ||
| FormatterNotFound: formatter ``cls.path`` not found in path | ||
| Returns: | ||
| CompletedProcess: result of the execution | ||
| """ | ||
| try: | ||
| return subprocess.run( # noqa: S603 | ||
| args, | ||
| stdout=subprocess.PIPE, | ||
| stderr=subprocess.PIPE, | ||
| timeout=10, | ||
| encoding="utf-8", | ||
| ) | ||
| except FileNotFoundError as exc: | ||
| if exc.filename == cls.path: | ||
| raise FormatterNotFound | ||
| raise |
| """Definition of format function, calling all formatters.""" | ||
| from typing import List | ||
| from python_dev_tools.formatters.autoflake import AutoflakeFormatter | ||
| from python_dev_tools.formatters.black import BlackFormatter | ||
| from python_dev_tools.formatters.common import Formatter | ||
| from python_dev_tools.formatters.pyupgrade import PyupgradeFormatter | ||
| formatters: List[Formatter] = [ | ||
| AutoflakeFormatter, | ||
| PyupgradeFormatter, | ||
| BlackFormatter, # BlackFormatter should be the last one | ||
| ] | ||
| def format_file(filepath: str) -> None: | ||
| """Format the file with known formatters. | ||
| Args: | ||
| filepath (str): path of the file to format | ||
| """ | ||
| for formatter in formatters: | ||
| formatter.format_file(filepath) |
| """Pyupgrade formatter management.""" | ||
| from python_dev_tools.formatters.common import Formatter | ||
| class PyupgradeFormatter(Formatter): | ||
| """Pyupgrade formatter management.""" | ||
| name = "pyupgrade" | ||
| path = "pyupgrade" | ||
| cli_args = ["--py37-plus"] |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
42881
3.94%8
-42.86%287
-3.04%