Skip to content

Commit

Permalink
Merge pull request #546 from hhatto/support-toml
Browse files Browse the repository at this point in the history
Support compatible TOML format with pyproject.toml
  • Loading branch information
hhatto authored May 25, 2020
2 parents 047376a + 7113771 commit 20f8a41
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 33 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ configuration file example::

[tool.autopep8]
max_line_length = 120
ignore = E501
ignore = "E501,W6" # or ["E501", "W6"]


Testing
Expand Down
74 changes: 46 additions & 28 deletions autopep8.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class documentation for more information.
from ConfigParser import SafeConfigParser
from ConfigParser import Error

import toml
import pycodestyle
from pycodestyle import STARTSWITH_INDENT_STATEMENT_REGEX

Expand Down Expand Up @@ -3756,7 +3757,10 @@ def parse_args(arguments, apply_config=False):
if apply_config:
parser = read_config(args, parser)
# prioritize settings when exist pyproject.toml's tool.autopep8 section
parser_with_pyproject_toml = read_pyproject_toml(args, parser)
try:
parser_with_pyproject_toml = read_pyproject_toml(args, parser)
except Exception:
parser_with_pyproject_toml = None
if parser_with_pyproject_toml:
parser = parser_with_pyproject_toml
args = parser.parse_args(arguments)
Expand Down Expand Up @@ -3891,38 +3895,52 @@ def read_config(args, parser):

def read_pyproject_toml(args, parser):
"""Read pyproject.toml and load configuration."""
config = SafeConfigParser()
config = None

if os.path.exists(args.global_config):
with open(args.global_config) as fp:
config = toml.load(fp)

if not args.ignore_local_config:
parent = tail = args.files and os.path.abspath(
os.path.commonprefix(args.files))
while tail:
pyproject_toml = os.path.join(parent, "pyproject.toml")
if os.path.exists(pyproject_toml):
with open(pyproject_toml) as fp:
config = toml.load(fp)
break
(parent, tail) = os.path.split(parent)

try:
config.read(args.global_config)
if not config:
return None

if not args.ignore_local_config:
parent = tail = args.files and os.path.abspath(
os.path.commonprefix(args.files))
while tail:
if config.read([os.path.join(parent, "pyproject.toml"), ]):
break
(parent, tail) = os.path.split(parent)
if config.get("tool", {}).get("autopep8") is None:
return None

defaults = {}
option_list = {o.dest: o.type or type(o.default)
for o in parser._actions}
config = config.get("tool").get("autopep8")

for section in ["tool.autopep8"]:
if not config.has_section(section):
continue
for norm_opt, k, value in _get_normalize_options(config, section,
option_list):
if args.verbose:
print("enable pyproject.toml config: section={}, "
"key={}, value={}".format(section, k, value))
defaults[norm_opt] = value
defaults = {}
option_list = {o.dest: o.type or type(o.default)
for o in parser._actions}

if defaults:
# set value when exists key-value in defaults dict
parser.set_defaults(**defaults)
except Error:
return None
TUPLED_OPTIONS = ("ignore", "select")
for (k, v) in config.items():
norm_opt = k.lstrip('-').replace('-', '_')
if not option_list.get(norm_opt):
continue
if type(v) in (list, tuple) and norm_opt in TUPLED_OPTIONS:
value = ",".join(v)
else:
value = v
if args.verbose:
print("enable pyproject.toml config: "
"key={}, value={}".format(k, value))
defaults[norm_opt] = value

if defaults:
# set value when exists key-value in defaults dict
parser.set_defaults(**defaults)

return parser

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


INSTALL_REQUIRES = (
['pycodestyle == 2.5.0']
['pycodestyle == 2.5.0', 'toml']
)


Expand Down
20 changes: 17 additions & 3 deletions test/test_autopep8.py
Original file line number Diff line number Diff line change
Expand Up @@ -5751,7 +5751,7 @@ def test_pyproject_toml_with_flake8_config(self):
"""override to flake8 config"""
line = "a = 1\n"
dot_flake8 = """[pep8]\naggressive=0\n"""
pyproject_toml = """[tool.autopep8]\naggressvie=2\nignore=E,W\n"""
pyproject_toml = """[tool.autopep8]\naggressvie=2\nignore="E,W"\n"""
with temporary_project_directory() as dirname:
with open(os.path.join(dirname, "pyproject.toml"), "w") as fp:
fp.write(pyproject_toml)
Expand All @@ -5767,8 +5767,8 @@ def test_pyproject_toml_with_flake8_config(self):
def test_pyproject_toml_with_verbose_option(self):
"""override to flake8 config"""
line = "a = 1\n"
verbose_line = "enable pyproject.toml config: section=tool.autopep8, key=ignore, value=E,W\n"
pyproject_toml = """[tool.autopep8]\naggressvie=2\nignore=E,W\n"""
verbose_line = "enable pyproject.toml config: key=ignore, value=E,W\n"
pyproject_toml = """[tool.autopep8]\naggressvie=2\nignore="E,W"\n"""
with temporary_project_directory() as dirname:
with open(os.path.join(dirname, "pyproject.toml"), "w") as fp:
fp.write(pyproject_toml)
Expand All @@ -5781,6 +5781,20 @@ def test_pyproject_toml_with_verbose_option(self):
self.assertTrue(verbose_line in output)
self.assertEqual(p.returncode, 0)

def test_pyproject_toml_with_iterable_value(self):
line = "a = 1\n"
pyproject_toml = """[tool.autopep8]\naggressvie=2\nignore=["E","W"]\n"""
with temporary_project_directory() as dirname:
with open(os.path.join(dirname, "pyproject.toml"), "w") as fp:
fp.write(pyproject_toml)
target_filename = os.path.join(dirname, "foo.py")
with open(target_filename, "w") as fp:
fp.write(line)
p = Popen(list(AUTOPEP8_CMD_TUPLE) + [target_filename, ], stdout=PIPE)
output = p.communicate()[0].decode("utf-8")
self.assertTrue(line in output)
self.assertEqual(p.returncode, 0)


class ExperimentalSystemTests(unittest.TestCase):

Expand Down

0 comments on commit 20f8a41

Please sign in to comment.