Skip to content

Commit

Permalink
style: Added black formatting & refactored configs into pyproject.toml (
Browse files Browse the repository at this point in the history
#58)

* fix: Fixed collect_env nvidia smi

* chore: Refactored config into pyproject.toml

* ci: Updated dependency check

* ci: Updated dep check

* ci: Added CI job for black formatting

* docs: Updated makefile

* docs: Updated CONTRIBUTING

* style: Applied black formatting

* chore: Fixed pydocstyle version

* ci: Fixed style checks

* style: Made mypy stricter

* style: Fixed typing

* style: Fixed typing

* refactor: Removed unused import
  • Loading branch information
frgfm authored May 31, 2022
1 parent 0032f78 commit 579c189
Show file tree
Hide file tree
Showing 24 changed files with 591 additions and 511 deletions.
5 changes: 5 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[flake8]
max-line-length = 120
ignore = E203, E402, E265, F403, W503, W504, E731
exclude = .github, .git, venv*, docs, build
per-file-ignores = **/__init__.py:F401
44 changes: 16 additions & 28 deletions .github/validate_deps.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
from pathlib import Path

import requirements
import toml
from requirements.requirement import Requirement

# All req files to check
EXTRA_MAP = {
"test": "tests/requirements.txt",
"docs": "docs/requirements.txt",
}
EXTRA_IGNORE = ["dev"]


def parse_deps(deps):
def check_deps(deps):
reqs = {}
for _dep in deps:
lib, specs = _dep
Expand All @@ -26,10 +26,10 @@ def get_conficts(setup_reqs, requirement_file):
# Parse the deps from the requirements.txt
folder = Path(__file__).parent.parent.absolute()
req_deps = {}
with open(folder.joinpath(requirement_file), 'r') as f:
with open(folder.joinpath(requirement_file), "r") as f:
_deps = [(req.name, req.specs) for req in requirements.parse(f)]

req_deps = parse_deps(_deps)
req_deps = check_deps(_deps)

# Compare them
assert len(req_deps) == len(setup_reqs)
Expand All @@ -46,32 +46,18 @@ def main():

# Collect the one from setup.py
folder = Path(__file__).parent.parent.absolute()
with open(folder.joinpath("setup.cfg"), 'r') as f:
setup = f.readlines()
toml_reqs = toml.load(folder.joinpath("pyproject.toml"))

# install_requires
lines = setup[setup.index("install_requires =\n") + 1:]
lines = [_dep.strip() for _dep in lines[:lines.index("\n")]]
_reqs = [Requirement.parse(_line) for _line in lines]
install_requires = parse_deps([(req.name, req.specs) for req in _reqs])
_reqs = [Requirement.parse(_line) for _line in toml_reqs["project"]["dependencies"]]
install_requires = check_deps([(req.name, req.specs) for req in _reqs])

# extras
extras_require = {}
lines = setup[setup.index("[options.extras_require]\n") + 1:]
lines = lines[:lines.index("\n")]
# Split each extra
extra_lines = [_line for _line in lines if str.isalpha(_line[0])]
extra_names = [_line.strip().replace("=", "").strip() for _line in extra_lines]
for current_extra, start_line, end_line in zip(extra_names, extra_lines, extra_lines[1:] + [None]):
if current_extra in EXTRA_IGNORE:
continue
_lines = [_dep for _dep in lines[lines.index(start_line) + 1:]]
if isinstance(end_line, str):
_lines = _lines[:_lines.index(end_line)]
# Remove comments
_lines = [_line.strip() for _line in _lines]
_reqs = [Requirement.parse(_line.strip()) for _line in _lines if not _line.strip().startswith("#")]
extras_require[current_extra] = parse_deps([(req.name, req.specs) for req in _reqs])
extras_require = {
k: [Requirement.parse(_line) for _line in lines]
for k, lines in toml_reqs["project"]["optional-dependencies"].items()
}
extras_require = {k: check_deps([(req.name, req.specs) for req in _reqs]) for k, _reqs in extras_require.items()}

# Resolve conflicts
mismatches = {}
Expand All @@ -82,11 +68,13 @@ def main():
# Display the results
if any(len(mismatch) > 0 for mismatch in mismatches.values()):
mismatch_str = "version specifiers mismatches:\n"
mismatch_str += '\n'.join(
mismatch_str += "\n".join(
f"- {lib}: {setup} (from setup.cfg) | {reqs} (from {req_file})"
for req_file, issues in mismatches.items() for lib, setup, reqs in issues
for req_file, issues in mismatches.items()
for lib, setup, reqs in issues
)
raise AssertionError(mismatch_str)


if __name__ == "__main__":
main()
19 changes: 6 additions & 13 deletions .github/validate_headers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,16 @@
current_year = datetime.now().year

year_options = [f"{current_year}"] + [f"{year}-{current_year}" for year in range(starting_year, current_year)]
copyright_notices = [
[f"# Copyright (C) {year_str}, François-Guillaume Fernandez.\n"]
for year_str in year_options
]
copyright_notices = [[f"# Copyright (C) {year_str}, François-Guillaume Fernandez.\n"] for year_str in year_options]
license_notice = [
"# This program is licensed under the Apache License version 2.\n",
"# See LICENSE or go to <https://www.apache.org/licenses/LICENSE-2.0.txt> for full license details.\n"
"# See LICENSE or go to <https://www.apache.org/licenses/LICENSE-2.0.txt> for full license details.\n",
]

# Define all header options
HEADERS = [
shebang + [blank_line] + copyright_notice + [blank_line] + license_notice
for copyright_notice in copyright_notices
] + [
copyright_notice + [blank_line] + license_notice
for copyright_notice in copyright_notices
]
shebang + [blank_line] + copyright_notice + [blank_line] + license_notice for copyright_notice in copyright_notices
] + [copyright_notice + [blank_line] + license_notice for copyright_notice in copyright_notices]


IGNORED_FILES = ["version.py", "__init__.py"]
Expand All @@ -38,7 +31,7 @@ def main():

# For every python file in the repository
for folder in FOLDERS:
for source_path in Path(__file__).parent.parent.joinpath(folder).rglob('**/*.py'):
for source_path in Path(__file__).parent.parent.joinpath(folder).rglob("**/*.py"):
if source_path.name not in IGNORED_FILES:
# Parse header
header_length = max(len(option) for option in HEADERS)
Expand All @@ -50,7 +43,7 @@ def main():
break
# Validate it
if not any(
"".join(current_header[:min(len(option), len(current_header))]) == "".join(option)
"".join(current_header[: min(len(option), len(current_header))]) == "".join(option)
for option in HEADERS
):
invalid_files.append(source_path)
Expand Down
12 changes: 7 additions & 5 deletions .github/verify_labels.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
"topic: ci",
}

