diff --git a/README.rst b/README.rst index c71b933e..b2ae323d 100644 --- a/README.rst +++ b/README.rst @@ -56,6 +56,14 @@ You can install, upgrade, and uninstall ``pycodestyle.py`` with these commands:: There's also a package for Debian/Ubuntu, but it's not always the latest version. +If you want to use a PEP518 compliant ``pyproject.toml`` for configuration you must +install the pep518 extra:: + + $ pip install pycodestyle[pep518] + +In this case, you can add a ``[tool.pycodestyle]`` configuration section in your +``pyproject.toml`` file instead of using ``tox.ini`` or ``setup.cfg``. + Example usage and output ------------------------ diff --git a/pycodestyle.py b/pycodestyle.py index 0d8ed50f..d704427d 100755 --- a/pycodestyle.py +++ b/pycodestyle.py @@ -78,6 +78,13 @@ def lru_cache(maxsize=128): # noqa as it's a fake implementation. except ImportError: from ConfigParser import RawConfigParser +try: + from toml import load as load_toml_from_file +except ImportError: + _IS_TOML_AVAILABLE = False +else: + _IS_TOML_AVAILABLE = True + # this is a performance hack. see https://bugs.python.org/issue43014 if ( sys.version_info < (3, 10) and @@ -101,6 +108,8 @@ def lru_cache(maxsize=128): # noqa as it's a fake implementation. USER_CONFIG = None PROJECT_CONFIG = ('setup.cfg', 'tox.ini') +PY_PROJECT_TOML_CONFIG = 'pyproject.toml' +PY_PROJECT_TOML_TOOL_SECTION = 'tool' TESTSUITE_PATH = os.path.join(os.path.dirname(__file__), 'testsuite') MAX_LINE_LENGTH = 79 # Number of blank lines between various code parts. @@ -2653,7 +2662,20 @@ def read_config(options, args, arglist, parser): parent = tail = args and os.path.abspath(os.path.commonprefix(args)) while tail: - if config.read(os.path.join(parent, fn) for fn in PROJECT_CONFIG): + py_project_file = os.path.join(parent, PY_PROJECT_TOML_CONFIG) + if _IS_TOML_AVAILABLE is True and os.path.exists(py_project_file): + config_dict = load_toml_from_file(py_project_file) + if PY_PROJECT_TOML_TOOL_SECTION in config_dict.keys(): + tool_section = config_dict[PY_PROJECT_TOML_TOOL_SECTION] + if parser.prog in tool_section.keys(): + prog_config = tool_section[parser.prog] + prog_config = {parser.prog: prog_config} + config.read_dict(prog_config) + local_dir = parent + if options.verbose: + print('local configuration from pyproject: in %s' % parent) + break + elif config.read(os.path.join(parent, fn) for fn in PROJECT_CONFIG): local_dir = parent if options.verbose: print('local configuration: in %s' % parent) diff --git a/setup.py b/setup.py index 148751bc..6964a5c4 100644 --- a/setup.py +++ b/setup.py @@ -39,6 +39,9 @@ def get_long_description(): # Broken with Python 3: https://github.com/pypa/pip/issues/650 # 'setuptools', ], + extras_require={ + 'pep518': ['toml>=0.10.2'] + }, entry_points={ 'console_scripts': [ 'pycodestyle = pycodestyle:_main',