Repository: facebookincubator/ptr

Issue:
Add MacOS X CI
Lets add MacOS X CI runs to ensure not Apple / Mac *features* cause `ptr` any pain :)

Discussion:

Patch:
diff --git a/.pylint b/.pylint
deleted file mode 100644
index 7d64a88..0000000
--- a/.pylint
+++ /dev/null
@@ -1,553 +0,0 @@
-[MASTER]
-
-# A comma-separated list of package or module names from where C extensions may
-# be loaded. Extensions are loading into the active Python interpreter and may
-# run arbitrary code
-extension-pkg-whitelist=
-
-# Add files or directories to the blacklist. They should be base names, not
-# paths.
-ignore=CVS
-
-# Add files or directories matching the regex patterns to the blacklist. The
-# regex matches against base names, not paths.
-ignore-patterns=
-
-# Python code to execute, usually for sys.path manipulation such as
-# pygtk.require().
-#init-hook=
-
-# Use multiple processes to speed up Pylint.
-jobs=1
-
-# List of plugins (as comma separated values of python modules names) to load,
-# usually to register additional checkers.
-load-plugins=
-
-# Pickle collected data for later comparisons.
-persistent=yes
-
-# Specify a configuration file.
-#rcfile=
-
-# When enabled, pylint would attempt to guess common misconfiguration and emit
-# user-friendly hints instead of false-positive error messages
-suggestion-mode=yes
-
-# Allow loading of arbitrary C extensions. Extensions are imported into the
-# active Python interpreter and may run arbitrary code.
-unsafe-load-any-extension=no
-
-
-[MESSAGES CONTROL]
-
-# Only show warnings with the listed confidence levels. Leave empty to show
-# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
-confidence=
-
-# Disable the message, report, category or checker with the given id(s). You
-# can either give multiple identifiers separated by comma (,) or put this
-# option multiple times (only on the command line, not in the configuration
-# file where it should appear only once).You can also use "--disable=all" to
-# disable everything first and then reenable specific checks. For example, if
-# you want to run only the similarities checker, you can use "--disable=all
-# --enable=similarities". If you want to run only the classes checker, but have
-# no Warning level messages displayed, use"--disable=all --enable=classes
-# --disable=W"
-disable=print-statement,
-        parameter-unpacking,
-        unpacking-in-except,
-        old-raise-syntax,
-        backtick,
-        long-suffix,
-        old-ne-operator,
-        old-octal-literal,
-        import-star-module-level,
-        non-ascii-bytes-literal,
-        raw-checker-failed,
-        bad-inline-option,
-        locally-disabled,
-        locally-enabled,
-        file-ignored,
-        suppressed-message,
-        useless-suppression,
-        deprecated-pragma,
-        apply-builtin,
-        basestring-builtin,
-        buffer-builtin,
-        cmp-builtin,
-        coerce-builtin,
-        execfile-builtin,
-        file-builtin,
-        long-builtin,
-        raw_input-builtin,
-        reduce-builtin,
-        standarderror-builtin,
-        unicode-builtin,
-        xrange-builtin,
-        coerce-method,
-        delslice-method,
-        getslice-method,
-        setslice-method,
-        no-absolute-import,
-        old-division,
-        dict-iter-method,
-        dict-view-method,
-        next-method-called,
-        metaclass-assignment,
-        indexing-exception,
-        raising-string,
-        reload-builtin,
-        oct-method,
-        hex-method,
-        nonzero-method,
-        cmp-method,
-        input-builtin,
-        round-builtin,
-        intern-builtin,
-        unichr-builtin,
-        map-builtin-not-iterating,
-        zip-builtin-not-iterating,
-        range-builtin-not-iterating,
-        filter-builtin-not-iterating,
-        using-cmp-argument,
-        eq-without-hash,
-        div-method,
-        idiv-method,
-        rdiv-method,
-        exception-message-attribute,
-        invalid-str-codec,
-        sys-max-int,
-        bad-python3-import,
-        deprecated-string-function,
-        deprecated-str-translate-call,
-        deprecated-itertools-function,
-        deprecated-types-field,
-        next-method-defined,
-        dict-items-not-iterating,
-        dict-keys-not-iterating,
-        dict-values-not-iterating,
-        missing-docstring,
-        bad-continuation,
-        global-statement,
-        invalid-name,
-        duplicate-code,
-		unused-argument,
-		missing-docstring,
-		function-redefined,
-        too-many-public-methods,
-        protected-access,
-        logging-format-interpolation,
-        no-self-use,
-        ungrouped-imports,
-        fixme
-
-# Enable the message, report, category or checker with the given id(s). You can
-# either give multiple identifier separated by comma (,) or put this option
-# multiple time (only on the command line, not in the configuration file where
-# it should appear only once). See also the "--disable" option for examples.
-enable=c-extension-no-member
-
-
-[REPORTS]
-
-# Python expression which should return a note less than 10 (10 is the highest
-# note). You have access to the variables errors warning, statement which
-# respectively contain the number of errors / warnings messages and the total
-# number of statements analyzed. This is used by the global evaluation report
-# (RP0004).
-evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
-
-# Template used to display messages. This is a python new-style format string
-# used to format the message information. See doc for all details
-#msg-template=
-
-# Set the output format. Available formats are text, parseable, colorized, json
-# and msvs (visual studio).You can also give a reporter class, eg
-# mypackage.mymodule.MyReporterClass.
-output-format=text
-
-# Tells whether to display a full report or only the messages
-reports=no
-
-# Activate the evaluation score.
-score=no
-
-
-[REFACTORING]
-
-# Maximum number of nested blocks for function / method body
-max-nested-blocks=6
-
-# Complete name of functions that never returns. When checking for
-# inconsistent-return-statements if a never returning function is called then
-# it will be considered as an explicit return statement and no message will be
-# printed.
-never-returning-functions=optparse.Values,sys.exit
-
-
-[LOGGING]
-
-# Logging modules to check that the string format arguments are in logging
-# function parameter format
-logging-modules=logging
-
-
-[SPELLING]
-
-# Limits count of emitted suggestions for spelling mistakes
-max-spelling-suggestions=4
-
-# Spelling dictionary name. Available dictionaries: none. To make it working
-# install python-enchant package.
-spelling-dict=
-
-# List of comma separated words that should not be checked.
-spelling-ignore-words=
-
-# A path to a file that contains private dictionary; one word per line.
-spelling-private-dict-file=
-
-# Tells whether to store unknown words to indicated private dictionary in
-# --spelling-private-dict-file option instead of raising a message.
-spelling-store-unknown-words=no
-
-
-[MISCELLANEOUS]
-
-# List of note tags to take in consideration, separated by a comma.
-notes=FIXME,
-      XXX,
-      TODO
-
-
-[TYPECHECK]
-
-# List of decorators that produce context managers, such as
-# contextlib.contextmanager. Add to this list to register other decorators that
-# produce valid context managers.
-contextmanager-decorators=contextlib.contextmanager
-
-# List of members which are set dynamically and missed by pylint inference
-# system, and so shouldn't trigger E1101 when accessed. Python regular
-# expressions are accepted.
-generated-members=
-
-# Tells whether missing members accessed in mixin class should be ignored. A
-# mixin class is detected if its name ends with "mixin" (case insensitive).
-ignore-mixin-members=yes
-
-# This flag controls whether pylint should warn about no-member and similar
-# checks whenever an opaque object is returned when inferring. The inference
-# can return multiple potential results while evaluating a Python object, but
-# some branches might not be evaluated, which results in partial inference. In
-# that case, it might be useful to still emit no-member and other checks for
-# the rest of the inferred objects.
-ignore-on-opaque-inference=yes
-
-# List of class names for which member attributes should not be checked (useful
-# for classes with dynamically set attributes). This supports the use of
-# qualified names.
-ignored-classes=optparse.Values,thread._local,_thread._local
-
-# List of module names for which member attributes should not be checked
-# (useful for modules/projects where namespaces are manipulated during runtime
-# and thus existing member attributes cannot be deduced by static analysis. It
-# supports qualified module names, as well as Unix pattern matching.
-ignored-modules=
-
-# Show a hint with possible names when a member name was not found. The aspect
-# of finding the hint is based on edit distance.
-missing-member-hint=yes
-
-# The minimum edit distance a name should have in order to be considered a
-# similar match for a missing member name.
-missing-member-hint-distance=1
-
-# The total number of similar names that should be taken in consideration when
-# showing a hint for a missing member.
-missing-member-max-choices=1
-
-
-[VARIABLES]
-
-# List of additional names supposed to be defined in builtins. Remember that
-# you should avoid to define new builtins when possible.
-additional-builtins=
-
-# Tells whether unused global variables should be treated as a violation.
-allow-global-unused-variables=yes
-
-# List of strings which can identify a callback function by name. A callback
-# name must start or end with one of those strings.
-callbacks=cb_,
-          _cb
-
-# A regular expression matching the name of dummy variables (i.e. expectedly
-# not used).
-dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
-
-# Argument names that match this expression will be ignored. Default to name
-# with leading underscore
-ignored-argument-names=_.*|^ignored_|^unused_
-
-# Tells whether we should check for unused import in __init__ files.
-init-import=no
-
-# List of qualified module names which can have objects that can redefine
-# builtins.
-redefining-builtins-modules=six.moves,past.builtins,future.builtins
-
-
-[FORMAT]
-
-# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
-expected-line-ending-format=LF
-
-# Regexp for a line that is allowed to be longer than the limit.
-ignore-long-lines=^\s*(# )?<?https?://\S+>?$
-
-# Number of spaces of indent required inside a hanging  or continued line.
-indent-after-paren=4
-
-# String used as indentation unit. This is usually "    " (4 spaces) or "\t" (1
-# tab).
-indent-string='    '
-
-# Maximum number of characters on a single line.
-max-line-length=90
-
-# Maximum number of lines in a module
-max-module-lines=2000
-
-# List of optional constructs for which whitespace checking is disabled. `dict-
-# separator` is used to allow tabulation in dicts, etc.: {1  : 1,\n222: 2}.
-# `trailing-comma` allows a space between comma and closing bracket: (a, ).
-# `empty-line` allows space-only lines.
-no-space-check=trailing-comma,
-               dict-separator
-
-# Allow the body of a class to be on the same line as the declaration if body
-# contains single statement.
-single-line-class-stmt=no
-
-# Allow the body of an if to be on the same line as the test if there is no
-# else.
-single-line-if-stmt=no
-
-
-[SIMILARITIES]
-
-# Ignore comments when computing similarities.
-ignore-comments=yes
-
-# Ignore docstrings when computing similarities.
-ignore-docstrings=yes
-
-# Ignore imports when computing similarities.
-ignore-imports=no
-
-# Minimum lines number of a similarity.
-min-similarity-lines=4
-
-
-[BASIC]
-
-# Naming style matching correct argument names
-argument-naming-style=snake_case
-
-# Regular expression matching correct argument names. Overrides argument-
-# naming-style
-#argument-rgx=
-
-# Naming style matching correct attribute names
-attr-naming-style=snake_case
-
-# Regular expression matching correct attribute names. Overrides attr-naming-
-# style
-#attr-rgx=
-
-# Bad variable names which should always be refused, separated by a comma
-bad-names=foo,
-          bar,
-          baz,
-          toto,
-          tutu,
-          tata
-
-# Naming style matching correct class attribute names
-class-attribute-naming-style=any
-
-# Regular expression matching correct class attribute names. Overrides class-
-# attribute-naming-style
-#class-attribute-rgx=
-
-# Naming style matching correct class names
-class-naming-style=PascalCase
-
-# Regular expression matching correct class names. Overrides class-naming-style
-#class-rgx=
-
-# Naming style matching correct constant names
-const-naming-style=UPPER_CASE
-
-# Regular expression matching correct constant names. Overrides const-naming-
-# style
-#const-rgx=
-
-# Minimum line length for functions/classes that require docstrings, shorter
-# ones are exempt.
-docstring-min-length=-1
-
-# Naming style matching correct function names
-function-naming-style=snake_case
-
-# Regular expression matching correct function names. Overrides function-
-# naming-style
-#function-rgx=
-
-# Good variable names which should always be accepted, separated by a comma
-good-names=i,
-           j,
-           k,
-           ex,
-           Run,
-           _
-
-# Include a hint for the correct naming format with invalid-name
-include-naming-hint=no
-
-# Naming style matching correct inline iteration names
-inlinevar-naming-style=any
-
-# Regular expression matching correct inline iteration names. Overrides
-# inlinevar-naming-style
-#inlinevar-rgx=
-
-# Naming style matching correct method names
-method-naming-style=snake_case
-
-# Regular expression matching correct method names. Overrides method-naming-
-# style
-#method-rgx=
-
-# Naming style matching correct module names
-module-naming-style=snake_case
-
-# Regular expression matching correct module names. Overrides module-naming-
-# style
-#module-rgx=
-
-# Colon-delimited sets of names that determine each other's naming style when
-# the name regexes allow several styles.
-name-group=
-
-# Regular expression which should only match function or class names that do
-# not require a docstring.
-no-docstring-rgx=^_
-
-# List of decorators that produce properties, such as abc.abstractproperty. Add
-# to this list to register other decorators that produce valid properties.
-property-classes=abc.abstractproperty
-
-# Naming style matching correct variable names
-variable-naming-style=snake_case
-
-# Regular expression matching correct variable names. Overrides variable-
-# naming-style
-#variable-rgx=
-
-
-[IMPORTS]
-
-# Allow wildcard imports from modules that define __all__.
-allow-wildcard-with-all=no
-
-# Analyse import fallback blocks. This can be used to support both Python 2 and
-# 3 compatible code, which means that the block might have code that exists
-# only in one or another interpreter, leading to false positives when analysed.
-analyse-fallback-blocks=no
-
-# Deprecated modules which should not be used, separated by a comma
-deprecated-modules=optparse,tkinter.tix
-
-# Create a graph of external dependencies in the given file (report RP0402 must
-# not be disabled)
-ext-import-graph=
-
-# Create a graph of every (i.e. internal and external) dependencies in the
-# given file (report RP0402 must not be disabled)
-import-graph=
-
-# Create a graph of internal dependencies in the given file (report RP0402 must
-# not be disabled)
-int-import-graph=
-
-# Force import order to recognize a module as part of the standard
-# compatibility libraries.
-known-standard-library=
-
-# Force import order to recognize a module as part of a third party library.
-known-third-party=enchant
-
-
-[CLASSES]
-
-# List of method names used to declare (i.e. assign) instance attributes.
-defining-attr-methods=__init__,
-                      __new__,
-                      setUp
-
-# List of member names, which should be excluded from the protected access
-# warning.
-exclude-protected=_asdict,
-                  _fields,
-                  _replace,
-                  _source,
-                  _make
-
-# List of valid names for the first argument in a class method.
-valid-classmethod-first-arg=cls
-
-# List of valid names for the first argument in a metaclass class method.
-valid-metaclass-classmethod-first-arg=mcs
-
-
-[DESIGN]
-
-# Maximum number of arguments for function / method
-max-args=10
-
-# Maximum number of attributes for a class (see R0902).
-max-attributes=8
-
-# Maximum number of boolean expressions in a if statement
-max-bool-expr=5
-
-# Maximum number of branch for function / method body
-max-branches=20
-
-# Maximum number of locals for function / method body
-max-locals=28
-
-# Maximum number of parents for a class (see R0901).
-max-parents=7
-
-# Maximum number of public methods for a class (see R0904).
-max-public-methods=20
-
-# Maximum number of return / yield for function / method body
-max-returns=6
-
-# Maximum number of statements in function / method body
-max-statements=50
-
-# Minimum number of public methods for a class (see R0903).
-min-public-methods=1
-
-
-[EXCEPTIONS]
-
-# Exceptions that will emit a warning when being caught. Defaults to
-# "Exception"
-overgeneral-exceptions=Exception
diff --git a/ci.py b/ci.py
index 0f62dab..d64ab24 100644
--- a/ci.py
+++ b/ci.py
@@ -14,7 +14,7 @@ import json
 from os import environ
 from pathlib import Path
 from subprocess import PIPE, run
-from sys import stderr
+from sys import exit, stderr
 from tempfile import gettempdir
 
 
@@ -27,6 +27,9 @@ def check_ptr_stats_json(stats_file: Path) -> int:
         print("Stats JSON Error: {}".format(jde))
         return 69
 
+    # Lets always print JSON to help debug any failures and have JSON history
+    print(json.dumps(stats_json, indent=2, sort_keys=True))
+
     any_fail = int(stats_json["total.fails"]) + int(stats_json["total.timeouts"])
     if any_fail:
         print("Stats report {} fails/timeouts".format(any_fail), file=stderr)
@@ -40,11 +43,17 @@ def check_ptr_stats_json(stats_file: Path) -> int:
         print("We didn't test all setup.py files ...", file=stderr)
         stats_errors += 1
 
-    if "suite.ptr_coverage.file.ptr.py" not in stats_json:
-        print("We didn't get any coverage stats for ptr.py", file=stderr)
+    # TODO: Make getting project name better - For now quick CI hack
+    coverage_key_count = 0
+    for key in stats_json.keys():
+        if "_coverage." in key:
+            coverage_key_count += 1
+    if coverage_key_count != 4:
+        print("We didn't get coverage stats for all ptr files + total", file=stderr)
         stats_errors += 1
 
-    print("Stats check found {} errors".format(stats_errors))
+    print("Stats check found {} error(s)".format(stats_errors))
+
     return stats_errors
 
 
@@ -53,18 +62,11 @@ def integration_test() -> int:
     print("Running `ptr` integration tests (aka run itself)", file=stderr)
 
     stats_file = Path(gettempdir()) / "ptr_ci_stats"
-    cp = run(
-        (
-            "python",
-            "ptr.py",
-            "-d",
-            "--print-cov",
-            "--stats-file",
-            str(stats_file),
-            "--venv",
-            environ["VIRTUAL_ENV"],
-        )
-    )
+    ci_cmd = ["python", "ptr.py", "-d", "--print-cov", "--stats-file", str(stats_file)]
+    if "VIRTUAL_ENV" in environ:
+        ci_cmd.extend(["--venv", environ["VIRTUAL_ENV"]])
+
+    cp = run(ci_cmd)
     return cp.returncode + check_ptr_stats_json(stats_file)
 
 
diff --git a/ptr.py b/ptr.py
index f739409..79ae6b7 100755
--- a/ptr.py
+++ b/ptr.py
@@ -72,8 +72,6 @@ class StepName(Enum):
     analyze_coverage = 3
     mypy_run = 4
     black_run = 5
-    pylint_run = 6
-    flake8_run = 7
 
 
 coverage_line = namedtuple("coverage_line", ["stmts", "miss", "cover", "missing"])
@@ -222,7 +220,7 @@ def _generate_install_cmd(
 def _generate_mypy_cmd(
     module_dir: Path, mypy_exe: Path, config: Dict
 ) -> Tuple[str, ...]:
-    if config.get("run_mypy", False):
+    if config["run_mypy"]:
         mypy_entry_point = module_dir / "{}.py".format(config["entry_point_module"])
     else:
         return ()
@@ -235,38 +233,6 @@ def _generate_mypy_cmd(
     return tuple(cmds)
 
 
-def _generate_flake8_cmd(
-    module_dir: Path, flake8_exe: Path, config: Dict
-) -> Tuple[str, ...]:
-    if not config.get("run_flake8", False):
-        return ()
-
-    py_files = set()  # type: Set[str]
-    find_py_files(py_files, module_dir)
-
-    cmds = [str(flake8_exe)]
-    flake8_config = module_dir / ".flake8"
-    if flake8_config.exists():
-        cmds.extend(["--config", str(flake8_config)])
-    return (*cmds, *sorted(py_files))
-
-
-def _generate_pylint_cmd(
-    module_dir: Path, pylint_exe: Path, config: Dict
-) -> Tuple[str, ...]:
-    if not config.get("run_pylint", False):
-        return ()
-
-    py_files = set()  # type: Set[str]
-    find_py_files(py_files, module_dir)
-
-    cmds = [str(pylint_exe)]
-    pylint_config = module_dir / ".pylint"
-    if pylint_config.exists():
-        cmds.extend(["--rcfile", str(pylint_config)])
-    return (*cmds, *sorted(py_files))
-
-
 def _get_test_modules(base_path: Path, stats: Dict[str, int]) -> Dict[Path, Dict]:
     get_tests_start_time = time()
     all_setup_pys = find_setup_pys(
@@ -418,10 +384,8 @@ async def _test_steps_runner(
 ) -> Tuple[Optional[test_result], int]:
     black_exe = venv_path / "bin" / "black"
     coverage_exe = venv_path / "bin" / "coverage"
-    flake8_exe = venv_path / "bin" / "flake8"
     mypy_exe = venv_path / "bin" / "mypy"
     pip_exe = venv_path / "bin" / "pip"
-    pylint_exe = venv_path / "bin" / "pylint"
     config = tests_to_run[setup_py_path]
     setup_py_parent_path = setup_py_path.parent
     # For running unit tests via coverage in the venv
@@ -469,20 +433,6 @@ async def _test_steps_runner(
             "Running black for {}".format(setup_py_path),
             config["test_suite_timeout"],
         ),
-        step(
-            StepName.flake8_run,
-            bool("run_flake8" in config and config["run_flake8"]),
-            _generate_flake8_cmd(setup_py_path.parent, flake8_exe, config),
-            "Running flake8 for {}".format(setup_py_path),
-            config["test_suite_timeout"],
-        ),
-        step(
-            StepName.pylint_run,
-            bool("run_pylint" in config and config["run_pylint"]),
-            _generate_pylint_cmd(setup_py_path.parent, pylint_exe, config),
-            "Running pylint for {}".format(setup_py_path),
-            config["test_suite_timeout"],
-        ),
     )
 
     steps_ran = 0
@@ -503,17 +453,13 @@ async def _test_steps_runner(
         try:
             if a_step.cmds:
                 LOG.debug("CMD: {}".format(" ".join(a_step.cmds)))
-                stdout, _stderr = await _gen_check_output(
+                stdout, stderr = await _gen_check_output(
                     a_step.cmds, a_step.timeout, env=env
                 )
             else:
                 LOG.debug("Skipping running a cmd for {} step".format(a_step))
         except CalledProcessError as cpe:
-            if a_step.step_name in {
-                StepName.mypy_run,
-                StepName.flake8_run,
-                StepName.pylint_run,
-            }:
+            if a_step.step_name in {StepName.mypy_run}:
                 err_output = cpe.stdout.decode("utf-8")
             else:
                 err_output = cpe.stderr.decode("utf-8")
diff --git a/ptrconfig.sample b/ptrconfig.sample
index 4fdfb86..06bafa4 100644
--- a/ptrconfig.sample
+++ b/ptrconfig.sample
@@ -8,8 +8,6 @@ pypi_url = https://pypi.org/simple/
 venv_pkgs =
   black
   coverage
-  flake8
   mypy
   pip
-  pylint
   setuptools
diff --git a/requirements.txt b/requirements.txt
index 35d3d87..28d93b8 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,7 +1,5 @@
 black
 coverage
-flake8
 mypy
 pip
-pylint
 setuptools
diff --git a/setup.cfg.sample b/setup.cfg.sample
index 56ff149..1940e25 100644
--- a/setup.cfg.sample
+++ b/setup.cfg.sample
@@ -7,5 +7,3 @@ required_coverage_ptr.py = 84
 required_coverage_TOTAL = 90
 run_black = true
 run_mypy = true
-run_flake8 = true
-run_pylint = true
diff --git a/setup.py b/setup.py
index 271662e..df28c69 100644
--- a/setup.py
+++ b/setup.py
@@ -21,10 +21,6 @@ ptr_params = {
     "run_black": True,
     # Run mypy or not
     "run_mypy": True,
-    # Run flake8 or not
-    "run_flake8": True,
-    # Run pylint or not
-    "run_pylint": True,
 }
 
 


Test patch:
diff --git a/ptr_tests.py b/ptr_tests.py
index a2ba285..f262c37 100644
--- a/ptr_tests.py
+++ b/ptr_tests.py
@@ -15,13 +15,7 @@ from platform import system
 from shutil import rmtree
 from subprocess import CalledProcessError
 from tempfile import TemporaryDirectory, gettempdir
-from typing import (  # noqa: F401 # pylint: disable=unused-import
-    Any,
-    Dict,
-    List,
-    Optional,
-    Tuple,
-)
+from typing import Any, Dict, List, Optional, Tuple  # noqa: F401
 from unittest.mock import Mock, patch
 
 import ptr
@@ -60,12 +54,6 @@ def return_specific_tmp(*args: Any, **kwargs: Any) -> str:
     return "/tmp"
 
 
-def touch_files(*paths: Path) -> None:
-    for path in paths:
-        path.parent.mkdir(parents=True, exist_ok=True)
-        path.touch(exist_ok=True)
-
-
 class TestPtr(unittest.TestCase):
     def setUp(self) -> None:
         self.loop = asyncio.get_event_loop()
@@ -146,7 +134,7 @@ class TestPtr(unittest.TestCase):
         td = Path(__file__).parent
         sc = ptr._config_read(str(td), "ptrconfig.sample")
         self.assertEqual(sc["ptr"]["pypi_url"], expected_pypi_url)
-        self.assertEqual(len(sc["ptr"]["venv_pkgs"].split()), 7)
+        self.assertEqual(len(sc["ptr"]["venv_pkgs"].split()), 5)
 
     @patch("ptr._gen_check_output", async_none)  # noqa
     @patch("ptr._set_pip_mirror")  # noqa
@@ -168,7 +156,10 @@ class TestPtr(unittest.TestCase):
             build_path = td_path / "build-arm"
             cooper_path = td_path / "cooper"
 
-            touch_files(*(adir / "setup.py" for adir in {build_path, cooper_path}))
+            for adir in {build_path, cooper_path}:
+                adir.mkdir()
+                a_setup_py = adir / "setup.py"
+                a_setup_py.touch()
 
             setup_pys = ptr.find_setup_pys(td_path, {"build*"})
             self.assertEqual(len(setup_pys), 1)
@@ -181,9 +172,11 @@ class TestPtr(unittest.TestCase):
         with TemporaryDirectory() as td:
             module_dir = Path(td)
             subdir = module_dir / "awlib"
+            subdir.mkdir()
             py2 = subdir / "awesome2.py"
             py1 = module_dir / "awesome.py"
-            touch_files(py1, py2)
+            for afile in (py1, py2):
+                afile.touch()
 
             self.assertEqual(
                 ptr._generate_black_cmd(module_dir, black_exe),
@@ -205,7 +198,8 @@ class TestPtr(unittest.TestCase):
             mypy_exe = Path("mypy")
             mypy_ini_path = td_path / "mypy.ini"
             entry_py_path = td_path / "cooper_is_awesome.py"
-            touch_files(mypy_ini_path, entry_py_path)
+            for a_path in (mypy_ini_path, entry_py_path):
+                a_path.touch()
 
             conf = {
                 "run_mypy": True,
@@ -216,40 +210,6 @@ class TestPtr(unittest.TestCase):
                 (str(mypy_exe), "--config", str(mypy_ini_path), str(entry_py_path)),
             )
 
-    def test_generate_flake8_command(self) -> None:
-        flake8_exe = Path("/bin/flake8")
-        with TemporaryDirectory() as td:
-            module_dir = Path(td)
-            subdir = module_dir / "awlib"
-            cf = module_dir / ".flake8"
-            py2 = subdir / "awesome2.py"
-            py1 = module_dir / "awesome.py"
-            touch_files(cf, py1, py2)
-
-            conf = {"run_flake8": True}
-
-            self.assertEqual(
-                ptr._generate_flake8_cmd(module_dir, flake8_exe, conf),
-                (str(flake8_exe), "--config", str(cf), str(py1), str(py2)),
-            )
-
-    def test_generate_pylint_command(self) -> None:
-        pylint_exe = Path("/bin/pylint")
-        with TemporaryDirectory() as td:
-            module_dir = Path(td)
-            subdir = module_dir / "awlib"
-            cf = module_dir / ".pylint"
-            py2 = subdir / "awesome2.py"
-            py1 = module_dir / "awesome.py"
-            touch_files(cf, py1, py2)
-
-            conf = {"run_pylint": True}
-
-            self.assertEqual(
-                ptr._generate_pylint_cmd(module_dir, pylint_exe, conf),
-                (str(pylint_exe), "--rcfile", str(cf), str(py1), str(py2)),
-            )
-
     def test_get_site_packages_path_error(self) -> None:
         with TemporaryDirectory() as td:
             lib_path = Path(td) / "lib"
@@ -380,7 +340,7 @@ class TestPtr(unittest.TestCase):
 
             # Run everything but black
             etp = deepcopy(ptr_tests_fixtures.EXPECTED_TEST_PARAMS)
-            del etp["run_black"]
+            del (etp["run_black"])
             fake_no_black_tests_to_run = {fake_setup_py: etp}
             self.assertEqual(
                 self.loop.run_until_complete(
@@ -393,7 +353,7 @@ class TestPtr(unittest.TestCase):
                         True,
                     )
                 ),
-                (None, 6),
+                (None, 4),
             )
 
             # Run everything including black
@@ -410,7 +370,7 @@ class TestPtr(unittest.TestCase):
                         True,
                     )
                 ),
-                (None, 7),
+                (None, 5),
             )
             # Ensure we've "printed coverage"
             self.assertTrue(mock_print.called)
diff --git a/ptr_tests_fixtures.py b/ptr_tests_fixtures.py
index 9872ae1..0e28678 100644
--- a/ptr_tests_fixtures.py
+++ b/ptr_tests_fixtures.py
@@ -14,10 +14,10 @@ from ptr import test_result
 
 
 class FakeEventLoop:
-    def close(self, *args, **kwargs) -> None:
-        pass
+    def close(*args, **kwargs) -> None:
+        ...
 
-    def run_until_complete(self, *args, **kwargs) -> int:
+    def run_until_complete(*args, **kwargs) -> int:
         return 0
 
 
@@ -28,8 +28,6 @@ EXPECTED_TEST_PARAMS = {
     "required_coverage": {"ptr.py": 85, "TOTAL": 90},
     "run_black": True,
     "run_mypy": True,
-    "run_flake8": True,
-    "run_pylint": True,
 }
 
 EXPECTED_COVERAGE_FAIL_RESULT = test_result(
@@ -45,11 +43,7 @@ EXPECTED_COVERAGE_FAIL_RESULT = test_result(
 EXPECTED_PTR_COVERAGE_FAIL_RESULT = test_result(
     setup_py_path=Path("unittest/setup.py"),
     returncode=3,
-    output=(
-        "The following files did not meet coverage requirements:\n  tg/tg.py: "
-        "22 < 99 - Missing: 39-59, 62-73, 121, 145-149, 153-225, 231-234, 238\n  "
-        "TOTAL: 40 < 99 - Missing: \n"
-    ),
+    output="The following files did not meet coverage requirements:\n  tg/tg.py: 22 < 99 - Missing: 39-59, 62-73, 121, 145-149, 153-225, 231-234, 238\n  TOTAL: 40 < 99 - Missing: \n",
     runtime=0,
     timeout=False,
 )
@@ -167,8 +161,6 @@ required_coverage_ptr.py = 85
 required_coverage_TOTAL = 90
 run_black = true
 run_mypy = true
-run_flake8 = true
-run_pylint = true
 """
 
 SAMPLE_SETUP_PY_PTR = {