Skip to content

Commit

Permalink
[BE] Add lint workflow (#1557)
Browse files Browse the repository at this point in the history
And format `smoke_test.py` with `ruff`
Invoke/confgure `ruff` using `lintrunner`
Copy lint runner adapters from https://github.com/pytorch/pytorch/tree/main/tools/linter/adapters
  • Loading branch information
malfet committed Sep 30, 2023
1 parent 71772d1 commit 685a807
Show file tree
Hide file tree
Showing 6 changed files with 629 additions and 8 deletions.
35 changes: 35 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Lint

on:
push:
branches:
- main
pull_request:

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}-${{ github.event_name == 'workflow_dispatch' }}
cancel-in-progress: true

jobs:
lintrunner:
name: lintrunner

runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: "3.11"
- name: Install Lintrunner
run: |
pip install lintrunner
lintrunner init
- name: Run lintrunner on all files - Linux
run: |
set +e
if ! lintrunner -v --force-color --all-files --tee-json=lint.json; then
echo ""
echo -e "\e[1m\e[36mYou can reproduce these results locally by using \`lintrunner -m main\`.\e[0m"
exit 1
fi
20 changes: 20 additions & 0 deletions .lintrunner.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
merge_base_with = "origin/main"

[[linter]]
code = 'RUFF'
include_patterns = ['test/smoke_test/*.py']
command = [
'python3',
'tools/linter/adapters/ruff_linter.py',
'--config=pyproject.toml',
'--show-disable',
'--',
'@{{PATHSFILE}}'
]
init_command = [
'python3',
'tools/linter/adapters/pip_init.py',
'--dry-run={{DRYRUN}}',
'ruff==0.0.290',
]
is_formatter = true
23 changes: 23 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[tool.ruff]
target-version = "py38"
line-length = 120
select = [
"B",
"C4",
"G",
"E",
"F",
"SIM1",
"W",
# Not included in flake8
"UP",
"PERF",
"PGH004",
"PIE807",
"PIE810",
"PLE",
"PLR1722", # use sys exit
"PLW3301", # nested min max
"RUF017",
"TRY302",
]
14 changes: 6 additions & 8 deletions test/smoke_test/smoke_test.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import os
import re
import sys
from pathlib import Path
import argparse
import torch
import platform
import importlib
import subprocess
import torch._dynamo
Expand Down Expand Up @@ -41,7 +39,7 @@

class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
super().__init__()
self.conv1 = nn.Conv2d(1, 32, 3, 1)
self.conv2 = nn.Conv2d(32, 64, 3, 1)
self.fc1 = nn.Linear(9216, 1)
Expand Down Expand Up @@ -69,7 +67,7 @@ def check_version(package: str) -> None:


def check_nightly_binaries_date(package: str) -> None:
from datetime import datetime, timedelta
from datetime import datetime
format_dt = '%Y%m%d'

date_t_str = re.findall("dev\\d+", torch.__version__)
Expand Down Expand Up @@ -177,11 +175,11 @@ def smoke_test_linalg() -> None:
print("Testing smoke_test_linalg")
A = torch.randn(5, 3)
U, S, Vh = torch.linalg.svd(A, full_matrices=False)
U.shape, S.shape, Vh.shape
assert U.shape == A.shape and S.shape == torch.Size([3]) and Vh.shape == torch.Size([3, 3])
torch.dist(A, U @ torch.diag(S) @ Vh)

U, S, Vh = torch.linalg.svd(A)
U.shape, S.shape, Vh.shape
assert U.shape == A.shape and S.shape == torch.Size([3]) and Vh.shape == torch.Size([3, 3])
torch.dist(A, U[:, :3] @ torch.diag(S) @ Vh)

A = torch.randn(7, 5, 3)
Expand Down Expand Up @@ -234,9 +232,9 @@ def smoke_test_modules():
smoke_test_command, stderr=subprocess.STDOUT, shell=True,
universal_newlines=True)
except subprocess.CalledProcessError as exc:
raise RuntimeError(f"Module {module['name']} FAIL: {exc.returncode} Output: {exc.output}")
raise RuntimeError(f"Module {module['name']} FAIL: {exc.returncode} Output: {exc.output}") from exc
else:
print("Output: \n{}\n".format(output))
print(f"Output: \n{output}\n")


def main() -> None:
Expand Down
83 changes: 83 additions & 0 deletions tools/linter/adapters/pip_init.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
"""
Initializer script that installs stuff to pip.
"""
import argparse
import logging
import os
import subprocess
import sys
import time

from typing import List


def run_command(args: List[str]) -> "subprocess.CompletedProcess[bytes]":
logging.debug("$ %s", " ".join(args))
start_time = time.monotonic()
try:
return subprocess.run(args, check=True)
finally:
end_time = time.monotonic()
logging.debug("took %dms", (end_time - start_time) * 1000)


if __name__ == "__main__":
parser = argparse.ArgumentParser(description="pip initializer")
parser.add_argument(
"packages",
nargs="+",
help="pip packages to install",
)
parser.add_argument(
"--verbose",
action="store_true",
help="verbose logging",
)
parser.add_argument(
"--dry-run", help="do not install anything, just print what would be done."
)
parser.add_argument(
"--no-black-binary",
help="do not use pre-compiled binaries from pip for black.",
action="store_true",
)

args = parser.parse_args()

logging.basicConfig(
format="<%(threadName)s:%(levelname)s> %(message)s",
level=logging.NOTSET if args.verbose else logging.DEBUG,
stream=sys.stderr,
)

pip_args = ["pip3", "install"]

# If we are in a global install, use `--user` to install so that you do not
# need root access in order to initialize linters.
#
# However, `pip install --user` interacts poorly with virtualenvs (see:
# https://bit.ly/3vD4kvl) and conda (see: https://bit.ly/3KG7ZfU). So in
# these cases perform a regular installation.
in_conda = os.environ.get("CONDA_PREFIX") is not None
in_virtualenv = os.environ.get("VIRTUAL_ENV") is not None
if not in_conda and not in_virtualenv:
pip_args.append("--user")

pip_args.extend(args.packages)

for package in args.packages:
package_name, _, version = package.partition("=")
if version == "":
raise RuntimeError(
"Package {package_name} did not have a version specified. "
"Please specify a version to produce a consistent linting experience."
)
if args.no_black_binary and "black" in package_name:
pip_args.append(f"--no-binary={package_name}")

dry_run = args.dry_run == "1"
if dry_run:
print(f"Would have run: {pip_args}")
sys.exit(0)

run_command(pip_args)
Loading

0 comments on commit 685a807

Please sign in to comment.