GH_ORG = 'frgfm'
GH_REPO = 'torch-scan'
GH_ORG = "frgfm"
GH_REPO = "torch-scan"


def query_repo(cmd: str, *, accept) -> Any:
Expand All @@ -61,10 +61,12 @@ def main(args):

def parse_args():
import argparse
parser = argparse.ArgumentParser(description='PR label checker',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)

parser.add_argument('pr', type=int, help='PR number')
parser = argparse.ArgumentParser(
description="PR label checker", formatter_class=argparse.ArgumentDefaultsHelpFormatter
)

parser.add_argument("pr", type=int, help="PR number")
args = parser.parse_args()

return args
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,6 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install requirements-parser==0.2.0
pip install requirements-parser==0.2.0 toml
- name: Run unittests
run: python .github/validate_deps.py
22 changes: 20 additions & 2 deletions .github/workflows/style.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ jobs:
- name: Run mypy
run: |
mypy --version
mypy --config-file mypy.ini torchscan/
mypy torchscan/
pydocstyle-py3:
runs-on: ${{ matrix.os }}
Expand All @@ -91,7 +91,25 @@ jobs:
architecture: x64
- name: Run pydocstyle
run: |
pip install pydocstyle
pip install "pydocstyle[toml]"
pydocstyle --version
pydocstyle torchscan/
black-py3:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
python: [3.7]
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python }}
architecture: x64
- name: Run black
run: |
pip install black
black --version
black --check --diff .
18 changes: 13 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,19 @@ make quality

