Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ni_python_styleguide/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
"""NI's internal and external style rules enforcement tool for Python."""


class _Flake8Error(Exception):
def __init__(self, *args: object) -> None:
super().__init__(*args)
self.code = args[0]
21 changes: 13 additions & 8 deletions ni_python_styleguide/_cli.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import pathlib
import sys

import click
import toml

from ni_python_styleguide import _acknowledge_existing_errors
from ni_python_styleguide import _fix
from ni_python_styleguide import _Flake8Error
from ni_python_styleguide import _lint


Expand Down Expand Up @@ -126,14 +128,17 @@ def main(ctx, verbose, quiet, config, exclude, extend_exclude):
@click.pass_obj
def lint(obj, format, extend_ignore, file_or_dir):
"""Lint the file(s)/directory(s) given.""" # noqa: D4
_lint.lint(
qs_or_vs=_qs_or_vs(obj["VERBOSITY"]),
exclude=obj["EXCLUDE"],
app_import_names=obj["APP_IMPORT_NAMES"],
format=format,
extend_ignore=extend_ignore,
file_or_dir=file_or_dir,
)
try:
_lint.lint(
qs_or_vs=_qs_or_vs(obj["VERBOSITY"]),
exclude=obj["EXCLUDE"],
app_import_names=obj["APP_IMPORT_NAMES"],
format=format,
extend_ignore=extend_ignore,
file_or_dir=file_or_dir,
)
except _Flake8Error:
sys.exit(-1) # exit without additional output


@main.command()
Expand Down
18 changes: 9 additions & 9 deletions ni_python_styleguide/_lint.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
"""Linting methods."""
import contextlib
from io import StringIO
import io

import flake8.main.application

from ni_python_styleguide import _config_constants
from ni_python_styleguide import _Flake8Error


def lint(qs_or_vs, exclude, app_import_names, format, extend_ignore, file_or_dir):
Expand All @@ -24,20 +25,19 @@ def lint(qs_or_vs, exclude, app_import_names, format, extend_ignore, file_or_dir
*[str(p) for p in file_or_dir],
]
app.run(list(filter(bool, args)))
app.exit()
if app.exit_code() != 0:
raise _Flake8Error(app.exit_code())


# Note: tried to use functools.wraps
# - but VSCode did not properly identify the wrapped method's signature :(
def get_lint_output(qs_or_vs, exclude, app_import_names, format, extend_ignore, file_or_dir) -> str:
"Return the output from running the linter."
capture = StringIO()
capture = io.TextIOWrapper(io.BytesIO())
with contextlib.redirect_stdout(capture):
try:
lint(qs_or_vs, exclude, app_import_names, format, extend_ignore, file_or_dir)
except SystemExit as e:
if e.code in (True, 0):
pass # the flake8 app wants to always SystemExit :(
else:
raise
return capture.getvalue()
except _Flake8Error:
pass
capture.seek(0)
return capture.read()
18 changes: 10 additions & 8 deletions ni_python_styleguide/_utils/lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@

def get_errors_to_process(exclude, app_import_names, extend_ignore, file_or_dir, excluded_errors):
"""Get lint errors to process."""
lint_errors = _lint.get_lint_output(
format=None,
qs_or_vs=None,
exclude=exclude,
app_import_names=app_import_names,
extend_ignore=extend_ignore,
file_or_dir=file_or_dir,
).splitlines()
lint_errors = sorted(
_lint.get_lint_output(
format=None,
qs_or_vs=None,
exclude=exclude,
app_import_names=app_import_names,
extend_ignore=extend_ignore,
file_or_dir=file_or_dir,
).splitlines()
)
parsed_errors = map(parse, lint_errors)
parsed_errors = list(filter(None, parsed_errors))
lint_errors_to_process = [error for error in parsed_errors if error.code not in excluded_errors]
Expand Down
55 changes: 27 additions & 28 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 4 additions & 9 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "ni-python-styleguide"
# The -alpha.0 here denotes a source based version
# This is removed when released through the Publish-Package.yml GitHub action
# Official PyPI releases follow Major.Minor.Patch
version = "0.2.0-alpha.0"
version = "0.3.0-alpha.0"
description = "NI's internal and external Python linter rules and plugins"
authors = ["NI <opensource@ni.com>"]
readme = "README.md" # apply the repo readme to the package as well
Expand All @@ -15,7 +15,7 @@ include = ["ni_python_styleguide/config.toml"]
python = "^3.7"

