1# Copyright 2016 Christoph Reiter
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7
8import itertools
9from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
10
11import pytest
12
13from quodlibet.util import is_wine
14
15from tests import TestCase
16from tests.helper import capture_output
17
18from .util import iter_project_py_files, setup_cfg
19
20try:
21    import pycodestyle
22except ImportError:
23    try:
24        import pep8 as pycodestyle
25    except ImportError:
26        pycodestyle = None
27
28
29def create_pool():
30    if is_wine():
31        # ProcessPoolExecutor is broken under wine
32        return ThreadPoolExecutor(1)
33    else:
34        return ProcessPoolExecutor(None)
35
36
37def _check_file(f, ignore):
38    style = pycodestyle.StyleGuide(ignore=ignore)
39    with capture_output() as (o, e):
40        style.check_files([f])
41    return o.getvalue().splitlines()
42
43
44def check_files(files, ignore=[]):
45    lines = []
46    with create_pool() as pool:
47        for res in pool.map(_check_file, files, itertools.repeat(ignore)):
48            lines.extend(res)
49    return sorted(lines)
50
51
52@pytest.mark.quality
53class TPEP8(TestCase):
54    def test_all(self):
55        assert pycodestyle is not None, "pycodestyle/pep8 is missing"
56
57        files = iter_project_py_files()
58        errors = check_files(files, ignore=setup_cfg.ignore)
59        if errors:
60            raise Exception("\n".join(errors))
61