##### Lint verification

To ensure that your incoming PR complies with the lint settings, you need to install [flake8](https://flake8.pycqa.org/en/latest/) and run the following command from the repository's root folder:
To ensure that your incoming PR complies with the lint settings, you need to install [flake8](https://flake8.pycqa.org/en/latest/), [black](https://black.readthedocs.io/en/stable/) and run the following command from the repository's root folder:

```shell
flake8 ./
black --check .
```
This will read the `.flake8` setting file and let you know whether your commits need some adjustments.

##### Import order

In order to ensure there is a common import order convention, run [isort](https://github.com/PyCQA/isort) as follows:

```shell
isort **/*.py
isort .
```
This will reorder the imports of your local files.

Expand All @@ -108,9 +108,17 @@ This will reorder the imports of your local files.
Additionally, to catch type-related issues and have a cleaner codebase, annotation typing are expected. After installing [mypy](https://github.com/python/mypy), you can run the verifications as follows:

```shell
mypy --config-file mypy.ini
mypy torchscan/
```
The `mypy.ini` file will be read to check your typing.

##### Docstring style

Finally, documentation being important, [pydocstyle](https://github.com/PyCQA/pydocstyle) will be checking the docstrings:

```shell
pydocstyle torchscan/
```


### Submit your modifications

Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ quality:
flake8 ./
mypy torchscan/
pydocstyle torchscan/
black --check .

# this target runs checks on all files and potentially modifies some of them
style:
isort .
black .

# Run tests for the library
test:
Expand Down
47 changes: 24 additions & 23 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@

import sphinx_rtd_theme

sys.path.insert(0, os.path.abspath('../..'))
sys.path.insert(0, os.path.abspath("../.."))
from datetime import datetime

import torchscan

# -- Project information -----------------------------------------------------

master_doc = 'index'
project = 'torchscan'
master_doc = "index"
project = "torchscan"
copyright = f"2020-{datetime.now().year}, François-Guillaume Fernandez"
author = 'François-Guillaume Fernandez'
author = "François-Guillaume Fernandez"

# The full version, including alpha/beta/rc tags
version = torchscan.__version__
release = torchscan.__version__ + '-git'
release = torchscan.__version__ + "-git"


# -- General configuration ---------------------------------------------------
Expand All @@ -43,54 +43,55 @@
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.napoleon',
'sphinx.ext.viewcode',
'sphinx.ext.mathjax',
'sphinxemoji.sphinxemoji', # cf. https://sphinxemojicodes.readthedocs.io/en/stable/
'sphinx_copybutton',
"sphinx.ext.autodoc",
"sphinx.ext.napoleon",
"sphinx.ext.viewcode",
"sphinx.ext.mathjax",
"sphinxemoji.sphinxemoji", # cf. https://sphinxemojicodes.readthedocs.io/en/stable/
"sphinx_copybutton",
]

napoleon_use_ivar = True

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
templates_path = ["_templates"]

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = [u'_build', 'Thumbs.db', '.DS_Store']
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]


# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
highlight_language = 'python3'
pygments_style = "sphinx"
highlight_language = "python3"

# -- Options for HTML output -------------------------------------------------

# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
html_theme = "sphinx_rtd_theme"
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]

# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
html_theme_options = {
'collapse_navigation': False,
'display_version': False,
'logo_only': False,
'analytics_id': 'UA-148140560-3',
"collapse_navigation": False,
"display_version": False,
"logo_only": False,
"analytics_id": "UA-148140560-3",
}


# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_static_path = ["_static"]


def setup(app):
app.add_css_file('css/custom.css')
app.add_js_file('js/custom.js')
app.add_css_file("css/custom.css")
app.add_js_file("js/custom.js")
Loading

0 comments on commit 579c189

Please sign in to comment.