# Tools we aggregate
flake8 = "^3.8" # flake8 4.x broke the test
flake8 = "^5.0"
black = ">=22.3, !=22.10.0" # https://github.com/psf/black/issues/3312

# Additional support libraries
Expand Down Expand Up @@ -50,14 +50,9 @@ ni-python-styleguide = 'ni_python_styleguide._cli:main'

[tool.black]
line-length = 100
exclude = '''
extend-exclude = '''
(
/(
\.eggs # exclude a few common directories in the
| \.git # root of the project
| \.venv
)/
| /.*__snapshots/.*output\.py # exclude the simple snapshot outputs
/.*__snapshots/.*output\.py # exclude the simple snapshot outputs
)
'''

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def method_withBadName_with_parameters_on_multiple_lines(x, y): # noqa N802: fu
return x + y


def method_withBadName_with_bad_params_on_single_line(myBadlyNamedParam, my_other_Bad_name): # noqa N802: function name 'method_withBadName_with_bad_params_on_single_line' should be lowercase (auto-generated noqa) # noqa N803: argument name 'myBadlyNamedParam' should be lowercase (auto-generated noqa)
def method_withBadName_with_bad_params_on_single_line(myBadlyNamedParam, my_other_Bad_name): # noqa N803: argument name 'myBadlyNamedParam' should be lowercase (auto-generated noqa) # noqa N802: function name 'method_withBadName_with_bad_params_on_single_line' should be lowercase (auto-generated noqa)
"""Provide parameters with bad names on single line."""
return myBadlyNamedParam + my_other_Bad_name

Expand All @@ -90,7 +90,7 @@ def method_withBadName_with_bad_params_on_multiple_lines_2( # noqa N802: functi
return myBadlyNamedParam + my_other_Bad_name


def method_withBadName_andParams(my_normal_param, myBadlyNamedParam, my_other_Bad_param): # noqa N802: function name 'method_withBadName_andParams' should be lowercase (auto-generated noqa) # noqa N803: argument name 'myBadlyNamedParam' should be lowercase (auto-generated noqa)
def method_withBadName_andParams(my_normal_param, myBadlyNamedParam, my_other_Bad_param): # noqa N803: argument name 'myBadlyNamedParam' should be lowercase (auto-generated noqa) # noqa N802: function name 'method_withBadName_andParams' should be lowercase (auto-generated noqa)
"""Provide example where black will want to split out result."""
return 5 + 7

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""example of a python file with linter errors.
"""

import pathlib, glob # noqa F401: 'pathlib' imported but unused (auto-generated noqa) # noqa E401: multiple imports on one line (auto-generated noqa)
import pathlib, glob # noqa E401: multiple imports on one line (auto-generated noqa) # noqa F401: 'glob' imported but unused (auto-generated noqa)
import os # noqa I100: Import statements are in the wrong order. 'import os' should be before 'import pathlib, glob' (auto-generated noqa)
from os import path # noqa F401: 'os.path' imported but unused (auto-generated noqa)
from os.path import * # noqa F403: 'from os.path import *' used; unable to detect undefined names (auto-generated noqa)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""example of a python file with linter errors.
"""

import pathlib, glob # noqa F401: 'pathlib' imported but unused (auto-generated noqa) # noqa E401: multiple imports on one line (auto-generated noqa)
import pathlib, glob # noqa E401: multiple imports on one line (auto-generated noqa) # noqa F401: 'glob' imported but unused (auto-generated noqa)
import os # noqa I100: Import statements are in the wrong order. 'import os' should be before 'import pathlib, glob' (auto-generated noqa)
from os import path # noqa F401: 'os.path' imported but unused (auto-generated noqa)
from os.path import * # noqa F403: 'from os.path import *' used; unable to detect undefined names (auto-generated noqa)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ def problem_chars(self):
return self._problem_chars


def method_withBadName_andParams(my_normal_param, myBadlyNamedParam, my_other_Bad_param): # noqa N802: function name 'method_withBadName_andParams' should be lowercase (auto-generated noqa) # noqa N803: argument name 'myBadlyNamedParam' should be lowercase (auto-generated noqa)
def method_withBadName_andParams(my_normal_param, myBadlyNamedParam, my_other_Bad_param): # noqa N803: argument name 'myBadlyNamedParam' should be lowercase (auto-generated noqa) # noqa N802: function name 'method_withBadName_andParams' should be lowercase (auto-generated noqa)
"""Provide example where black will want to split out result."""
return 5 + 7